代碼和原理圖都是錯的,給你一個容易理解的不規(guī)則端口驅(qū)動數(shù)碼管的代碼參考。
無標(biāo)題.jpg (58.89 KB, 下載次數(shù): 14)
下載附件
2023-2-4 13:59 上傳
- #include <reg51.H>
- #define uchar unsigned char
- #define uint unsigned int
- #define key_S 3 //宏定義短按(約15ms)
- #define key_L key_S*40 //宏定義長按(約600ms)
- #define key_I key_S*20 //宏定義長按連+間隔(約300ms)
- sbit K1=P2^6;//連接按鍵
- sbit dula0=P0^2;
- sbit dula1=P0^1;
- sbit dula2=P0^5;
- sbit dula3=P2^1;
- sbit dula4=P2^4;
- sbit dula5=P0^3;
- sbit dula6=P0^4;
- sbit dula7=P2^0;//連接冒號
- sbit wela0=P0^0;
- sbit wela1=P2^5;
- sbit wela2=P2^7;
- sbit wela3=P1^7;
- uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共陽LED段碼表
- uchar data dis_buf[4];//顯示數(shù)據(jù)緩存
- char shi=12,fen=30,sec=0;//時,分,秒
- uchar Cnt5ms;//5ms時基
- uchar KeySec;//鍵值
- uint num=0;//計(jì)數(shù)
- bit flashing=0;//閃爍標(biāo)志
- //定時器初始化程序
- void Timer0Init(void) //5毫秒@12.000MHz
- {
- TMOD |= 0x01; //設(shè)置定時器模式
- TL0 = 0x78; //設(shè)置定時初始值
- TH0 = 0xEC; //設(shè)置定時初始值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時器0開始計(jì)時
- }
- void keyscan()
- {
- static unsigned int time=0;//計(jì)數(shù)變量
- if(!K1)//按鍵按下
- {
- time++;
- if(time>=key_L)//長按
- {
- switch(KeySec)
- {
- case 1: shi++;if(shi>23)shi=0; break;
- case 2: fen++;if(fen>59)fen=0; break;
- }
- time=key_I;//連+間隔
- num=1000;//自復(fù)位變量賦值(5秒)
- }
- }
- else //松手
- {
- if(time>key_S && time<key_I)//短按
- {
- KeySec++;
- if(KeySec>2)
- {
- KeySec=0;
- Cnt5ms=0;
- sec=0;
- }
- num=1000;//自復(fù)位變量賦值(5秒)
- }
- time=0;
- }
- }
- void dula(uchar i) //寫入8位段碼
- {
- dula0=i&0x01;i>>=1;
- dula1=i&0x01;i>>=1;
- dula2=i&0x01;i>>=1;
- dula3=i&0x01;i>>=1;
- dula4=i&0x01;i>>=1;
- dula5=i&0x01;i>>=1;
- dula6=i&0x01;i>>=1;
- dula7=i&0x01;
- }
- void wela(uchar i) //寫入4位位碼
- {
- wela0=i&0x01;i>>=1;
- wela1=i&0x01;i>>=1;
- wela2=i&0x01;i>>=1;
- wela3=i&0x01;
- }
- void display()//數(shù)碼管動態(tài)顯示函數(shù)
- {
- static uchar i=0;
- switch(i)//分解數(shù)據(jù)
- {
- case 0: dis_buf[0] = table[shi/10%10];break;
- case 1: dis_buf[1] = table[shi%10]; break;
- case 2: dis_buf[2] = table[fen/10%10];break;
- case 3: dis_buf[3] = table[fen%10]; break;
- }
- wela(0x00);//位碼消隱
- switch(KeySec)//送段碼
- {
- case 0: if(KeySec==0)dula(dis_buf[i]);break; //正常走時
- case 1: if(flashing && (i==0||i==1) && K1)dula(0xff);
- else dula(dis_buf[i]);break; //調(diào)整時閃爍
- case 2: if(flashing && (i==2||i==3) && K1)dula(0xff);
- else dula(dis_buf[i]);break; //調(diào)整分閃爍
- default: break;
- }
- if(!KeySec && flashing)dula7=1;//冒號閃爍
- else dula7=0;
- wela(0x01<<i);//送位碼
- i=++i%4; //循環(huán)計(jì)數(shù)
- }
- void Timing()
- {
- Cnt5ms++;
- if(KeySec!=0)
- {
- num--;
- if(num==0)//按鍵停止操作5秒自動恢復(fù)正常顯示
- {
- KeySec=0;
- Cnt5ms=0;
- sec=0;
- }
- if(Cnt5ms%50==0) //0.25s 快閃調(diào)時
- flashing=~flashing;
- }
- else if(Cnt5ms%100==0)//0.5s 慢閃顯秒
- flashing=~flashing;
- if(Cnt5ms==200)//1s
- {
- Cnt5ms=0;
- sec++;
- if(sec>=60)
- {
- sec=0;
- fen++;
- if(fen>=60)
- {
- fen=0;
- shi++;
- if(shi>23)
- shi=0;
- }
- }
- }
- }
- void main()//主函數(shù)
- {
- Timer0Init();//初始化定時器
- while(1)
- {
- if(TF0)//查詢定時器中斷請求位
- {
- TF0=0;
- TL0 = 0x78; //設(shè)置定時初始值
- TH0 = 0xEC; //設(shè)置定時初始值
- Timing(); //計(jì)時函數(shù)
- keyscan(); //按鍵掃描函數(shù)
- display(); //數(shù)碼管顯示函數(shù)
- }
- }
- }
復(fù)制代碼
|