分享一個基于51單片機的可調時鐘小設計
模式鍵:按一次,進入倒計時設置模式(設置倒計時的時間,比如2min30s,5min40s等)
按兩次,進入倒計時模式(開始倒計時)
按三次,進入鐘表時間調節模式
按四次,回到正常顯示模式(進入計時器/倒計時模式時不影響鐘表正常走時)
配置鍵:按一次調整分
按兩次調整時
按三次,回到調整分,依次循環
(配置鍵選擇需要調整的單位,由加/減鍵進行加減調整)
加法鍵:數值加
減法鍵:數值減
紅色數碼管顯示0時,為正常顯示模式
紅色數碼管顯示1時,為倒計時設置模式
紅色數碼管顯示3時,為倒計時模式
在正常顯示模式下,除模式鍵外其他按鍵都不可用
在鐘表時間調節模式下,鐘表不走時,其他任何模式都不影響鐘表的正常走時
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (18.34 KB, 下載次數: 43)
下載附件
2018-5-30 18:27 上傳
單片機源程序如下:
- /*晶振12MHZ*/
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code wela[6] = {0x20,0x10,0x08,0x04,0x02,0x01}; //位選碼
- uchar code dula[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //段選碼
- uchar buff[6] = {0,0,0,0,0,0};
- sbit P33 = P3^3;
- sbit P32 = P3^2;
- sbit P34 = P3^4;
- sbit P35 = P3^5;
- uchar hour,second,minute,hour_1,second_1,minute_1,hour_2,second_2,minute_2,t0,mode,reset,i;
- //無下劃線的為時分秒輔助變量,下劃線1的為時鐘時分秒,下劃線2的為倒計時時分秒
- void init(); //初始化函數
- void mode_0(void); //動態掃描函數
- void mode_1(void); //閃爍函數
- void time_1(void); //時鐘函數(正計時)
- void time_2(void); //倒計時函數
- void oper_add(void); //加法鍵函數
- void oper_minus(void); //減法鍵函數
- void delay(uint z); //延時函數
- void main()
- {
- init();
- while(1)
- {
- if(mode==1)
- {
- second = second_2;
- minute = minute_2;
- hour = hour_2;
- oper_add(); //加法鍵函數
- oper_minus(); //減法鍵函數
- second_2 = second;
- minute_2 = minute;
- hour_2 = hour;
- }
- else if(mode==3)
- {
- second = second_1;
- minute = minute_1;
- hour = hour_1;
- oper_add();
- oper_minus();
- second_1 = second;
- minute_1 = minute;
- hour_1 = hour;
- }
- }
- }
- /*初始化函數*/
- void init()
- {
- TMOD = 0x01; //設置T0為方式一
- TH0 = 0x3c;
- TL0 = 0xb0;
- IE = 0x87;
- IT0 = IT1 = 0;
- IP = 0X02; //設置T0為高優先級
- TR0 = 1;
- t0 = 0;
- mode = 0;
- P1 = 0xc0;
- }
- /*模式鍵函數,外部中斷0*/
- void X0_mode() interrupt 0
- {
- delay(10);
- if(P32 == 0)
- {
- mode++; //mode為模式標志位
- reset = 0; //reset為時分秒調節標志位
- switch(mode)
- {
- case 0 : P1 = 0xc0 ; break;
- case 1 : { P1 = 0xf9 ; hour_2 = second_2 = minute_2 = 0;} break;
- case 2 : P1 = 0xa4 ; break;
- case 3 : P1 = 0xb0 ; break;
- case 4 : { P1 = 0xc0 ; mode = 0;} break;
- default : break;
- }
- }
- while(P32 == 0);
-
- }
- /*配置鍵函數,外部中斷1*/
- void X1_reset() interrupt 2
- {
- delay(10);
- if(P33 == 0)
- {
- if((mode==1) || (mode==3))
- {
- reset++; //時分秒調節標志位
- if(reset == 3)
- reset = 0;
- }
- }
- while(P33 == 0);
-
- }
- /*計時/動態掃描函數,內部中斷0*/
- void T0_disp() interrupt 1
- {
- TH0 = 0xb1;
- TL0 = 0xe0; //b1e0(20ms)
- t0++;
- if(t0==50) //秒計數部分(正倒計時共用)
- {
- t0=0;
- if(mode != 3)
- time_1(); //除了調節鐘表時間調節模式外,其他模式下執行正計時函數
- if(mode==2)
- time_2(); //進入倒計時模式時,執行倒計時函數(正計時不受干擾)
- }
- if((mode==1) || (mode==2)) //裝載部分,將時分秒裝載到數組buff,便于動態掃描。
- {
- buff[0]=second_2%10;
- buff[1]=second_2/10;
- buff[2]=minute_2%10;
- buff[3]=minute_2/10;
- buff[4]=hour_2%10;
- buff[5]=hour_2/10;
-
- }
- else
- {
- buff[0]=second_1%10;
- buff[1]=second_1/10;
- buff[2]=minute_1%10;
- buff[3]=minute_1/10;
- buff[4]=hour_1%10;
- buff[5]=hour_1/10;
- }
- switch(mode) //顯示部分,包括動態掃描和閃爍函數
- {
- case 0 : mode_0() ; break;
- case 1 : mode_1() ; break;
- case 2 : mode_0() ; break;
- case 3 : mode_1() ; break;
- default : break;
- }
-
- }
- /*動態掃描函數*/
- void mode_0(void)
- {
- for(i=0;i<6;i++)
- {
- P2=wela[i];
- P0=dula[buff[i]];
- delay(1);
- }
- P2 = 0xe0;
- P0 = 0xbf;
- delay(1);
- }
- /*閃爍函數*/
- void mode_1(void) //實現0.5s亮滅閃爍
- {
- P2 = 0xc0;
- P0 = 0xbf;
- delay(1);
-
- if((reset==0) && (t0>24)) P2 = 0;
- else P2 = wela[0];
- P0 = dula[buff[0]];
- delay(1);
- if((reset==0) && (t0>24)) P2 = 0;
- else P2 = wela[1];
- P0 = dula[buff[1]];
- delay(1);
- if((reset==1) && (t0>24)) P2 = 0;
- else P2 = wela[2];
- P0 = dula[buff[2]];
- delay(1);
- if((reset==1) && (t0>24)) P2 = 0;
- else P2 = wela[3];
- P0 = dula[buff[3]];
- delay(1);
- if((reset==2) && (t0>24)) P2 = 0;
- else P2 = wela[4];
- P0 = dula[buff[4]];
- delay(1);
- if((reset==2) && (t0>24)) P2 = 0;
- else P2 = wela[5];
- P0 = dula[buff[5]];
- delay(1);
- }
- /*正計時函數*/
- void time_1(void)
- {
- second_1++;
- if(second_1==60)
- {
- second_1=0;
- minute_1++;
- if(minute_1==60)
- {
- minute_1=0;
- hour_1++;
- if(hour_1==24)
- hour_1=0;
- }
- }
- }
- /*倒計時函數*/
- void time_2(void)
- {
- second_2--;
- if(second_2==255)
- {
- second_2=59;
- minute_2--;
- if(minute_2==255)
- {
- minute_2=59;
- hour_2--;
- if(hour_2==255)
- hour_2=23;
- }
- }
- }
- /*加法鍵函數*/
- void oper_add(void)
- {
- if(P35 == 0)
- {
- delay(10);
- if(P35 == 0)
- {
- switch(reset)
- {
- case 0 :
- {
- second++;
- if(second > 59)
- second = 0;
- } break;
- case 1 :
- {
- minute++;
- if(minute > 59)
- minute = 0;
- } break;
- case 2 :
- {
- hour++;
- if(hour > 24)
- hour = 0;
- }
- default : break;
- }
- }
- while(P35 == 0);
- }
- }
- /*減法鍵函數*/
- void oper_minus(void)
- {
- if(P34 == 0)
- {
- delay(10);
- if(P34 == 0)
- {
- switch(reset)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (53.67 KB, 下載次數: 55)
下載附件
2018-5-30 18:27 上傳
所有資料51hei提供下載:
clock.zip
(65.56 KB, 下載次數: 67)
2018-5-30 12:00 上傳
點擊文件名下載附件
可調時鐘的c程序及仿真圖 下載積分: 黑幣 -5
|