完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
3个回答
|
|
实验原理
如下图所示,用一个N比特的计数器,最大值可以表示为2的N次方,最小值0,计数器以“period”为步进值累加,加到最大值后会溢出,进入下一个累加周期。当计数器值大于“duty”时,脉冲输出高,否则输出低,这样就可以完成图中红色线所示的脉冲占空比可调的脉冲输出,同时“period”可以调节脉冲频率,可以理解为计数器的步进值。 PWM脉宽调制示意图 不同的脉冲占空比的方波输出后加在LED上,LED灯就会显示不同的亮度,通过不断地调节方波的占空比,从而实现LED灯亮度的调节。 |
|
|
|
实验设计
PWM模块设计非常简单,在上面的原理中已经讲到,这里不再说原理。
`timescale1ns/1ps moduleax_pwm #( parameterN=16//pwmbitwidth ) ( inputclk, inputrst, input[N-1:0]period, //pwmstepvalue input[N-1:0]duty, //dutyvalue outputpwm_out //pwmoutput ); reg[N-1:0]period_r; //periodregister reg[N-1:0]duty_r; //dutyregister reg[N-1:0]period_cnt; //periodcounter regpwm_r; assignpwm_out=pwm_r; always@(posedgeclkorposedgerst) begin if(rst==1) begin period_r《={N{1‘b0}}; duty_r《={N{1’b0}}; end else begin period_r《=period; duty_r《=duty; end end //periodcounter,stepisperiodvalue always@(posedgeclkorposedgerst) begin if(rst==1) period_cnt《={N{1‘b0}}; else period_cnt《=period_cnt+period_r; end always@(posedgeclkorposedgerst) begin if(rst==1) begin pwm_r《=1’b0; end else begin if(period_cnt》=duty_r) //ifperiodcounteri***iggerorequalstodutyvalue,thensetpwmvaluetohigh pwm_r《=1‘b1; else pwm_r《=1’b0; end end 那么如何实现呼吸灯的效果呢?我们知道呼吸灯效果是由暗不断的变亮,再由亮不断的变暗的过程,而亮暗效果是由占空比来调节的,因此我们主要来控制占空比,也就是控制duty的值。 在下面的测试代码中,通过设置period的值,设定PWM的频率为200Hz,PWM_PLUS状态即是增加duty值,如果增加到最大值,将pwm_flag置1,并开始将duty值减少,待减少到最小的值,则开始增加duty值,不断循环。其中PWM_GAP状态为调整间隔,时间为100us。 `timescale1ns/1ps modulepwm_test( inputclk,//25MHz inputrst_n,//lowactive outputled//high-off,low-on ); localparamCLK_FREQ=25;//25MHz localparamUS_COUNT=CLK_FREQ;//1uscounter localparamMS_COUNT=CLK_FREQ*1000;//1mscounter localparamDUTY_STEP=32‘d100000;//dutystep localparamDUTY_MIN_VALUE=32’h6fffffff;//dutyminimumvalue localparamDUTY_MAX_VALUE=32‘hffffffff;//dutymaximumvalue localparamIDLE=0;//IDLEstate localparamPWM_PLUS=1;//PWMdutyplusstate localparamPWM_MINUS=2;//PWMdutyminusstate localparamPWM_GAP=3;//PWMdutyadjustmentgap wirepwm_out;//pwmoutput reg[31:0]period;//pwmstepvalue reg[31:0]duty;//dutyvalue regpwm_flag;//dutyvalueplusandminusflag,0:plus;1:minus reg[3:0]state; reg[31:0]timer;//dutyadjustmentcounter assignled=~pwm_out;//ledlowactive always@(posedgeclkornegedgerst_n) begin if(rst_n==1’b0) begin period《=32‘d0; timer《=32’d0; duty《=32‘d0; pwm_flag《=1’b0; state《=IDLE; end else case(state) IDLE: begin period《=32‘d17179;//Thepwmstepvalue,pwm200Hz(period=200*2^32/50000000) state《=PWM_PLUS; duty《=DUTY_MIN_VALUE; end PWM_PLUS: begin if(duty》DUTY_MAX_VALUE-DUTY_STEP)//ifdutyi***iggerthanDUTYMAXVALUEminusDUTY_STEP,begintominusdutyvalue begin pwm_flag《=1’b1; duty《=duty-DUTY_STEP; end else begin pwm_flag《=1‘b0; duty《=duty+DUTY_STEP; end state《=PWM_GAP; end PWM_MINUS: begin if(duty《DUTY_MIN_VALUE+DUTY_STEP)//ifdutyislittlethanDUTYMINVALUEplusdutystep,begintoadddutyvalue begin pwm_flag《=1’b0; duty《=duty+DUTY_STEP; end else begin pwm_flag《=1‘b1; duty《=duty-DUTY_STEP; end state《=PWM_GAP; end PWM_GAP: begin if(timer》=US_COUNT*100)//adjustmentgapis100us begin if(pwm_flag) state《=PWM_MINUS; else state《=PWM_PLUS; timer《=32’d0; end else begin timer《=timer+32‘d1; end end default: begin state《=IDLE; end endcase end //Instantiatepwmmodule ax_pwm #( .N(32) ) ax_pwm_m0( .clk(clk), .rst(~rst_n), .period(period), .duty(duty), .pwm_out(pwm_out) ); endmodule |
||
|
||
|
|
|
|
只有小组成员才能发言,加入小组>>
2427 浏览 7 评论
2828 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2295 浏览 9 评论
3377 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2467 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
1281浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
592浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
455浏览 1评论
2010浏览 0评论
736浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 17:33 , Processed in 1.490260 second(s), Total 82, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号