這周我做了一個用51單片機的時鐘,下面介紹一下具體實用功能 。仿真一開始,時間顯示的是20:30:00
mmexport1590381120338.jpg (248.86 KB, 下載次數: 32)
下載附件
2020-5-25 12:32 上傳
當按下第二個開關時 即可調節"分"如圖,按一下便調整為31分。
mmexport1590381122557.jpg (198.7 KB, 下載次數: 23)
下載附件
2020-5-25 12:32 上傳
再按一下第二個鍵,此時可調節"時"如圖。
mmexport1590381125521.jpg (239.71 KB, 下載次數: 21)
下載附件
2020-5-25 12:33 上傳
按一下以后,時間為21時。
mmexport1590381127960.jpg (217.43 KB, 下載次數: 24)
下載附件
2020-5-25 12:33 上傳
代碼放在附件,有需要可以下載。
單片機源程序如下:
- #include <reg51.h>
- sbit key1 = P1^0;
- bit flag1s = 0;
- bit KeySta = 1;
- unsigned char hour = 20;
- unsigned char minute = 30;
- unsigned char second = 00;
- unsigned char mode = 0;
- void FreshTime();
- void TimeInit();
- void IntInit();
- void InitLedBuff();
- void keyscan();
-
- unsigned char code LedChar[] = { //共陰數碼管顯示字符轉換表
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};
- unsigned char LedBuff[6] = { //數碼管顯示緩沖區
- 0xff,0xff,0xff,0xff,0xff,0xff};
- void main()
- {
- TimeInit();
- IntInit();
- InitLedBuff();
- while(1)//顯示內容處理
- {
- if(flag1s&&!mode) //時間顯示模式
- {
- flag1s = 0;
- FreshTime();
- }
- else if(mode == 1) //校準分鐘
- {
- LedBuff[0] = 17;
- LedBuff[1] = 17;
- LedBuff[4] = 17;
- LedBuff[5] = 17;//不顯示
- LedBuff[2] = minute/10;
- LedBuff[3] = minute%10;
- }
- else if(mode == 2) //校準小時
- {
- LedBuff[2] = 17;
- LedBuff[3] = 17;
- LedBuff[4] = 17;
- LedBuff[5] = 17;//不顯示
- LedBuff[0] = hour/10;
- LedBuff[1] = hour%10;
- }
- else if(mode == 3) //校準完成重新顯示
- {
- InitLedBuff();
- mode = 0;
- }
- keyscan();
- }
- }
- void InitLedBuff()//初始化時間到顯示緩沖區
- {
- LedBuff[0] = hour/10;
- LedBuff[1] = hour%10;
- LedBuff[2] = minute/10;
- LedBuff[3] = minute%10;
- LedBuff[4] = second/10;
- LedBuff[5] = second%10;
- }
- void FreshTime()//刷新時間到顯示緩沖區
- {
- second++;
- if(second == 60)//進位
- {
- second = 0;
- minute++;
- LedBuff[2] = minute/10;
- LedBuff[3] = minute%10;
- if(minute == 60)//進位
- {
- minute = 0;
- hour++;
- if(hour == 24)
- hour = 0;
- LedBuff[0] = hour/10;
- LedBuff[1] = hour%10;
- }
- }
- LedBuff[4] = second/10;
- LedBuff[5] = second%10;
- }
- void TimeInit()//定時器初始化
- {
- TMOD = 0X11; //設置定時器為模式1
- TL0 = 0xB0;
- TH0 = 0x3C; //定時初值 50ms
- TL1 = 0x18; //
- TH1 = 0xFC; //定時初值 1ms
- TR0 = 1; //定時器0開始計時
- TR1 = 1; //定時器1開始計時
- ET1 = 1; //使能定時器1
- ET0 = 1; //使能定時器0
- PT0 = 1; //提高計時準確性,提高定時器0中斷優先級
- EA = 1; //打開總中斷
- }
- void IntInit()//外部中斷初始化
- {
- IT0 = 1; //下降沿觸發
- EX0 = 1; //使能外部中斷0
- }
- void keyscan() //按鍵掃描及處理
- {
- static bit backup = 1;
- if (KeySta != backup) //當前值與前次值不相等說明此時按鍵有動作
- {
- if (backup == 0) //如果前次值為0,則說明當前是彈起動作
- {
- if(mode == 1) //校準分鐘時,分鐘加一
- {
- minute++;
- if(minute==60)
- minute = 0;
- }
- else if(mode == 2) //校準小時,小時加一
- {
- hour++;
- if(hour==24)
- hour = 0;
- }
- }
- backup = KeySta; //更新備份為當前值,以備進行下次比較
- }
- }
- void Int0() interrupt 0
- {
- mode++;
- if(mode == 4)
- {
- mode = 0;
- }
- }
- void Ledfresh() //數碼管顯示刷新
- {
- static unsigned char i = 0;
- switch(i)
- {
- case 0 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
- case 1 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
- case 2 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
- case 3 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
- case 4 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
- case 5 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i=0;break;
- }
- }
- void Time0() interrupt 1 //12MHz 50ms
- {
- static unsigned char n = 0;
- TL0 = 0xB0;
- TH0 = 0x3C;
- n++;
- if(n==20)
- {
- n=0;
- flag1s = 1;//1s標志位
- }
- }
- void Time1() interrupt 3 //12MHz 1ms
- {
- static unsigned char keybuff = 0xff;
- TL1 = 0x18; //
- TH1 = 0xFC; //定時初值 1ms
- Ledfresh();
- keybuff = (keybuff<<1)|key1;
- if (keybuff == 0x00)
- { //連續8次掃描值都為0,即16ms內都只檢測到按下狀態時,可認為按鍵已按下
- KeySta = 0;
- }
- else if (keybuff == 0xFF)
- { //連續8次掃描值都為1,即16ms內都只檢測到彈起狀態時,可認為按鍵已彈起
- KeySta = 1;
- }
- else
- {} //其它情況則說明按鍵狀態尚未穩定,則不對KeySta變量值進行更新
- }
復制代碼 請自行畫圖
|