C51用第三个定时器timer2扫描驱动6位数码管显示clock的方式:
大家都知道:
1. 通常C51驱动6-8段数码管,都习惯用delay延时扫描显示方式,那么有没有更好的驱动方式?
2. C51有三个定时器,timer0,timer1用的多,都比较熟悉,那么定时器3(timer2)怎么使用?
本实例程序实现了采用定时器3(timer2)快速扫描驱动6位数码管,并显示clock(时分秒)的新方式,程序更简洁,无delay延时函数,运行效率更高,而且屏显效果更好(刷新更快,且无delay方式驱动显示残影问题)。
单片机源程序如下:
- #include <reg52.h>
- //#include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char //宏定义
- sbit dula=P2^6; //数码管段控制锁存引脚定义声明
- sbit wela=P2^7; //数码管位控制锁存引脚定义声明
- uchar AA,BB,CC,DD,EE,FF;
- uchar displaynum,displaytm; //数码管显示函数名定义
- void dispay(uchar AA,uchar BB,uchar CC,uchar DD,uchar EE,uchar FF);
- //void delay(uint); //函数声明
- void init();
- uint temp; //注意数据类型
- uchar tm,kp,hnum,fnum,num,numwe; //函数名定义
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
- 0x79,0x71,0x80,0x76,0x38,0x00}; //数码管字符表
- uchar code tablewe[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //数码管位选参数表
- void main()
- {
- init(); //调用初始化子函数
- while(1)
- {
- if(tm==20)
- {
- tm=0; //定时器清零
- temp++;
- P1=~P1;
- if(temp==60)
- {
- temp=0;
- fnum++;
- if(fnum==60)
- {
- fnum=0;
- hnum++;
- if(hnum=24)
- hnum=0;
- }
- }
- AA=hnum/10; //时
- BB=hnum%10; //时
- CC=fnum/10; //分
- DD=fnum%10; //分
- EE=temp/10; //秒
- FF=temp%10; //数位提取
- }
- dispay(AA,BB,CC,DD,EE,FF);
- }
- }
- /*void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=100;y>0;y--);
- } */
- void dispay(uchar AA,uchar BB,uchar CC,uchar DD,uchar EE,uchar FF) //六位数码管显示驱动
- {
- if(displaytm==1)
- {
- displaytm=0;
- displaynum++;
- if(displaynum==1)
- {
- dula=1;
- P0=table[AA];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[0];
- wela=0;
- }
- if(displaynum==2)
- {
- dula=1;
- P0=table[BB];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[1];
- wela=0;
- }
- if(displaynum==3)
- {
- dula=1;
- P0=table[CC];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[2];
- wela=0;
- }
- if(displaynum==4)
- {
- dula=1;
- P0=table[DD];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[3];
- wela=0;
- }
- if(displaynum==5)
- {
- dula=5;
- P0=table[EE];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[4];
- wela=0;
- }
- if(displaynum==6)
- {
- dula=1;
- P0=table[FF];
- dula=0;
- P0=0xff; //消数码管残影
- wela=1;
- P0=tablewe[5];
- wela=0;
- }
- if(displaynum==7)
- displaynum=0;
- }
- }
- void init()
- {
- P0=0xff; //消除数码管残影
- dula=0; //初始化关闭段选
- wela=0; //初始化关闭位选
- temp=0;
- num=0xfe; //点亮第LED1
- P1=num; //点亮第LED1
- hnum=12;
- fnum=0;
- TMOD=0x01; //设置定时器T0,T1为定时器模式
- TH0=0x4C; //T0定时器高8位初始值设置计时50ms
- TL0=0x00; //T0定时器低8位初始值设置计时50ms
- //TH1=0x4c; //T1定时器高8位初始值设置计时50ms
- //TL1=0x00; //T1定时器低8位初始值设置计时50ms
- EA=1; //开cpu中断
- ET0=1; //开定时器T0中断
- TR0=1;
- //ET1=1; //开定时器T1中断
- //TR1=1;
- TH2=0x0f4; //T2定时器高8位初始值设置计时0.4ms
- TL2=0x48; //T2定时器低8位初始值设置计时0.4ms
- ET2=1; //开定时器中断
- TR2=1; //开启定时器T2
- }
- void timer_p0() interrupt 1
- {
- TH0=0x4c; //T0定时器高8位初始值设置再计时50ms
- TL0=0x00; //T0定时器低8位初始值设置再计时50ms
- tm++;
- }
- /*void timer_p1() interrupt 3
- {
- TH1=0x4C; //T0定时器高8位初始值设置再计时50ms
- TL1=0x00; //T0定时器低8位初始值设置再计时50ms
- tt++;
- }*/
- void timer_p2() interrupt 5 //定时器timer1中断设置
- {
- TF2=0; //定时器T2必须由软件对标志位清零
- TH2=0x0f4; //T2定时器高8位初始值设置再计时0.4ms
- TL2=0x48; //T2定时器低8位初始值设置再计时0.4ms
- displaytm++;
- }
- // 采用C52第三个定时器timer2定时扫描方式显示6位数码管
复制代码
所有资料51hei提供下载:
C51timer2-clock.rar
(31.5 KB, 下载次数: 9)
|