给你详细注释。
- #include <reg52.h>
- sbit DULA = P2^6;//数码管段锁存端口
- sbit WELA = P2^7;//数码管位锁存端口
- unsigned char code DUTable[16] = //共阴数码管段码0~f数组
- {
- 0x3F,0x06,0x5B,0x4F,
- 0x66,0x6D,0x7D,0x07,
- 0x7F,0x6F,0x77,0x7C,
- 0x39,0x5E,0x79,0x71
- };
- unsigned char code WETable[8] = //8位共阳数码管位码数组取反即是共阴
- {
- ~0x80,~0x40,~0x20,~0x10,
- ~0x08,~0x04,~0x02,~0x01
- };
- /*
- //等同下表
- unsigned char code WETable[8] = //8位共阴数码管位码数组
- {
- 0x7f,0xbf,0xdf,0xef
- 0xf7,0xfb,0xfd,0xfe,
- };*/
- unsigned char LedBuff[8] = //显示缓存数组
- {
- 0x3F,0x3F,0x00,0X00,
- 0X00,0X00,0X00,0X00
- };
- unsigned char T0RH,T0RL;//中间变量
- bit flag1s = 0;//秒标志
- void ConfigTimer0(/*unsigned char ms*/);//定时器初始化函数声明
- void TransLED(void);//倒计数函数声明
- void main(void)
- {
- ConfigTimer0();//定时器初始化
- while(1)
- {
- if(flag1s)//如果flag1s为真
- {
- flag1s = 0;//清0复位
- TransLED();//倒计数
- }
- }
- }
- //倒计数函数
- void TransLED(void)
- {
- static unsigned char num = 0;//静态局部变量
- static unsigned char led = 0;//静态局部变量
- if(0 == num)//如果计数变量=0,则执行下一轮倒计数
- {
- switch(led)
- {
- case 0 : led = 1; num = 9; P1 = ~0x04; break;//第一轮倒计数num赋初值
- case 1 : led = 2; num = 4; P1 = ~0x02; break;//第二轮倒计数num赋初值
- case 2 : led = 0; num = 9; P1 = ~0x01; break;//第三轮倒计数num赋初值 建议num>10测试
- }
- }
- else//num大于0
- {
- num--;//num自减1
- }
-
- LedBuff[0] = DUTable[num/1%10];//分解num的个位并转换为代码字符保存在缓存
- LedBuff[1] = DUTable[num/10%10];//分解num的十位并转换为代码字符保存在缓存,实际用不到,num最大是9
- }
- //定时器初始化函数
- void ConfigTimer0(/*unsigned char ms*/)
- {
- //计算定时初值
- /*
- unsigned long tmp;
- tmp = 11059200 / 12;
- tmp = tmp * ms / 1000;
- tmp = 65536 - tmp;
- tmp += 12;
-
- T0RH = (unsigned char)(tmp>>8);
- T0RL = (unsigned char)tmp;
-
- TH0 = T0RH;//设置定时高8位初值
- TL0 = T0RL;//设置定时低8位初值
- */
- // 直接赋值等同于上述复杂计算
- TH0 = 0xFC; //设置定时初值1ms
- TL0 = 0x66; //设置定时初值1ms
- TMOD &= 0xF0; //TMOD寄存器低4位清0
- TMOD |= 0x01; //设置T0工作模式1
- EA = 1; //开总中断
- ET0 = 1; //开T0中断
- TF0 = 0; //T0中断请求标志清0
- TR0 = 1; //T0开始计时
- }
- //数码管动态显示函数
- void LedScan(void)
- {
- static unsigned char i = 0;//静态局部变量
- // P0分时复用,输出段码和位码
- P0 = 0x00;//输出段清0码,消除残影
- DULA = 1;//送段码
- DULA = 0;//段码锁存
- P0 = WETable[i];//输出位码
- WELA = 1;//送位码
- WELA = 0;//位码锁存
- P0 = LedBuff[i];//输出段码
- DULA = 1;//送段码
- DULA = 0;//段码锁存
-
- i++;
- if(i>=8)//8位数码管轮流显示计数
- {
- i = 0;//清0
- }
- }
- void InterruptTimer0(void) interrupt 1
- {
- static unsigned int tmr1s = 0;
-
- // TH0 = T0RH;
- // TL0 = T0RL;
- TH0 = 0xFC; //重装定时初值1ms
- TL0 = 0x66; //重装定时初值1ms
- LedScan(); //运行数码管动态显示程序
-
- tmr1s++; //中断计数
- if(tmr1s>=1000) //1秒
- {
- tmr1s = 0; //清0
- flag1s = 1; //1秒标志置1
- }
- }
复制代码
|