基于PWM的呼吸灯设计(Verilog版)
module Breath_Led(clk,rst,led); input clk,rst; output reg led; reg[19:0] count; reg[19:0] duty_cycle; always @(posedge clk) begin if(!rst) begin led<=1'b0; count<=1'b0; end else begin if(count<20'd999_999) begin count<=count+1'b1; if(count<duty_cycle) led<=1'b1; else led<=1'b0; end else count<=1'b0; end end reg flag; always @(posedge led) begin if(!rst) begin duty_cycle<=1'b1; flag<=1'b0; end else begin if(flag==1'b0) begin if(duty_cycle<20'd979_511) begin duty_cycle<=duty_cycle+15'd9990; flag<=1'b0; end else begin duty_cycle<=duty_cycle-15'd9990; flag<=1'b1; end end else begin if(duty_cycle>1'b1) begin duty_cycle<=duty_cycle-15'd9990; flag<=1'b1; end else begin duty_cycle<=duty_cycle+15'd9990; flag<=1'b0; end end end end endmodule
记录自己写的呼吸灯小程序,程序未经重构,总体较粗糙,望看官见谅。
主体思想是基于PWM脉冲宽度调制来控制LED呈现出一种由暗到亮-由亮到暗的渐变效果;
由于程序比较简单,故程序中没有给出详细注释,在这里大概说一下其两个always块的作用,
第一个always块下面主要是实现一个闪烁频率为50Hz(这里晶振为50M)的LED功能,但每个闪烁周期的亮与灭的占空比由下面的always块控制。
第二个always块通过对占空比变量赋初值1的方式开始递增,当达到接近闪烁周期时(此程序中不要超过闪烁周期,否则会出问题,可以修改触发沿或其他方式控制,这里不做讨论)做递减操作。
通过这种简单的控制每个周期的高电平占空比便可以控制LED实现呼吸灯的效果。
以上,欢迎各位看客共同讨论,共同进步!!!