PWM呼吸灯

PWM呼吸灯

设计一个周期是8msPWM,用来控制LED实现呼吸灯的效果。

1. 设计分析

PWM的周期为8ms,每0.1秒调整一次占空比,分10档,从95%85%....5%。这里需要设计三个计数器:8ms的计数器,0.1秒的计数器,1秒的计数器。经过测试可以发现档数越多,间隔越小,呼吸灯的效果就越细腻。

 

2. 代码说明

(1) PWM周期计数器

//8ms计数

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        cnt0 <= 0;

    end

    else if(add_cnt0)begin

        if(end_cnt0)

            cnt0 <= 0;

        else

            cnt0 <= cnt0 + 1;

        end

    end

 

assign add_cnt0 = 1;

 

assign end_cnt0 = add_cnt0 && cnt0==400_000 -1 ;

这里用的clk50MHz,经过换算,8ms计数器的最大值为400000-1,代码设计里没有用常规的直接判断最大值的方式,而是用了计数使能add_cnt0,计数结束标志end_cnt,看了后续两个计数器的代码,就会明白,一是为了计数器设计的风格统一,增强代码的复用性,而是通过计数结束标志,代替直接用最大值判断,可以嵌套复用计数器,节省设计资源。

 

20.1秒计数器

//0.1s计数

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        cnt1 <= 0;

    end

    else if(add_cnt1)begin

        if(end_cnt1)

            cnt1 <= 0;

        else

            cnt1 <= cnt1 + 1;

        end

 

end

 

assign add_cnt1 = end_cnt0;

 

assign end_cnt1 = add_cnt1 && cnt1==13-1 ;

这里用end_cnt0驱动add_cnt1,就复用了前面的8ms计数器。最大值本为12.5,这里取了近似值13-1,方便计数。

 

310档计数器

//1s计数

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        cnt2 <= 0;

    end

    else if(add_cnt2)begin

        if(end_cnt2)

            cnt2 <= 0;

        else

            cnt2 <= cnt2 + 1;

        end

 

end

 

assign add_cnt2 = end_cnt1;

 

assign end_cnt2 = add_cnt2 && cnt2==10-1 ;

模式都一样,为了使显示更细腻,这里分了10档,0.1秒一档,当然也可以分更细,更多档。

 

(4)LED的控制

always @(posedge clk or negedge rst_n)begin

    if(rst_n==1'b0)begin

        led <= 9'b1_1111_1111;

    end

    else if(add_cnt0 && cnt0==led_1to0-1)begin

        led <= 9'b0;

    end

    else if(end_cnt0)begin

        led <= 9'b1_1111_1111;

    end

 

end

//每0.1秒不同的占空比

always @(*)begin

    if(cnt2==0)begin

        led_1to0 = 380_000;

    end 

    else if(cnt2==1)begin

        led_1to0 = 340_000;

    end

    else if(cnt2==2)begin

        led_1to0 = 300_000;

    end

    else if(cnt2==3)begin

        led_1to0 = 260_000;

    end

    else if(cnt2==4)begin

        led_1to0 = 220_000;

    end

    else if(cnt2==5)begin

        led_1to0 = 180_000;

    end

    else if(cnt2==6)begin

        led_1to0 = 140_000;

    end

    else if(cnt2==7)begin

        led_1to0 = 120_000;

    end

    else if(cnt2==8)begin

        led_1to0 = 80_000;

    end

    else begin

        led_1to0 = 40_000;

    end

end

对不同的占空比脉冲信号,高亮低灭,改变占空比,就改变了平均电流的大小,也就改变了亮度。

 

3. 演示视频

(1) 61秒间隔

PWM呼吸灯61spwmhttps://www.bilibili.com/video/BV15i421D7oC/?share_source=copy_web&vd_source=68c33dfb807678d785a70ba1e19f297a

 

2100.1秒间隔

PWM呼吸灯100.1spwmhttps://www.bilibili.com/video/BV17w4m1X7e6/?share_source=copy_web&vd_source=68c33dfb807678d785a70ba1e19f297a

 

4. 参考文献

https://mp.weixin.qq.com/s/v38VvtFUM00RS5_LXonPwA

 

posted on 2024-05-16 14:42  yf.x  阅读(22)  评论(0编辑  收藏  举报

导航