仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include<reg51.h>
- //---------------------端口定義-----------------
- sbit K1 = P1^0; //指定P1.0為K1,在C51中Px.y寫為Px^y,因“.”在C語言中是一種運算符
- sbit K2 = P1^1;
- sbit K3 = P1^2;
- sbit K4 = P1^3;
- //---------------------變量定義-----------------
- unsigned char hou,min,sec,yea,mon,day;
- unsigned char disp_buf[6]; //定義顯示緩沖單元
- bit update_time; //時間更新標志,1:當前時間已更新 0:當前時間未更新
- unsigned char cnt=0; //時間累加變量
- unsigned int fli=0; //閃爍時間累加變量
-
- bit c = 0; //時間 與日期切換標志變量,c=0顯示時間,c=1顯示日期
- bit leap; //判斷是否為閏年標志變量
- bit f = 0; //判斷閃爍與不閃爍切換標志變量
- bit s = 1; //停留在某一狀態變量
- //---------------------函數聲明-----------------
- void sysinit(void); //調用初始化函數
- //void time_inc(void); //調用時間加1函數
- void key_proc(void); //調用按鍵模塊
- void disp_proc(void); //調用顯示模塊
- void delayms(unsigned char x);//延時xms函數
- void main(void)
- {
- sysinit(); //調用初始化函數
- while(1)
- {
- //time_inc(); //調用時間加1函數
- key_proc(); //調用按鍵模塊
- //showcut(); //調用切換函數
- disp_proc(); //調用顯示模塊
- }
- }
- void sysinit(void)
- {
- hou = 12;
- min = 0;
- sec = 0;
- yea = 16;
- mon = 10;
- day = 1;
- TMOD=0X11; //設置定時器0和定時器1為工作方式1
- TH0=(65536-50000)/256; //裝初值
- TL0=(65536-50000)%256;
- TH1=(65536-50000)/256; //裝初值
- TL1=(65536-50000)%256;
- EA=1; //開總中斷
- ET0=1; //開定時器0中斷
- TR0=1; //啟動定時器0
- ET1=1; //開定時器1中斷
- TR1=0; //啟動定時器1
-
- }
- void key_proc(void)
- {
- static key_ask=0;
- if((K1 == 0)&&(c == 0))
- {
- delayms(10); //去抖動
- if(key_ask == 0)
- {
- hou++;
- hou=hou%24;
- key_ask =1;
- }
- }
- else if((K2 == 0)&&(c == 0))
- {
- delayms(10);
- if(key_ask == 0)
- {
- min++;
- min = min % 60;
- key_ask = 1;
- }
- }
- else if((K1 == 0)&&(c == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- day++;
- if((leap ==1)&&(mon == 2)&&(day >29 ))
- day = 1;
- else if((leap == 0)&&(mon == 2)&&(day > 28))
- day=1;
- else if(((mon == 1)||(mon == 3)||(mon == 5)||(mon == 7)||(mon == 8)||(mon == 10)||(mon == 12))&&(day > 31))
- day = 1;
- else if(((mon == 2)||(mon == 4)||(mon == 6)||(mon == 9)||(mon == 11))&&(day > 30))
- day = 1;
- key_ask = 1;
- }
- }
- else if((K2 == 0)&&(c == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- mon++;
- if(mon > 12)
- mon = 1;
- key_ask = 1;
- }
- }
- else if(K3 == 0)
- {
- delayms(10);
- if(key_ask == 0)
- {
- c=~c;
- key_ask = 1;
- }
- }
- if((K4 == 0)&&(f == 0))
- {
- delayms(10);
- if(key_ask == 0)
- {
- TR1=1;
- f = 1;
- key_ask = 1;
- }
- }
- else if((K4 == 0)&&(f == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- TR1 = 0;
- f = 0;
- key_ask = 1;
- s = 1;
- }
- }
-
- else if(key_ask == 1)
- {
- if(K1 == 1 && K2 == 1 && K3 ==1)
- {
- key_ask = 0;
- }
- }
- }
- void gengxin(void)
- {
-
- }
- void disp_proc(void)
- {
- unsigned char i,j;
- unsigned char code dis_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- unsigned char code bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
- if((update_time == 1)&&(s == 1)) //若時值(hou,min,sec)已更新則要更新顯緩disp_buf。使顯示與時值保持一致
- {
- if((c == 0))
- {
- update_time = 0;
- disp_buf[0] = hou / 10; //更新時值
- disp_buf[1] = hou % 10;
- disp_buf[2] = min / 10; //更新分值
- disp_buf[3] = min % 10;
- disp_buf[4] = sec / 10; //更新秒值
- disp_buf[5] = sec % 10;
- }
- if((c == 1))
- {
- update_time = 0;
- disp_buf[0] = yea / 10; //年
- disp_buf[1] = yea % 10;
- disp_buf[2] = mon / 10; //月
- disp_buf[3] = mon % 10;
- disp_buf[4] = day/ 10; //日
- disp_buf[5] = day% 10;
- }
- }
-
- for(i = 0; i < 6; i++)
- {
- P3 = 0xff; //熄滅顯示器(避免數碼管出現亂碼,不熄
- //滅就會下次字型碼輸出的時候,下個數碼
- //管沒有亮得時候,在之前的數碼管上就瞬間亮了)
- if((i==1)||(i==3))
- {
- P2 = dis_tab[disp_buf[i]]+0x80; //輸現定形碼
- P3 = bit_tab[i];
- for(j = 0; j < 100; j++);
- }
- else
- {
- P2 = dis_tab[disp_buf[i]]; //輸現定形碼
- P3 = bit_tab[i];
- for(j = 0; j < 100; j++);
-
-
- }
-
- }
- }
- void T0_time()interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ++cnt;
- if((yea%4 == 0)&&(yea%100 != 0)||(yea%400 == 0))
- leap = 1; //判斷為閏年
- else
- leap = 0; //不是閏年
- if(cnt >= 20)
- {
- update_time = 1; //置時間更新標志
- cnt = 0;
- ++sec;
- if(sec >= 60)
- {
- sec = 0;
- ++min;
- if(min >= 60)
- {
- min = 0;
- ++hou;
- if(hou >= 24)
- {
- hou = 0;
- day++;
- if((leap ==1)&&(mon == 2)&&(day >29 ))
- {
- mon++;
- day = 0;
- }
- else if((leap == 0)&&(mon == 2)&&(day > 28))
- {
- mon++;
- day = 0;
- }
- else if((mon == 1)||(mon == 3)||(mon == 5)||(mon == 7)||(mon == 8)||(mon == 10)||(mon == 12)&&(day > 31))
- {
- mon++;
- day = 0;
- }
- else if((mon == 2)||(mon == 4)||(mon == 6)||(mon == 9)||(mon == 11)&&(day > 30))
- {
- mon++;
- day = 0;
- }
- if(mon > 12)
- mon = 1;
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
-數字鐘24.rar
(78.96 KB, 下載次數: 29)
2018-9-11 17:27 上傳
點擊文件名下載附件
數字鐘
|