高级流水灯水滴效果.docx

上传人:b****6 文档编号:6307475 上传时间:2023-01-05 格式:DOCX 页数:14 大小:269.12KB
下载 相关 举报
高级流水灯水滴效果.docx_第1页
第1页 / 共14页
高级流水灯水滴效果.docx_第2页
第2页 / 共14页
高级流水灯水滴效果.docx_第3页
第3页 / 共14页
高级流水灯水滴效果.docx_第4页
第4页 / 共14页
高级流水灯水滴效果.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

高级流水灯水滴效果.docx

《高级流水灯水滴效果.docx》由会员分享,可在线阅读,更多相关《高级流水灯水滴效果.docx(14页珍藏版)》请在冰豆网上搜索。

高级流水灯水滴效果.docx

高级流水灯水滴效果

简介

学习嵌入式第一个例子通常都是控制一个LED亮灭,然后是花样繁多的流水灯,但不管灯的花样如何变化,单个LED的亮度没有变化,只有亮、灭两个状态,本章我们实现如何控制LED的亮度。

1什么是PWM

脉冲宽度调制(PulseWidthModulation,简称PWM),是利用微处理器的数字输出来对模拟电路进行控制的一种技术。

在本章的应用中可以认为PWM就是一种方波。

比如图1:

(原文件名:

120611_0.png)图1方波

是周期为10ms,占空比为60%的PWM。

占空比:

高电平在一个周期之内所占的时间比率。

2硬件设计

在例说51单片机的第三章,我们讲过如何控制开发板上LED的亮灭。

首先译码器输出端LEDS6为低,T10导通,给8个LED供电,然后通过缓冲器8个输出端BD0~BD7的控制LED的亮灭(低亮高灭)。

(原文件名:

120611_1.png)图2LED硬件连接

如果BD口输出高低不断变化,则LED会闪烁;如果这种高低电平变化非常快,由于人的视觉暂留现象,LED就会出现不同的亮度。

3软件设计

3.1PWM能否控制亮度

下面我们就用实践验证PWM是否能够控制LED的亮度,测试代码如下:

程序清单L1:

验证PWM能否控制LED的亮度

1    #include

2    #include"my_type.h"

3    #include"hw_config.h"

4    

5    

6    voidmain(void)

7    {

8        u8i=0;

9        

10        //使能独立LED的供电,即LEDS6输出低电平

11        LEDEN=0;

12        ADDR0=0;

13        ADDR1=1;

14        ADDR2=1;

15        ADDR3=1;

16        

17        //第一个LED亮

18        P0=0xFE;

19        

20        while

(1)

21        {

22            for(i=0;i<250;i++)

23            {

24                if(i<10)

25                {

26                    P0&=0xFD;  //第二个灯亮

27                }

28                else

29                {

30                    P0|=0x02;  //第二个灯灭

31                }

32            }

33        }

34    }

L1(22-32):

这段代码实现P0.1输出占空比为96%的方波,而P0.0恒为低。

P0.1输出如图3所示(受纸张限制,图中高低电平长度比例和实际有偏差)。

(原文件名:

120611_2.png)图3

下载验证:

从开发板上可以看到运行效果,D1比D2亮。

(这里说明一点:

当P0输出低电平时,LED亮,所以,PWM的占空比越小越亮)。

3.2产生8个亮度级别

3.1节的例子证实了我们的设想,PWM可控制LED的亮度,下面我们设计几组占空比不同的PWM,看看对LED亮度的控制效果。

代码如下:

程序清单L2:

不同占空比对LED亮度的控制

1    #include

2    #include"hw_config.h"

3    #include"my_type.h"

4    

5    

6    //亮度级别表

7    codeu8LightLevel[8]={0,1,2,4,8,16,32,64};

8    

9    voidmain(void)

10    {

11        u8i=0;

12        u8j=0;

13        u8k=0;

14        u8temp=0;

15        

16        //使能独立LED的供电,即LEDS6输出低电平

17        LEDEN=0;

18        ADDR0=0;

19        ADDR1=1;

20        ADDR2=1;

21        ADDR3=1;

22        

23        //开始全灭

24        P0=0xFF;

25        

26        while

(1)

27        {

28            //P0端口输出8组占空比不同的PWM

29            for(i=0;i<64;i++)

30            {

31                for(j=0;j<8;j++)

32                {

33                    if(LightLevel[j]<=i)

34                    {

35                        temp|=(1<

36                    }

37                    else

38                    {

39                        temp&=~(1<

40                    }

41                }

42                

43                P0=temp;

44            }

45        }

46    }

L2(29-45).此段程序是让P0口输出8组占空比不同的PWM,如图4:

(原文件名:

120611_3.png)图4

下载验证:

从开发板上可以看到运行效果,从D1到D8的亮度逐渐增大。

3.3水滴下落效果

根据PWM可控制LED亮度的原理,我们用8个LED实现水滴下落的效果。

第一步,水滴逐渐变大,用D1从暗变亮模拟;第二步,水滴下落,带有拖尾效果,LED逐个亮,移动速度加快,且越靠前的LED亮度越大。

程序清单L3水滴流水灯

1    #include

2    #include"hw_config.h"

3    #include"my_type.h"

4    

5    //亮度级别表

6    codeu8LightLevel[8]={0,1,2,4,8,16,32,64};

7    

8    //水滴时间,实现加速效果

9    codeu8LightTime[16]={16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};

10    

11    

12    voidmain(void)

13    {

14        u8i,j,k;

15        u8temp,count;

16        u8state;

17        

18        //使能独立LED的供电,即LEDS6输出低电平

19        LEDEN=0;

20        ADDR0=0;

21        ADDR1=1;

22        ADDR2=1;

23        ADDR3=1;

24    

25        while

(1)

26        {

27            //开始全灭

28            P0=0xFF;

29            

30            //---------------水滴逐渐变大(第一个LED亮度逐渐变大)---------

31            for(i=0;i<64;i++)

32            {

33                //一个亮度级别发送64个脉冲

34                for(j=0;j<64;j++)

35                {

36                    P0=0xFE;

37                    //以i为亮度级别,随着i的增大,占空比增大

38                    for(k=0;k<64;k++)

39                    {

40                        if(k>i)

41                        {

42                            P0=0xFF;

43                        }

44                    }

45                }

46            }

47            

48            //----------------------水滴降落过程---------------------

49            for(state=0;state<16;state++)

50            {    

51                //每一状态维持LightTime[state]个脉冲

52                for(count=0;count<=LightTime[state];count++)

53                {

54                    //temp记录8个LED的状态,0代表亮,1代表灭

55                    temp=0x00;

56                    

57                    //一个脉冲长度j从0到63

58                    for(j=0;j<64;j++)

59                    {

60                        //根据亮度表,依次确定8个LED当前状态,亮或灭

61                        for(k=0;k<8;k++)

62                        {

63                            //以j为亮度级别,每个LED亮度不一样

64                            if(LightLevel[k]==j)

65                            {

66                                temp|=(1<

67                            }

68                        }

69                        

70                        if(state<=7)

71                        {

72                            P0=~((~temp)>>(7-state));

73                        }

74                        else

75                        {

76                            P0=~((~temp)<<(state-7));

77                        }

78                    }

79                }

80            }

81        }

82    }

L2(31-46).实现水滴变大效果,这段代码的作用可用图形表达,如图5:

(原文件名:

120611_4.png)图5

控制D1由暗变亮,用了64个亮度级别,每个级别发送64个脉冲。

L2(49-81).实现水滴下落。

代码就不逐行解释了,大家可根据注释自己分析,主要说一下实现的方法。

定义LED有8个亮度级别,若用开发板上的8个LED表示,如图6:

(原文件名:

120611_5.png)图6

图中的红色面积代表亮度程度。

实现流水效果的方法就是:

让所有的亮度依次经过在所有LED,如图7:

(原文件名:

120611_6.png)图7

状态的持续时间从0-15逐渐减小,以模拟水滴加速。

下载验证:

下载到开发板上,可以看到水滴下落效果。

3.4定时器产生PWM

前面3个例子中,我们用循环语句虽然能产生占空比不同的PWM,但PWM的周期不好控制,对此,我们学习如何用定时器产生特定周期PWM。

关于8051定时器的使用方法,大家可以参考例说51单片机的4章和5章。

我们用定时器0产生PWM,代码如下:

程序清单L4定时器0产生PWM

1    #include

2    #include"hw_config.h"

3    #include"my_type.h"

4    

5    

6    //亮度级别表

7    codeu8LightLevel[8]={1,2,4,8,16,28,50,64};

8    

9    //函数声明

10    voidtimer0_init(void);

11    

12    voidmain(void)

13    {

14        //使能独立LED的供电,即LEDS6输出低电平

15        LEDEN=0;

16        ADDR0=0;

17        ADDR1=1;

18        ADDR2=1;

19        ADDR3=1;

20        

21        timer0_init();

22      

23        while

(1)

24        {

25        }

26    }

27    

28    /**********************************************************

29    函数名称:

timer0_init

30    功  能:

初始化定时器0

31    **********************************************************/

32    voidtimer0_init(void)

33    {

34        TMOD=0x01;    //运行模式1

35        TH0  =0xFF;    //10us中断

36        TL0  =0xFA;

37        EA  =1;      //开启中断

38        ET0  =1;

39        TR0  =1;      //启动定时器

40        

41    }

42    

43    /************************************************************

44    函数名称:

timer0_overflow

45    功  能:

定时器0溢出中断

46    ************************************************************/

47    voidtimer0_overflow(void)interruptTIMER0_OVERFLOW

48    {

49        u8i,temp=0;

50        staticu8count=0;

51        

52        count++;

53        count%=64;

54        

55        for(i=0;i<8;i++)

56        {

57            if(LightLevel<=count)

58            {

59                temp|=(1<

60            }

61            else

62            {

63                temp&=~(1<

64            }

65        }

66        

67        P0=temp;

68        

69        TR0=0;

70        TH0=0xFF;    //重新赋值

71        TL0=0xF7;

72 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 视频讲堂

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1