利用定时器0模式1中断消除4位数码管动态显示闪烁问题的项目工程

 1 /********************************************************************************
 2 定时器定时1ms,数码管以秒钟计时,加上定时器0中断可消除数码管刷新时的闪烁问题,
 3 闪烁问题是由while语句中分离数字时计算造成的,因为每次1s时间到,在数码管刷新前
 4 都要进行计算,耽误了时间,导致闪烁,加了中断以后则是先刷新数码管再分离数字。
 5 ********************************************************************************/
 6 #include <reg52.h>//52单片机头文件
 7 #define uchar unsigned char   // 自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。)
 8 #define uint unsigned int     //自定义uint为unsigned int(即有符号整数型数据,数据范围:0到65535。)
 9 uint count,i,sec,shumaguainitflag;//声明定时器0中断次数变量、选位变量、秒钟变量、数码管初始化标志位变量
10 uint ge,shi,bai,qian;//声明数码管个位变量、数码管十位变量、数码管百位变量、数码管千位变量
11 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
12   void Timer0Init()//定时器0初始化
13 {
14    TMOD=0x01;//设定定时器类型为定时器0,定时器工作模式为模式0。
15    TH0=(65536-1000)/256;//TH0装初值
16    TL0=(65536-1000)%256;//TL0装初值
17    EA=1;//开启定时器总中断
18    ET0=1;//开启定时器0中断开关
19    TR0=1;//启动定时器0
20  }
21   void Timer0() interrupt 1//定时器0中断函数
22 {
23    TH0=(65536-1000)/256;//TH0重新装值
24    TL0=(65536-1000)%256;//TL0重新装值
25    count++;//定时器0中断次数变量先赋值再加
26    P2=0xff;//此句为消除瞬间错误,例如case 1下,P0已刷新而P2暂留在case 0瞬间状态,会造成case 0下数码管瞬间显示错误数值,在每次进入开关语句前关闭所有数码管即可消除该错误。
27    switch(i)//让4位数码管以1ms间隔轮流刷新
28  {
29     
30     case 0:  
31            P0 = ge;//数码管个位数值显示
32            P2 = 0xf7;//数码管个位显示位 
33            i++;//选位变量先赋值再加加 
34            break;
35     case 1: 
36            P0 = shi;//数码管十位数值显示
37            P2 = 0xfb;//数码管十位显示位    
38            i++;//选位变量先赋值再加加 
39            break;
40     case 2: 
41            P0 = bai;//数码管百位数值显示 
42            P2 = 0xfd;//数码管百位显示位 
43            i++;//选位变量先赋值再加加 
44            break;
45     case 3: 
46            P0 = qian;//数码管千位数值显示 
47            P2 = 0xfe;//数码管千位变量显示位 
48            i=0;//选位变量置0
49            break;
50     
51     default : break;//自定义 
52    }
53  }
54   void main()//主函数
55 {
56    Timer0Init();//定时器0初始化函数
57    while(1)//固定循环
58  {   
59     if(count<1000&&shumaguainitflag==0)//判断定时器0中断次数变量是否小于1000和数码管初始化标志位变量是否等于0
60   {
61      ge = table[0];//数码管个位变量为0
62      shi = table[0];//数码管十位变量为0
63      bai = table[0];//数码管百位变量为0
64      qian = table[0];//数码管千位变量为0
65     }
66     if(count>=1000)//判断定时器0中断次数变量是否大于等于1000,即1s。
67   {
68      count = 0;//定时器0中断次数变量置0
69      sec++;//秒钟变量先赋值再加加
70      shumaguainitflag=1;//数码管初始化标志位变量置1
71      ge = table[sec%10];//数码管个位变量
72      shi = table[sec%100/10];//数码管十位变量
73      bai = table[sec%1000/100];//数码管百位变量
74      qian = table[sec/1000];//数码管千位变量
75     }
76    }
77   }

猜你喜欢

转载自www.cnblogs.com/AChenWeiqiangA/p/12316271.html