PWM呼吸灯verilog实现

该博客介绍了如何使用Verilog实现PWM脉宽调制来控制呼吸灯效果。通过设置不同的延迟时间(1us、1ms、1s)来改变LED灯的亮度,实现1秒变亮、1秒变暗的呼吸周期。PWM周期为1ms,精度为1us,系统时钟为24MHz。在代码中,利用计数器和条件判断产生PWM信号,进而控制LED的亮度,达到呼吸灯的视觉效果。
摘要由CSDN通过智能技术生成

PWM脉冲调制

PWM——脉宽调制信号(Pulse Width Modulation),它利用微处理器的数字输出来实现,是对模拟电路控制的一种非常有效的技术,广泛应用于测量、通信、功率控制与变化等许多领域。

呼吸灯:采用pwm的方式,在固定的频率下,采用占空比的方式来实现LED亮度的变化。占空比为0,LED灯不亮,占空比为100%,则LED灯最亮。所以将占空比从0到100%,再从100%到0不断变化,就可以实现LED灯实现特效呼吸。

注意这里有几个频率:
1.呼吸周期:即在这个呼吸周期中实现变亮与变暗,比如呼吸周期为2秒,1秒逐渐变亮,1秒逐渐变暗。
2.PWM周期:即在1秒的呼吸周期内(例如1秒逐渐变亮的时间内)有许多PWM周期个时间段,这些时间段的高电平占空比不同,从而实现了逐渐的亮暗变化。
3.PWM精度:即每个相同的PWM周期中,控制亮度不同的是靠PWM周期中高电平的占空比不同来控制的,而相邻的PWM周期中占空比的差值即为精度
如下图所示,这里PWM周期为1ms,呼吸周期为2s,这里画的为1s内逐渐变亮的过程(1ms中高电平占空比从0逐渐增加到100,由暗变到最亮
在这里插入图片描述

verilog实现

用verilog实现PWM控制呼吸灯。呼吸周期2秒:1秒逐渐变亮,1秒逐渐变暗。系统时钟24MHz,pwm周期1ms,精度1us。
led_out高电平占空比多,led较亮,反之,led较暗,实现呼吸灯效果

module Breath_LED(
    input           clk,    //24Mhz
    input           rst_n,
    output          led_out
);
parameter   DELAY24 = 24;
//parameter   DELAY1000 = 1000;
parameter   DELAY1000 = 10;//just test
wire            delay_1us;
wire            delay_1ms;
wire            delay_1s;
reg             pwm;
reg     [7:0]   cnt1;
reg     [10:0]  cnt2;
reg     [10:0]  cnt3;
reg             display_state;

//延时1us
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        cnt1 <= 6'b0;
    else if(cnt1 == DELAY24 - 1'b1)
        cnt1 <= 6'b0;
    else 
        cnt1 <= cnt1 + 1'b1;
end
assign delay_1us = (cnt1 == DELAY24 - 1'b1)? 1'b1:1'b0;
//延时1ms
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        cnt2 <= 10'b0;
    else if(delay_1us == 1'b1)begin
        if(cnt2 == DELAY1000 - 1'b1)    
            cnt2 <= 10'b0;
        else 
            cnt2 <= cnt2 + 1'b1;
    end
    else 
        cnt2 <= cnt2;
end
assign delay_1ms = ((delay_1us == 1'b1) && (cnt2 == DELAY1000 - 1'b1))? 
1'b1:1'b0;
   
//延时1s
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        cnt3 <= 10'b0;
    else if(delay_1ms)
    begin
         if(cnt3 == DELAY1000 - 1'b1)
            cnt3 <= 10'b0;
        else 
            cnt3 <= cnt3 + 1'b1;
     end
    else 
        cnt3 <= cnt3;    
end
assign delay_1s = ((delay_1ms == 1'b1) && (cnt3 == DELAY1000 - 1'b1))? 
1'b1:1'b0;
//state change
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        display_state <= 1'b0;
    else if(delay_1s)//每一秒切换一次led灯显示状态
        display_state <= ~display_state;
    else 
        display_state <= display_state;
end
//pwm信号的产生
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
                pwm <= 1'b0;
    else 
        case(display_state)
            1'b0: pwm <= (cnt2 < cnt3)? 1'b1:1'b0;
            1'b1: pwm <= (cnt2 < cnt3)? 1'b0:1'b1;
            default: pwm <= pwm;
        endcase
end
//位拼接使得输出八位led呼吸灯
assign led_out = pwm;
endmodule 

这里cnt3是在1s内逐渐加一(每1ms加1),即每个pwm周期加1,而cnt2是在每个pwm周期内逐渐增加(每1us加1),所以一开始的pwm周期cnt3较小(cnt2由1增加到1000),所以在一个pwm周期内(cnt2由1增加到1000),cnt2小于cnt3的时间段占比小,所以比较暗(一个pwm周期内,高电平占比小),在后面的PWM周期,cnt3的值逐渐越来越大,在一个pwm周期内(cnt2仍由1增加到1000),此时cnt2小于cnt3的时间段占比大,所以比较亮(一个pwm周期内。高电平占比大)

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值