51单片机LED流水灯多种驱动方式_第1页
51单片机LED流水灯多种驱动方式_第2页
51单片机LED流水灯多种驱动方式_第3页
51单片机LED流水灯多种驱动方式_第4页
51单片机LED流水灯多种驱动方式_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第第页51单片机LED流水灯多种驱动方式

前言(开发者)在入门点亮第一盏灯后,再深入一点就会用到流水灯。而如何实现流水灯又有好几种方式,我查询了一网上大神们的作品,无非有三种方式即查询法、位移法。这篇文章,我就如何实现流水灯开展讨论。

(硬件)我以新定义TBK-RD8T3x_v1.0开发板,为实验条件。

板载了8个流水灯。原理图如下:

实现方式之一从原理图上看,这8个灯不是接在1个P口上,分别接到了P3的第1-4,与P4的0-3端口之,按网上的教材位移方法都是不适用的。

于是我写下了第一种方法那就是直接对每一个灯进行写来实现:

#include"rd8.h"#defineON1#defineOFF0sbitLED0=P4^0;sbitLED1=P4^1;sbitLED2=P4^2;sbitLED3=P4^3;sbitLED4=P3^1;sbitLED5=P3^2;sbitLED6=P3^3;sbitLED7=P3^4;voiddelay(uint32_txms)//延时约xms毫秒{uint32_ti,j;for(i=xms*2;i>0;i--)for(j=112;j>0;j--);//分号代表跑空,for语句不需要分号,112次表示一毫秒}voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}voidmain(void){LED_Init();while(1){LED0=ON;delay(500);LED0=OFF;LED1=ON;delay(500);LED1=OFF;LED2=ON;delay(500);LED2=OFF;LED3=ON;delay(500);LED3=OFF;LED4=ON;delay(500);LED4=OFF;LED5=ON;delay(500);LED5=OFF;LED6=ON;delay(500);LED6=OFF;LED7=ON;delay(500);LED7=OFF;delay(500);}}这样的(编程)实现了流水灯,优点是直观,缺点是编写起来麻烦,代码比较长。经查看map文件编译结果为:Prog(ram)Size:data=21.0xdata=28const=0code=418

实现方式之二用数组法来实现,我们用数据来定义了P4,P3两组显示状态,共组组了9对分别表示8个灯的显示状态:

#include"rd8.h"//P40P41P42P43//P31P32P33P34//定义LED状态数组staticuint8_tLEDs[]={0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10};voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}voiddelay(uint32_txms)//延时约xms毫秒{uint32_ti,j;for(i=xms*2;i>0;i--)for(j=112;j>0;j--);//分号代表跑空,for语句不需要分号,112次表示一毫秒}voidLED_Flash(void){staticuint8_tledIndex=0;if(ledIndex==9)ledIndex=0;P4=LEDs[ledIndex*2];P3=LEDs[ledIndex*2+1];ledIndex++;}voidmain(void){LED_Init();while(1){LED_Flash();delay(500);}}这样用查表法整理出来的的代码相对于第一种实现方式,代码行有所减短,编译后,查看.map结果为:ProgramSize:data=40.0xdata=0const=0code=454

实现方式之三实现方式2,主要是查表的数组还是比较点内存,这里优化一下。

#include"rd8.h"//P40P41P42P43//P31P32P33P34//定义LED状态数组//staticuint8_tLEDs[]={0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10};//高四位代表P4低四位代表P3由于P3为1-4,我们右移了一位,在显示时,我们需要左移一位staticuint8_tLEDs[]={0x00,//0b0000000000x10,//0b0001000000x20,0x40,0x80,0x01,//0b000000010x02,0x04,0x08,};voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}voiddelay(uint32_txms)//延时约xms毫秒{uint32_ti,j;for(i=xms*2;i>0;i--)for(j=112;j>0;j--);//分号代表跑空,for语句不需要分号,112次表示一毫秒}voidLED_Flash(void){staticuint8_tledIndex=0;if(ledIndex==9)ledIndex=0;P4=(LEDs[ledIndex]P3=(LEDs[ledIndex]ledIndex++;}voidmain(void){LED_Init();while(1){LED_Flash();delay(500);}}这样优化后,点用内存有所减少:ProgramSize:data=31.0xdata=0const=0code=446

实现方式之四在方式2、方式3,我们定义了数组,利用查表法来实现流水灯。这一节我用利用位移来实现。

#include"rd8.h"voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}voiddelay(uint32_txms)//延时约xms毫秒{uint32_ti,j;for(i=xms*2;i>0;i--)for(j=112;j>0;j--);//分号代表跑空,for语句不需要分号,112次表示一毫秒}voidLED_Flash(uint8_tled_data){P3=(led_data//由于P3从1开始,所以只右移3位P4=(led_data}voidmain(void){uint8_tLED_DATA;uint8_ti;LED_Init();while(1){LED_DATA=0x00;LED_Flash(LED_DATA);//这里开始是熄灭所有的灯delay(500);LED_DATA=0x01;//初始值for(i=0;i这样我也实现了流水灯,这次位移的实现,我们的代码量变化为:ProgramSize:data=23.0xdata=0const=0code=325

实现方式之五上面所有的流水灯是阻塞式的,我们如果需要处理其的事任,那就得修改为非阻塞式,这里我们增加了(定时器)来实现,代码如下:

#include"rd8.h"uint8_tsta;uint32_tcount=0;voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}void(Ti)mer0Iint(void){TMOD|=0x01;//配置定时器0为16位定时器,TH0、TL0全用TH0=(65536-1000)/256;//1000us定时,即1毫秒溢出产生中断TL0=(65536-1000)%256;//1000us定时,即1毫秒溢出产生中断ET0=1;//开启定时器0中断EA=1;//开启全局中断TR0=1;//定时器0开始计数;}voidLED_Flash(void){staticuint8_tled_data=0x00;P3=(led_data//由于P3从1开始,所以只右移3位P4=(led_dataled_data=led_data经过修改,这一版是基于非阻塞式的实现。编译后的.map,代码尺寸如下:ProgramSize:data=15.0xdata=0const=0code=364

实现方式之六这里再增加一种位移的方面代码如下,这种方式更加简洁:

#include"rd8.h"#includeuint8_tsta;uint32_tcount=0;voidLED_Init(void){P3CON|=0x1E;//P30b00011110输出P4CON|=0x0F;//P40b00001111}voidTimer0Iint(void){TMOD|=0x01;//配置定时器0为16位定时器,TH0、TL0全用TH0=(65536-1000)/256;//1000us定时,即1毫秒溢出产生中断TL0=(65536-1000)%256;//1000us定时,即1毫秒溢出产生中断ET0=1;//开启定时器0中断EA=1;//开启全局中断TR0=1;//定时器0开始计数;}voidLED_Flash(void){staticuint8_tled_data=0x01;led_data=_crol_(led_data,1);P3=(led_data//由于P3从1开始,所以只右移3位P4=(led_data//led_data=led_data此次修改后的.map文件显示为:ProgramSize:data=15.0xdata=0const=0code=359

总结总结一下这几种编程方式点用的空间:

序号dataxdataconstcode优点缺点定义端口法21.0280418代码可读性高,直观代码行数多,如何需要修改比较麻烦数组查表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论