logo资料库

高级流水灯--水滴效果(渐变带拖尾效果)实现和讲解.pdf

第1页 / 共17页
第2页 / 共17页
第3页 / 共17页
第4页 / 共17页
第5页 / 共17页
第6页 / 共17页
第7页 / 共17页
第8页 / 共17页
资料共17页,剩余部分请下载后查看
简介简介简介简介 学习嵌入式第一个例子通常都是控制一个 LED 亮灭,然后是花样繁多的流水灯,但不管灯 的花样如何变化,单个 LED 的亮度没有变化,只有亮、灭两个状态,本章我们实现如何控制 LED 的亮度。 1111 什么是什么是什么是什么是 PWMPWMPWMPWM 脉冲宽度调制(Pulse Width Modulation,简称 PWM),是利用微处理器的数字输出来 对模拟电路进行控制的一种技术。在本章的应用中可以认为 PWM 就是一种方波。比如图 1: 是周期为 10ms,占空比为 60%的 PWM。 占空比:高电平在一个周期之内所占的时间比率。 图 1 方波 2222 硬件设计 硬件设计硬件设计硬件设计 在例说 51 单片机的第三章,我们讲过如何控制开发板上 LED 的亮灭。首先译码器输出端 LEDS6 为低,T10 导通,给 8 个 LED 供电,然后通过缓冲器 8 个输出端 BD0~BD7 的控制 LED 的亮灭(低亮高灭)。 图 2 LED 硬件连接
如果 BD 口输出高低不断变化,则 LED 会闪烁;如果这种高低电平变化非常快,由于人的视觉 暂留现象,LED 就会出现不同的亮度。 3333 软件设计 软件设计软件设计软件设计 3.13.13.13.1 PWMPWMPWMPWM 能否控制亮度 能否控制亮度 能否控制亮度 能否控制亮度 下面我们就用实践验证 PWM 是否能够控制 LED 的亮度,测试代码如下: 能否控制能否控制能否控制 LEDLEDLEDLED 的亮度的亮度的亮度的亮度 程序清单程序清单程序清单 L1L1L1L1:::: 验证验证验证验证 PWMPWMPWMPWM 能否控制 程序清单 #include #include "my_type.h" #include "hw_config.h" void main(void) { u8 i = 0; //使能独立 LED 的供电,即 LEDS6 输出低电平 LEDEN = 0; ADDR0 = 0; ADDR1 = 1; ADDR2 = 1; ADDR3 = 1; //第一个 LED 亮 P0 = 0xFE; while(1) { for(i=0; i<250; i++) //第 22 行 { if(i<10) { P0 &= 0xFD; //第二个灯亮 } else
{ } P0 |= 0x02; //第二个灯灭 } //第 32 行 } } L1(22-32):这段代码实现 P0.1 输出占空比为 96%的方波,而 P0.0 恒为低。 P0.1 输出如图 3 所示(受纸张限制,图中高低电平长度比例和实际有偏差)。 图 3 下载验证:从开发板上可以看到运行效果,D1 比 D2 亮。(这里说明一点:当 P0 输出低电平时, LED 亮,所以,PWM 的占空比越小越亮)。 3.23.23.23.2 产生产生产生产生 8888 个亮度级别 个亮度级别 个亮度级别 个亮度级别 3.1 节的例子证实了我们的设想,PWM 可控制 LED 的亮度,下面我们设计几组占空比不 同的 PWM,看看对 LED 亮度的控制效果。代码如下: :不同占空比对 LEDLEDLEDLED 亮度的控制 :不同占空比对 程序清单程序清单程序清单 L2L2L2L2:不同占空比对 亮度的控制 :不同占空比对 亮度的控制 程序清单 亮度的控制 #include #include "hw_config.h" #include "my_type.h" //亮度级别表 code u8 LightLevel[8]={0,1,2,4,8,16,32,64}; void main(void) { u8 i = 0; u8 j = 0; u8 k = 0; u8 temp = 0;
//使能独立 LED 的供电,即 LEDS6 输出低电平 LEDEN = 0; ADDR0 = 0; ADDR1 = 1; ADDR2 = 1; ADDR3 = 1; //开始全灭 P0 = 0xFF; while(1) { //P0 端口输出 8 组占空比不同的 PWM for(i=0; i<64; i++) //第 29 行 { for(j=0; j<8; j++) { if(LightLevel[j] <= i) { temp |= (1<
图 4 下载验证:从开发板上可以看到运行效果,从 D1 到 D8 的亮度逐渐增大。 3.33.33.33.3 水滴下落效果 水滴下落效果 水滴下落效果 水滴下落效果 根据 PWM 可控制 LED 亮度的原理,我们用 8 个 LED 实现水滴下落的效果。第一步,水 滴逐渐变大,用 D1 从暗变亮模拟;第二步,水滴下落,带有拖尾效果,LED 逐个亮,移动速 度加快,且越靠前的 LED 亮度越大。 程序清单程序清单程序清单 L3L3L3L3 水滴流水灯 水滴流水灯 水滴流水灯 程序清单 水滴流水灯 #include #include "hw_config.h" #include "my_type.h" //亮度级别表 code u8 LightLevel[8]={0,1,2,4,8,16,32,64}; //水滴时间,实现加速效果 code u8 LightTime[16]={16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; void main(void) { u8 i,j,k;
u8 temp,count; u8 state; //使能独立 LED 的供电,即 LEDS6 输出低电平 LEDEN = 0; ADDR0 = 0; ADDR1 = 1; ADDR2 = 1; ADDR3 = 1; while(1) { //开始全灭 P0 = 0xFF; //---------------水滴逐渐变大(第一个 LED 亮度逐渐变大)--------- for(i=0; i<64; i++) { //一个亮度级别发送 64 个脉冲 for(j=0; j<64; j++) { P0 = 0xFE; //以 i 为亮度级别,随着 i 的增大,占空比增大 for(k=0; k<64; k++) { if(k > i) { P0 = 0xFF; } } } } //----------------------水滴降落过程--------------------- for(state=0; state<16; state++) {
//每一状态维持 LightTime[state]个脉冲 for(count=0; count<=LightTime[state]; count++) { //temp 记录 8 个 LED 的状态,0 代表亮,1 代表灭 temp = 0x00; //一个脉冲长度 j 从 0 到 63 for(j=0; j<64; j++) { //根据亮度表,依次确定 8 个 LED 当前状态,亮或灭 for(k=0; k<8; k++) { //以 j 为亮度级别,每个 LED 亮度不一样 if(LightLevel[k] == j) { temp |= (1 << k); } } if(state <= 7) { P0 = ~((~temp) >> (7-state)); P0 = ~((~temp) << (state-7)); } else { } } } } } } L2(31-46).实现水滴变大效果,这段代码的作用可用图形表达,如图 5:
图 5 控制 D1 由暗变亮,用了 64 个亮度级别,每个级别发送 64 个脉冲。 L2(49-81).实现水滴下落。代码就不逐行解释了,大家可根据注释自己分析,主要说一下实现 的方法。 定义 LED 有 8 个亮度级别,若用开发板上的 8 个 LED 表示,如图 6: 图中的红色面积代表亮度程度。实现流水效果的方法就是:让所有的亮度依次经过在所有 LED, 如图 7: 图 6
分享到:
收藏