給你詳細注釋。
無標題.jpg (252.56 KB, 下載次數: 70)
下載附件
2020-11-21 15:05 上傳
- #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
- }
- }
復制代碼
|