资源预览内容
第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
第9页 / 共15页
第10页 / 共15页
亲,该文档总共15页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
高级流水灯-水滴效果(渐变带拖尾效果)实现和讲解 复制链接 spark5115主题0好友124积分注册会员莫元111 发消息电梯直达1楼发表于 2011-12-6 09:03:44|只看该作者|倒序浏览简介学习嵌入式第一个例子通常都是控制一个LED亮灭,然后是花样繁多的流水灯,但不管灯的花样如何变化,单个LED的亮度没有变化,只有亮、灭两个状态,本章我们实现如何控制LED的亮度。1 什么是PWM脉冲宽度调制(Pulse Width Modulation,简称PWM),是利用微处理器的数字输出来对模拟电路进行控制的一种技术。在本章的应用中可以认为PWM就是一种方波。比如图1:(原文件名:120611_0.png)图1 方波是周期为10ms,占空比为60%的PWM。占空比:高电平在一个周期之内所占的时间比率。2 硬件设计在例说51单片机的第三章,我们讲过如何控制开发板上LED的亮灭。首先译码器输出端LEDS6为低,T10导通,给8个LED供电,然后通过缓冲器8个输出端BD0BD7的控制LED的亮灭(低亮高灭)。(原文件名:120611_1.png)图2 LED硬件连接如果BD口输出高低不断变化,则LED会闪烁;如果这种高低电平变化非常快,由于人的视觉暂留现象,LED就会出现不同的亮度。3 软件设计3.1 PWM能否控制亮度下面我们就用实践验证PWM是否能够控制LED的亮度,测试代码如下:程序清单L1: 验证PWM能否控制LED的亮度1 #include 2 #include my_type.h3 #include hw_config.h456 void main(void)7 8 u8 i = 0;910 /使能独立LED的供电,即LEDS6输出低电平11 LEDEN = 0;12 ADDR0 = 0;13 ADDR1 = 1;14 ADDR2 = 1;15 ADDR3 = 1;1617 /第一个LED亮18 P0 = 0xFE;1920 while(1)21 22 for(i=0; i250; i+)23 24 if(i10)25 26 P0 &= 0xFD; /第二个灯亮27 28 else29 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.h3 #include my_type.h456 /亮度级别表7 code u8 LightLevel8=0,1,2,4,8,16,32,64;89 void main(void)10 11 u8 i = 0;12 u8 j = 0;13 u8 k = 0;14 u8 temp = 0;1516 /使能独立LED的供电,即LEDS6输出低电平17 LEDEN = 0;18 ADDR0 = 0;19 ADDR1 = 1;20 ADDR2 = 1;21 ADDR3 = 1;2223 /开始全灭24 P0 = 0xFF;2526 while(1)27 28 /P0端口输出8组占空比不同的PWM29 for(i=0; i64; i+)30 31 for(j=0; j8; j+)32 33 if(LightLevelj = i)34 35 temp |= (1j);36 37 else38 39 temp &= (1j);40 41 4243 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.h3 #include my_type.h45 /亮度级别表6 code u8 LightLevel8=0,1,2,4,8,16,32,64;78 /水滴时间,实现加速效果9 code u8 LightTime16=16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1;101112 void main(void)13 14 u8 i,j,k;15 u8 temp,count;16 u8 state;1718 /使能独立LED的供电,即LEDS6输出低电平19 LEDEN = 0;20 ADDR0 = 0;21 ADDR1 = 1;22 ADDR2 = 1;23 ADDR3 = 1;2425 while(1)26 27 /开始全灭28 P0 = 0xFF;2930 /-水滴逐渐变大(第一个LED亮度逐渐变大)-31 for(i=0; i64; i+)32 33 /一个亮度级别发送64个脉冲34 for(j=0; j64; j+)35 36 P0 = 0xFE;37 /以i为亮度级别,随着i的增大,占空比增大38 for(k=0; k i)41 42 P0 = 0xFF;43 44 45 46 4748 /-水滴降落过程-49 for(state=0; state16; state+)50 51 /每一状态维持LightTimestate个脉冲52 for(count=0; count=LightTimestate; count+)53 54 /temp记录8个LED的状态,0代表亮,1代表灭55 temp = 0x00;5657 /一个脉冲长度j从0到6358 for(j=0; j64; j+)59 60 /根据亮度表,依次确定8个LED当前状态,亮或灭61 for(k=0; k8; k+)62 63 /以j为亮度级别,每个LED亮度不一样64 if(LightLevelk = j)65 66 temp |= (1 k);67 68 6970 if(state (7-state);73 74 else75 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产生PWM1 #include 2 #include hw_config.h3 #include my_type.h456 /亮度级别表7 code u8 LightLevel8=1,2,4,8,16,28,50,64;89 /函数声明10 void timer0_init(void);1112 void main(void)13 14 /使能独立LED的供电,即LEDS6输出低电平15 LEDEN = 0;16 ADDR0 = 0;17 ADDR1 = 1;18 ADDR2 = 1;19 ADDR3 = 1;2021 timer0_init();2223 while(1)24 25 26 2728 /*29 函数名称:timer0_init30 功 能:初始化定时器031 */32 void timer0_init(void)33 34 TMOD = 0x01; /运行模式135 TH0 = 0xFF; /10us中断36 TL0 = 0xFA;37 EA = 1; /开启中断38 ET0 = 1;39 TR0 = 1; /启动定时器4041 4243 /*44 函数名称:timer0_overflow45 功 能:定时器0溢出中断46 */47 void timer0_overflow(void) interrupt TIMER0
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号