|
電子時(shí)鐘仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (15.55 KB, 下載次數(shù): 35)
下載附件
2018-12-5 03:47 上傳
單片機(jī)源程序如下:
- #include "reg52.H"
- #include "stdio.h"
- #include "intrins.h"
- sbit K1 = P3^4;//設(shè)置鍵
- sbit K2 = P3^5;//加鍵
- sbit K3 = P3^6;//減鍵
- sbit K4 = P3^7;//日期時(shí)間切換鍵
- unsigned char pre_key = 0x0f;//記錄按鍵狀態(tài)
- unsigned char key_value;//獲取到按鍵的值
- #define DIG_SEG P0 //段選
- #define DIG_PLA P2 //位選
- unsigned char code dig_tab[18] =//共陰數(shù)碼管碼表
- {
- 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;//數(shù)碼管第一位顯示值
- unsigned char dig_show_two;//數(shù)碼管第二位顯示值
- unsigned char dig_show_thr;//數(shù)碼管第三位顯示值
- unsigned char dig_show_fou;//數(shù)碼管第四位顯示值
- unsigned char dig_show_fiv;//數(shù)碼管第五位顯示值
- unsigned char dig_show_six;//數(shù)碼管第六位顯示值
- unsigned char dig_show_sev;//數(shù)碼管第七位顯示值
- unsigned char dig_show_eig;//數(shù)碼管第八位顯示值
- unsigned char dig_show_tmp = 0;//顯示臨時(shí)變量
- unsigned char now_window;//當(dāng)前顯示窗口
- unsigned char now_win_sta;//當(dāng)前顯示狀態(tài)
- unsigned char win_sta_tmp;//顯示狀態(tài)臨時(shí)變量
- unsigned char tim_flg;//倒計(jì)時(shí)標(biāo)志1S一次
- unsigned char nian,yue,ri,shi,fen,miao;//定義時(shí)分秒年月日
- signed char tim_temp[3] = {0};//時(shí)分秒設(shè)置臨時(shí)變量
- #define FLIOPE 200//數(shù)碼管閃爍時(shí)間常量
- #define FLICLO 400//數(shù)碼管閃爍時(shí)間常量
- unsigned char part;//數(shù)碼管閃爍標(biāo)志設(shè)置的時(shí)候
- unsigned int sci_count;//數(shù)碼管閃爍時(shí)間
- unsigned char curr_menu;
- unsigned char alm_tim_cnt;//報(bào)警時(shí)間計(jì)數(shù)
- unsigned char alm_flag;//報(bào)警標(biāo)志
- unsigned char dist_yel_alm;//東西南北黃燈閃爍區(qū)分變量
- void init_all_hardware(void);//初始化硬件
- void delay_ms(unsigned int cnt);//延時(shí)函數(shù)
- void time_init(void);//定時(shí)器初始化
- void key_scan(void);//按鍵掃描
- void key_service(void);//按鍵處理函數(shù)
- void dis_dri(void);//動(dòng)態(tài)數(shù)碼管掃描
- void display_service(void);//數(shù)碼顯示處理
- void timing_service(void);//倒計(jì)時(shí)函數(shù)
- void main(void)
- {
- init_all_hardware();//初始化硬件,IO和定時(shí)器
- while(1)
- {
- key_scan();//按鍵掃描
- key_service();//按鍵服務(wù)處理函數(shù)
- display_service();//數(shù)碼顯示處理
- timing_service();//倒計(jì)時(shí)函數(shù)
- }
- }
- /******************************************************
- ** 函數(shù)名:init_all_hardware
- ** 描述 :初始化所有硬件,及其變量參數(shù)。
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :主程序
- ******************************************************/
- void init_all_hardware(void)
- {
- delay_ms(100);
- time_init();//定時(shí)器初始化
- key_value = 0;
- dig_show_fir = 17;//開(kāi)機(jī)不顯示
- dig_show_two = 17;//開(kāi)機(jī)不顯示
- dig_show_thr = 17;//開(kāi)機(jī)不顯示
- dig_show_fou = 17;//開(kāi)機(jī)不顯示
- dig_show_fiv = 17;//開(kāi)機(jī)不顯示
- dig_show_six = 17;//開(kāi)機(jī)不顯示
- dig_show_sev = 17;//開(kāi)機(jī)不顯示
- dig_show_eig = 17;//開(kāi)機(jī)不顯示
- shi = 8; //初始化時(shí)分秒
- 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);//延時(shí)1S
- }
- /*******************************************************************************
- * 函 數(shù) 名 : delay_ms
- * 函數(shù)功能 : 延時(shí)函數(shù),延時(shí)1ms
- * 輸 入 : cnt
- * 輸 出 : 無(wú)
- * 說(shuō) 名 : 該函數(shù)是在12MHZ晶振下,12分頻單片機(jī)的延時(shí)。
- *******************************************************************************/
- void delay_ms(unsigned int cnt) //
- {
- unsigned int x;
- for( ; cnt>0; cnt--)
- {
- for(x=110; x>0; x--);//軟件延時(shí)為1MS
- }
- }
- /******************************************************
- ** 函數(shù)名:time_init
- ** 描述 :定時(shí)器初始化
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void time_init(void)
- {
- TMOD |= 0x01;//time0 工作方式為1
- TH0 = 0xf8;//裝載初值
- TL0 = 0x2f;//裝載初值,為2ms(65535-63535)
- TR0 = 1;//開(kāi)啟定時(shí)器
- ET0 = 1;//打開(kāi)中斷
- ES = 1;
- }
- /******************************************************
- ** 函數(shù)名:key_scan
- ** 描述 :按鍵掃描
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void key_scan(void)
- {
- P3 |=0xf0;//P3高四位置高
- if (pre_key==(P3&0xf0))return;//按鍵狀態(tài)未改變時(shí)繼續(xù)
- pre_key = P3&0xf0;//保存當(dāng)前最新按鍵狀態(tài)
- if (!K1)//特殊模式按鍵
- {
- delay_ms(10);//延時(shí)10ms
- if(!K1)//還判斷為按下
- {
- key_value = 1;//觸發(fā)按鍵值
- }
- }
- if (!K2)//特殊模式按鍵
- {
- delay_ms(10);//延時(shí)10ms
- if(!K2)//還判斷為按下
- {
- key_value = 2;//觸發(fā)按鍵值
- }
- }
- if (!K3)//特殊模式按鍵
- {
- delay_ms(10);//延時(shí)10ms
- if(!K3)//還判斷為按下
- {
- key_value = 3;//觸發(fā)按鍵值
- }
- }
- if (!K4)//特殊模式按鍵
- {
- delay_ms(10);//延時(shí)10ms
- if(!K4)//還判斷為按下
- {
- key_value = 4;//觸發(fā)按鍵值
- }
- }
- }
- /******************************************************
- ** 函數(shù)名:key_service
- ** 描述 :按鍵服務(wù)函數(shù)
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :主程序
- ******************************************************/
- void key_service(void)
- {
- switch(now_window)//選擇不同窗口
- {
- case 1:
- {
- switch(key_value)
- {
- case 1://切換到設(shè)置日期
- {
- 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://切換到顯示時(shí)間
- {
- now_window = 1;
- now_win_sta = 1;
- }
- key_value = 0;
- break;
- }
- }
- break;
- case 3:
- {
- switch(key_value)
- {
- case 1://設(shè)置日期
- {
- 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;
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : dis_dri
- * 函數(shù)功能 : 數(shù)碼管掃描函數(shù)
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- 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個(gè)數(shù)碼管后,重新從第一個(gè)開(kāi)始掃描
- {
- dis_step=1;
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : display_service()
- * 函數(shù)功能 : 顯示服務(wù)函數(shù)
- * 輸 入 : 無(wú)
- * 輸 出 : 無(wú)
- *******************************************************************************/
- void display_service(void)
- {
- switch(now_window)
- {
- case 1://顯示時(shí)間
- {
- 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;//顯示時(shí)
- dig_show_eig = shi%10;//顯示時(shí)
- }
- }
- 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;//顯示時(shí)
- dig_show_eig = nian%10;//顯示時(shí)
- }
- }
- 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;//顯示時(shí)
- dig_show_eig = tim_temp[0]%10;//顯示時(shí)
- }
- switch (part)//設(shè)置時(shí)候閃爍
- {
- 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://時(shí)閃爍
- {
- 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;
- }
- }
- /******************************************************
- ** 函數(shù)名:timing_service
- ** 描述 :定時(shí)1秒函數(shù)
- ** 輸入 : 無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :中斷調(diào)用
- ******************************************************/
- void timing_service(void)//倒計(jì)時(shí)函數(shù)
- {
- 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小時(shí)到了嗎
- {
- shi=0; //時(shí)清零
- fen=0;
- miao=0;
- ri++;
- if (ri==30)
- {
- ri = 1;
- }
- }
- }
- }
- }
- }
- /******************************************************
- ** 函數(shù)名:time0_interrupt
- ** 描述 :按鍵掃描函數(shù)
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void time0_interrupt() interrupt 1
- {
- static unsigned int base_2ms_buff;
- static unsigned int samping_cnt = 0;//1//1S鐘計(jì)時(shí)
- TF0 = 0;//清除標(biāo)志
- TR0 = 0;
- dis_dri();//動(dòng)態(tài)掃描數(shù)碼管
- 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)
- }
復(fù)制代碼
所有資料51hei提供下載:
電子鐘程序程序及電路.zip
(63.26 KB, 下載次數(shù): 54)
2018-12-4 17:49 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|