電子時鐘仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include "reg52.H"
- #include "stdio.h"
- #include "intrins.h"
- sbit K1 = P3^4;//設置鍵
- sbit K2 = P3^5;//加鍵
- sbit K3 = P3^6;//減鍵
- sbit K4 = P3^7;//日期時間切換鍵
- unsigned char pre_key = 0x0f;//記錄按鍵狀態
- unsigned char key_value;//獲取到按鍵的值
- #define DIG_SEG P0 //段選
- #define DIG_PLA P2 //位選
- unsigned char code dig_tab[18] =//共陰數碼管碼表
- {
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0、1、2、3、4、5、6、7、
- 0x7f,0x6f,0x77,0x00,0x39,0x5e,0x79,0x71,//8、9、A、B、C、D、E、F、
- 0x40,0x00//-
- };
- unsigned char dig_show_fir;//數碼管第一位顯示值
- unsigned char dig_show_two;//數碼管第二位顯示值
- unsigned char dig_show_thr;//數碼管第三位顯示值
- unsigned char dig_show_fou;//數碼管第四位顯示值
- unsigned char dig_show_fiv;//數碼管第五位顯示值
- unsigned char dig_show_six;//數碼管第六位顯示值
- unsigned char dig_show_sev;//數碼管第七位顯示值
- unsigned char dig_show_eig;//數碼管第八位顯示值
- unsigned char dig_show_tmp = 0;//顯示臨時變量
- unsigned char now_window;//當前顯示窗口
- unsigned char now_win_sta;//當前顯示狀態
- unsigned char win_sta_tmp;//顯示狀態臨時變量
- unsigned char tim_flg;//倒計時標志1S一次
- unsigned char nian,yue,ri,shi,fen,miao;//定義時分秒年月日
- signed char tim_temp[3] = {0};//時分秒設置臨時變量
- #define FLIOPE 200//數碼管閃爍時間常量
- #define FLICLO 400//數碼管閃爍時間常量
- unsigned char part;//數碼管閃爍標志設置的時候
- unsigned int sci_count;//數碼管閃爍時間
- unsigned char curr_menu;
- unsigned char alm_tim_cnt;//報警時間計數
- unsigned char alm_flag;//報警標志
- unsigned char dist_yel_alm;//東西南北黃燈閃爍區分變量
- void init_all_hardware(void);//初始化硬件
- void delay_ms(unsigned int cnt);//延時函數
- void time_init(void);//定時器初始化
- void key_scan(void);//按鍵掃描
- void key_service(void);//按鍵處理函數
- void dis_dri(void);//動態數碼管掃描
- void display_service(void);//數碼顯示處理
- void timing_service(void);//倒計時函數
- void main(void)
- {
- init_all_hardware();//初始化硬件,IO和定時器
- while(1)
- {
- key_scan();//按鍵掃描
- key_service();//按鍵服務處理函數
- display_service();//數碼顯示處理
- timing_service();//倒計時函數
- }
- }
- /******************************************************
- ** 函數名:init_all_hardware
- ** 描述 :初始化所有硬件,及其變量參數。
- ** 輸入 :無
- ** 輸出 :無
- ** 調用 :主程序
- ******************************************************/
- void init_all_hardware(void)
- {
- delay_ms(100);
- time_init();//定時器初始化
- key_value = 0;
- dig_show_fir = 17;//開機不顯示
- dig_show_two = 17;//開機不顯示
- dig_show_thr = 17;//開機不顯示
- dig_show_fou = 17;//開機不顯示
- dig_show_fiv = 17;//開機不顯示
- dig_show_six = 17;//開機不顯示
- dig_show_sev = 17;//開機不顯示
- dig_show_eig = 17;//開機不顯示
- shi = 8; //初始化時分秒
- fen = 12;
- miao = 35;
- nian = 16;//初始化年月日
- yue = 1;
- ri = 4;
- part = 0;
- sci_count = 0;
- curr_menu = 0;
- now_window = 1;
- now_win_sta = 1;
- EA=1;
- delay_ms(1000);//延時1S
- }
- /*******************************************************************************
- * 函 數 名 : delay_ms
- * 函數功能 : 延時函數,延時1ms
- * 輸 入 : cnt
- * 輸 出 : 無
- * 說 名 : 該函數是在12MHZ晶振下,12分頻單片機的延時。
- *******************************************************************************/
- void delay_ms(unsigned int cnt) //
- {
- unsigned int x;
- for( ; cnt>0; cnt--)
- {
- for(x=110; x>0; x--);//軟件延時為1MS
- }
- }
- /******************************************************
- ** 函數名:time_init
- ** 描述 :定時器初始化
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void time_init(void)
- {
- TMOD |= 0x01;//time0 工作方式為1
- TH0 = 0xf8;//裝載初值
- TL0 = 0x2f;//裝載初值,為2ms(65535-63535)
- TR0 = 1;//開啟定時器
- ET0 = 1;//打開中斷
- ES = 1;
- }
- /******************************************************
- ** 函數名:key_scan
- ** 描述 :按鍵掃描
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void key_scan(void)
- {
- P3 |=0xf0;//P3高四位置高
- if (pre_key==(P3&0xf0))return;//按鍵狀態未改變時繼續
- pre_key = P3&0xf0;//保存當前最新按鍵狀態
- if (!K1)//特殊模式按鍵
- {
- delay_ms(10);//延時10ms
- if(!K1)//還判斷為按下
- {
- key_value = 1;//觸發按鍵值
- }
- }
- if (!K2)//特殊模式按鍵
- {
- delay_ms(10);//延時10ms
- if(!K2)//還判斷為按下
- {
- key_value = 2;//觸發按鍵值
- }
- }
- if (!K3)//特殊模式按鍵
- {
- delay_ms(10);//延時10ms
- if(!K3)//還判斷為按下
- {
- key_value = 3;//觸發按鍵值
- }
- }
- if (!K4)//特殊模式按鍵
- {
- delay_ms(10);//延時10ms
- if(!K4)//還判斷為按下
- {
- key_value = 4;//觸發按鍵值
- }
- }
- }
- /******************************************************
- ** 函數名:key_service
- ** 描述 :按鍵服務函數
- ** 輸入 :無
- ** 輸出 :無
- ** 調用 :主程序
- ******************************************************/
- void key_service(void)
- {
- switch(now_window)//選擇不同窗口
- {
- case 1:
- {
- switch(key_value)
- {
- case 1://切換到設置日期
- {
- now_window = 3;
- now_win_sta = 31;
- tim_temp[0] = shi;
- tim_temp[1] = fen;
- tim_temp[2] = miao;
- part = 1;
- curr_menu = 1;
- }
- key_value = 0;
- break;
- case 4://切換到顯示日期
- {
- now_window = 2;
- now_win_sta = 2;
- }
- key_value = 0;
- break;
- }
- }
- break;
- case 2:
- {
- switch(key_value)
- {
- case 4://切換到顯示時間
- {
- now_window = 1;
- now_win_sta = 1;
- }
- key_value = 0;
- break;
- }
- }
- break;
- case 3:
- {
- switch(key_value)
- {
- case 1://設置日期
- {
- if (curr_menu<4)
- curr_menu++;
- if (curr_menu == 2)
- {
- part = 2;
- now_win_sta = 31;
- }
- else if(curr_menu == 3)
- {
- part = 3;
- now_win_sta = 31;
- }
- else if (curr_menu == 4)
- {
- curr_menu = 0;
- now_window = 1;
- now_win_sta = 1;
- }
- }
- key_value = 0;
- break;
- case 2://日期加
- {
- if(curr_menu == 1)
- {
- if (++tim_temp[2]>59)
- {
- tim_temp[2] = 0;
- }
- miao = tim_temp[2];
- }
- else if (curr_menu == 2)
- {
- if (++tim_temp[1]>59)
- {
- tim_temp[1] = 0;
- }
- fen = tim_temp[1];
- }
- else if (curr_menu == 3)
- {
- if (++tim_temp[0]>23)
- {
- tim_temp[0] = 0;
- }
- shi = tim_temp[0];
- }
- }
- key_value = 0;
- break;
- case 3://日期減
- {
- if(curr_menu == 1)
- {
- if (--tim_temp[2]<0)
- {
- tim_temp[2] = 59;
- }
- miao = tim_temp[2];
- }
- else if (curr_menu == 2)
- {
- if (--tim_temp[1]<0)
- {
- tim_temp[1] = 59;
- }
- fen = tim_temp[1];
- }
- else if (curr_menu == 3)
- {
- if (--tim_temp[0]<0)
- {
- tim_temp[0] = 23;
- }
- shi = tim_temp[0];
- }
- }
- key_value = 0;
- break;
- }
- }
- break;
- }
- }
- /*******************************************************************************
- * 函 數 名 : dis_dri
- * 函數功能 : 數碼管掃描函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void dis_dri(void)
- {
- static unsigned char dis_step = 1;
- DIG_SEG = 0x00;
- switch(dis_step)
- {
- case 1: //顯示第1位
- {
- dig_show_tmp=dig_tab[dig_show_fir];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfe;
- }
- break;
- case 2: //顯示第2位
- {
- dig_show_tmp=dig_tab[dig_show_two];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfd;
- }
- break;
- case 3: //顯示第3位
- {
- dig_show_tmp=dig_tab[dig_show_thr];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfb;
- }
- break;
- case 4: //顯示第4位
- {
- dig_show_tmp=dig_tab[dig_show_fou];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xf7;
- }
- break;
- case 5: //顯示第5位
- {
- dig_show_tmp=dig_tab[dig_show_fiv];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xef;
- }
- break;
- case 6: //顯示第6位
- {
- dig_show_tmp=dig_tab[dig_show_six];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xdf;
- }
- break;
- case 7: //顯示第7位
- {
- dig_show_tmp=dig_tab[dig_show_sev];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xbf;
- }
- break;
- case 8: //顯示第8位
- {
- dig_show_tmp=dig_tab[dig_show_eig];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0x7f;
- }
- break;
- }
- dis_step++;
- if(dis_step>8) //掃描完4個數碼管后,重新從第一個開始掃描
- {
- dis_step=1;
- }
- }
- /*******************************************************************************
- * 函 數 名 : display_service()
- * 函數功能 : 顯示服務函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void display_service(void)
- {
- switch(now_window)
- {
- case 1://顯示時間
- {
- if (now_win_sta == 1)//刷新顯示
- {
- now_win_sta = 0;
- dig_show_fir = miao/10;//顯示秒
- dig_show_two = miao%10;//顯示秒
- dig_show_fou = 16;//顯示-
- dig_show_six = fen/10;//顯示分
- dig_show_thr = fen%10;//顯示分
- dig_show_fiv = 16;//顯示-
- dig_show_sev = shi/10;//顯示時
- dig_show_eig = shi%10;//顯示時
- }
- }
- break;
- case 2://顯示日期
- {
- if (now_win_sta == 2)//刷新顯示
- {
- now_win_sta = 0;
- dig_show_fir = ri/10;//顯示秒
- dig_show_two = ri%10;//顯示秒
- dig_show_fou = 16;//顯示-
- dig_show_six = yue/10;//顯示分
- dig_show_thr = yue%10;//顯示分
- dig_show_fiv = 16;//顯示-
- dig_show_sev = nian/10;//顯示時
- dig_show_eig = nian%10;//顯示時
- }
- }
- break;
- case 3:
- {
- if(now_win_sta ==31)
- {
- now_win_sta = 0;
- dig_show_fir = tim_temp[2]/10;//顯示秒
- dig_show_two = tim_temp[2]%10;//顯示秒
- dig_show_fou = 16;//顯示-
- dig_show_six = tim_temp[1]/10;//顯示分
- dig_show_thr = tim_temp[1]%10;//顯示分
- dig_show_fiv = 16;//顯示-
- dig_show_sev = tim_temp[0]/10;//顯示時
- dig_show_eig = tim_temp[0]%10;//顯示時
- }
- switch (part)//設置時候閃爍
- {
- case 1://秒閃爍
- {
- if (sci_count == FLIOPE)
- {
- dig_show_fir = tim_temp[2] / 10;
- dig_show_two = tim_temp[2] % 10;
- }
- else if (sci_count > FLICLO)
- {
- sci_count = 0;
- dig_show_fir = 17;
- dig_show_two = 17;
- }
- }
- break;
- case 2://分閃爍
- {
- if (sci_count == FLIOPE)
- {
- dig_show_six = tim_temp[1] / 10;
- dig_show_thr = tim_temp[1] % 10;
- }
- else if (sci_count > FLICLO)
- {
- sci_count = 0;
- dig_show_six = 17;
- dig_show_thr = 17;
- }
- }
- break;
- case 3://時閃爍
- {
- if (sci_count == FLIOPE)
- {
- dig_show_sev = tim_temp[0] / 10;
- dig_show_eig = tim_temp[0] % 10;
- }
- else if (sci_count > FLICLO)
- {
- sci_count = 0;
- dig_show_sev = 17;
- dig_show_eig = 17;
- }
- }
- break;
- }
- }
- break;
- }
- }
- /******************************************************
- ** 函數名:timing_service
- ** 描述 :定時1秒函數
- ** 輸入 : 無
- ** 輸出 :無
- ** 調用 :中斷調用
- ******************************************************/
- void timing_service(void)//倒計時函數
- {
- if (tim_flg == 1)
- {
- tim_flg = 0;
- now_win_sta = 1;
- miao++;
- if(miao==60)//六十秒到了嗎
- {
- fen++;//分加加
- miao=0;
- if(fen==60)//六十分到了嗎
- {
- shi++;
- fen=0;
- if(shi==24)//24小時到了嗎
- {
- shi=0; //時清零
- fen=0;
- miao=0;
- ri++;
- if (ri==30)
- {
- ri = 1;
- }
- }
- }
- }
- }
- }
- /******************************************************
- ** 函數名:time0_interrupt
- ** 描述 :按鍵掃描函數
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void time0_interrupt() interrupt 1
- {
- static unsigned int base_2ms_buff;
- static unsigned int samping_cnt = 0;//1//1S鐘計時
- TF0 = 0;//清除標志
- TR0 = 0;
- dis_dri();//動態掃描數碼管
- if (++samping_cnt > 500)
- {
- samping_cnt = 0;
- if (now_window!=3)
- {
- tim_flg = 1;
- }
- }
- if (++base_2ms_buff==50)
- {
- base_2ms_buff = 0;
- if (alm_tim_cnt)
- alm_tim_cnt--;
- }
- if (++sci_count > 2000)
- {
- sci_count = 0;
- }
- TR0 = 1;
- TH0 = 0xf8;
- TL0 = 0x2f;//裝載初值2ms(65535-63535)
- }
復制代碼
所有資料51hei提供下載:
電子鐘程序程序及電路.zip
(63.26 KB, 下載次數: 54)
2018-12-4 17:49 上傳
點擊文件名下載附件
|