基于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实现呼吸灯的效果。

以上,欢迎各位看客共同讨论,共同进步!!!

原文地址:https://www.cnblogs.com/lightmonster/p/10126745.html