PWM(脉宽调制)——LED特效呼吸灯设计


  简述PWM

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

  LED特效呼吸灯原理

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

  设计思路、框图  

  变亮:当cnt2 < cnt3时为高电平,反之为低电平。

  变暗:当cnt2 < cnt3时为低电平,反之为高电平。

  先分频出延时为1us的延时电路,作为后面电路的驱动电路,然后是1ms延时和1s延时,会产生两个计数器,刚好是1000倍的关系。

  (1)在第一秒时,随着cnt3由0到999逐渐增大,每一个1ms的占空比通过cnt2去调节。当cnt2 < cnt3时为高电平,反之为低电平。 因此,随着cnt3的逐渐增大,高电平的时间逐渐增大,直到100%。

  (2)在第二秒时,随着cnt3由0到999逐渐增大,每一个1ms的占空比通过cnt2去调节。当cnt2 < cnt3时为低电平,反之为高电平。 因此,随着cnt3的逐渐增大,高电平的时间逐渐减小,直到0。

  设计图如上所示,完后就可以照图施工了,附上部分代码。

//延时1us

    always @(posedge mclk or negedge rst_n)

    begin

        if(!rst_n)

            cnt1 <= 6'b0;

        else if(cnt1 < STOP_50 - 1'b1)

            cnt1 <= cnt1 + 1'b1;

        else 

            cnt1 <= 6'b0;

    end

    assign delay_1us = (cnt1 == STOP_50 - 1'b1)?1'b1:1'b0;

    

    //延时1ms

    always @(posedge mclk or negedge rst_n)

    begin

        if(!rst_n)

            cnt2 <= 10'b0;

        else if(delay_1us)

        begin

            if(cnt2 < STOP_1000 - 1'b1)    

                cnt2 <= cnt2 + 1'b1;

            else 

                cnt2 <= 10'b0;

        end

       end

       assign delay_1ms = ((delay_1us == 1'b1) && (cnt2 == STOP_1000 - 1'b1))?1'b1:1'b0;

       

       //延时1s

       always @(posedge mclk or negedge rst_n)

刘杰,软硬件工程师,10多年项目开发经验,擅长单片机产品开发。长期进行单片机产品设计免费教学,硬件家园创始人。

    begin

        if(!rst_n)

            cnt3 <= 10'b0;

        else if(delay_1ms)

        begin

             if(cnt3 < STOP_1000 - 1'b1)

                cnt3 <= cnt3 + 1'b1;

            else 

                cnt3 <= 10'b0;

         end

        

    end

    assign delay_1s = ((delay_1ms == 1'b1) && (cnt3 == STOP_1000 - 1'b1))?1'b1:1'b0;

    

    //state change

    always @(posedge mclk 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 mclk 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 = {8{pwm}};

产生的pwm信号原来是一位的,所以最后要是需要控制多个LED的亮灭,使用一个位拼接运算即可,如最后一行代码所示。

来源:http://www.cnblogs.com/ninghechuan/p/6291499.html  

> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >

我们学习串口通信主要是要实现单片机和电脑之间的信息交互,可以用电脑控制单片机的一些信息,可以把单片机的一些信息状况发给电脑上的软件。下面我们就做一个简单的例程,实现单片机串口调试助手发送的数据,在我们开发板上的数码管上显示出来。

生成海报
点赞 0

thePro

我还没有学会写个人说明!

相关推荐

51单片机——定时器

为什么使用定时器? 之前我们的led灯每隔1s循环左移点亮的时候,使用的定时方法是在c程序执行若干次空循环,这样会耗费很多cpu资源,因为空轮询。本篇博客将使用51单片机内置的定时器中断