logo资料库

51单片机控制数码管动态显示程序.pdf

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
51单片机控制数码管动态显示程序 单片机控制数码管动态显示程序 说明: 驱动四位一体数码管动态显示数字,可方便的移植到其它程序中。 例如:1、硬件改为三位一体或二位 一体数码管,只需修改Display_Scan()函数COM个数。 2、本例中,采用了共阴数码管,如果用在共阳数码 管,只需修改相应段码表。 本程序使用P0口作为段码数据发送端,P2.0-P2.3作为数码管扫描选通,使用P0口时,因单片机内部没有上拉电阻,所以要外 接上拉电阻(参考阻值470欧姆). // STC89C52RC // +---------------+ // | | // | | Digital Number // | | _______________________ // | | | __ __ __ __ | // | P0.0--P0.7|===>| | | | | | | | | | // | (a,b...g,h)| | |--| |--| |--| |--| | 4位共阴数码管 // | | | |__|.|__|.|__|.|__|.| // | | ----------------------- // | | | | | | // | | | | | | // | P2.7(COM3)|--------+ | | | // | | | | | // | P2.6(COM2)|-------------+ | | // | | | | // | P2.5(COM1)|------------------+ | // | | | // | P2.4(COM0)|-----------------------+ // +---------------+ #include // 函数声明 //======================================================================= void DisplayNumber(unsigned int Num); void delayms( int ms); //======================================================================= unsigned char code LED_table[]={ //使用附带“51单片机工具箱”可以很容易编码 0x3f, //"0" 0x06, //"1" 0x5b, //"2" AAAA 0x4f, //"3" F B 0x66, //"4" F B 0x6d, //"5" GGGG 0x7d, //"6" E C 0x07, //"7" E C 0x7f, //"8" DDDD H 0x6f, //"9" 0x00, //black 0x80 //dot }; #define black 10 // 空白 #define dot 11 // 小数点
unsigned char DisBuff[4]; //定义显示缓冲数组 unsigned char COM; // 定义通信端口 //=========================================================================== sbit COM0=P2^4; sbit COM1=P2^5; //对应口线由硬件确定 sbit COM2=P2^6; sbit COM3=P2^7; //=========================================================================== void Sys_Init() { TMOD=0x01; //定时器/计数器0为定时器方式16位工作模式 TH0=(65536-1000)/256; //初始时间常数 TL0=(65536-1000)%6; //1.0ms ET0=1; //定时器/计数器0中断允许 EA=1; //总中断允许 TR0=1; //启动定时器/计数器开始工作 } void DisplayNumber(unsigned int Num) //显示程序 { unsigned char i; EA=0; //禁止总中断 for(i=0;i<4;i++) { DisBuff[i]=Num; //拆分数字 Num/=10; } for(i=3;i>=0;i--) //循环4次 { if (DisBuff[i]==0) DisBuff[i]=black; //消隐无效"0" else break; //例如将 0123 改成 123,仅显示有效数字 } EA=1; //总中断允许 } void Display_Scan() interrupt 1 // 中断服务程序,数码管选通扫描 { TR0=0;
TH0=(65536-1000)/256; //高8位和低8位时间常数 TL0=(65536-1000)%6; TR0=1; //启动定时器0 if(COM>3) COM=0; COM0=COM1=COM2=COM3=1; //将COM0-COM3置1,全暗 switch(COM) { case 0: P0=LED_table[DisBuff[0]]; COM0=0; break; //分别选通COM0-COM3 低电平有效 case 1: P0=LED_table[DisBuff[1]]; COM1=0; break; case 2: P0=LED_table[DisBuff[2]]; COM2=0; break; case 3: P0=LED_table[DisBuff[3]]; COM3=0; break; } // 与decp(0x20)位或,恰好点亮小数点位段 COM++; } void delayms(int ms) { unsigned int i; for(;ms>0;ms--) //循环ms次 { for(i=0;i<123;i++); // for(i=0;i<123;i++); 每次1ms延迟@ 12.0MHz } // for(i=0;i<113;i++); 每次1ms延迟@ 11.0592MHz } void main() { unsigned int i; //定义变量 Sys_Init(); //初始化timer0 while(1) //死循环,单片机必须是死循环 { DisplayNumber(i); //调用数码管显示函数 delayms(200); //调用延时函数,使显示数字保持一段时间 i++; //这里演示一个数字累加的程序 //也可以直接写一个常数用来显示,看实际效果 } //例如DisplayNumber(1234); 编译后将HEX文件 } //下载到学板里应该正常显示数字 1234 。 // 另一种段编码方法 //=========================================================================== //宏定义,数码管a-g各段对应的比特,更换硬件只用改动以下8行
#define a 0x04 // AAAA #define b 0x01 // F B #define c 0x10 // F B #define d 0x40 // GGGG #define e 0x80 // E C #define f 0x02 // E C #define g 0x08 // DDDD H #define h 0x20 //用宏定义自动生成段码表,很好的写法,值得学习 //更换硬件无需重写段码表 unsigned char code LED_table[]={ a+b+c+d+e+f, //"0" b+c, //"1" a+b+d+e+g, //"2" a+b+c+d+g, //"3" b+c+f+g, //"4" a+c+d+f+g, //"5" a+c+d+e+f+g, //"6" a+b+c, //"7" a+b+c+d+e+f+g, //"8" a+b+c+d+f+g, //"9" b+c+e+f+g, //"H" a+f+e+g, //"C" d+e+f, //"L" g, //"-" 0x00 //black }; #undef a #undef b #undef c #undef d #undef e #undef f #undef g
分享到:
收藏