1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include<reg52.h>
typedef unsigned char u8; typedef unsigned int u16;
u8 LedChar[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管从0到9的真值 u8 LedBuff[] = {0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //数码管显示缓冲区,初值0xFF确保启动时都不亮 u8 flags = 1; //1秒定时标志
void TimeInit(); //定时器中断初始化函数 void HC138(u8 channel); //138译码器通道选择函数 void ShowSMG\_Bit(u8 date,u8 pos); //数码管显示函数
int main() { u8 sec = 0, minutes = 0, hours = 0, days = 0; //定义记录秒,分,时,天的变量 TimeInit(); //定时器中断初始化 while(1) { if(flags == 1) //判断1秒定时标志 { flags = 0; //标志位清零 sec++; //秒加1 if(sec == 60) //判断秒变量到达60秒 { sec = 0; //清0零 minutes++; //分钟位加1 } if(minutes == 60) //判断达到60分 { minutes = 0; //清零 hours++; //小时位加1 } if(hours == 24) //判断达到24小时 { hours = 0; //清零 days++; //天数加1 } LedBuff[0]= LedChar[sec%10]; //秒的低位 LedBuff[1]= LedChar[sec/10%10]; //秒的高位 LedBuff[2]= LedChar[minutes%10]; //分钟的低位 LedBuff[3]= LedChar[minutes/10%10]; //分钟的高位 LedBuff[4]= LedChar[hours%10]; //小时的低位 LedBuff[5]= LedChar[hours/10%10]; //小时的高位 LedBuff[6]= LedChar[days%10]; //天数的低位 LedBuff[7]= LedChar[days/10%10]; //天数的高位 } } }
void TimeInit() { EA = 1; //打开中断总开关 ET0 = 1; //打开T0中断开关 TMOD = 0x01; //设置定时器工作在模式1 TH0=(65536-5000)/256; //高四位寄存器的值;//5000us=5ms TL0=(65536-5000)%256; //低四位寄存器的值; TR0 = 1; //允许定时器T0工作 }
void HC138(u8 channel) { switch(channel) { case 4: P2 = (P2&0x1f)|0x80; //选择Y4对应模块(LED小灯) ,运算结果为P2高三位为100 break; case 5: P2 = (P2&0x1f)|0xa0; //选择Y5对应模块(蜂鸣器),运算结果为P2高三位为101 break; case 6: P2 = (P2&0x1f)|0xc0; //选择Y6对应模块(数码管的位选),运算结果为P2高三位为110 break; case 7: P2 = (P2&0x1f)|0xe0; //选择Y7对应模块(数码管的段选),运算结果为P2高三位为111 break; } }
void ShowSMG\_Bit(u8 date,u8 pos) { HC138(6); //Y6模块工作,数码管进行位选 P0 = 0x01<<pos; //数码管的位选传到P0口 HC138(7); //Y7模块工作,数码管进行段选 P0 = date; //当前数码管要显示数值对应的真值传到P0口 }
void InterruptTimer0() interrupt 1 { static u8 i = 0; //动态扫描的索引 static u16 cnt = 0; //用来记录中断次数,设置的中断定时为1ms,中断200次即一秒钟
TH0=(65536-5000)/256; //高四位寄存器的值;//5000us=5ms TL0=(65536-5000)%256; //低四位寄存器的值; cnt++; //中断次数计数值加1 if(cnt>=200) //中断次数达到200次即为1秒 { cnt = 0; //清零,重新记录中断次数 flags = 1; //设置1秒定时标志位1 }
P0 = 0xff; //消隐 switch(i) //根据动态索引i的值进行位选,依次点亮八个数码管 { case 0 : i++; ShowSMG\_Bit(LedBuff[0],7); break; //最右边一位数码管(com8)对应P0^7口 case 1 : i++; ShowSMG\_Bit(LedBuff[1],6); break; case 2 : i++; ShowSMG\_Bit(LedBuff[2],5); break; case 3 : i++; ShowSMG\_Bit(LedBuff[3],4); break; case 4 : i++; ShowSMG\_Bit(LedBuff[4],3); break; case 5 : i++; ShowSMG\_Bit(LedBuff[5],2); break; case 6 : i++; ShowSMG\_Bit(LedBuff[6],1); break; case 7 : i=0; ShowSMG\_Bit(LedBuff[7],0); break; default:break; } }
|