最近剛學了數碼管動態掃描和矩陣鍵盤,正好把這兩個內容合并在一起寫了這個可調時鐘
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
2.jpg (77.15 KB, 下載次數: 112)
下載附件
2020-7-31 11:54 上傳
單片機源程序如下:
- #include<at89x51.h>
- #define uint unsigned int
- #define uchar unsigned char
- uint time_t;//毫秒統計值
- char hour_now,min_now,sec_now,// 實時時間
- hour_a1,min_a1,sec_a1,
- hour_a2,min_a2,sec_a2;//鬧鐘時間
- uchar key,key_num,time_cdk;//鍵盤掃描值,鍵盤鍵值
- uchar code led[10]={0xfc,0x60,0xda,0xf2,
- 0x66,0xb6,0xbe,0xe0,0xfe,0xf6};//數碼管顯示0-9
- sbit beep=P3^7;//定義P3.7口為蜂鳴器控制口
- /********************************************************************/
- //函數名:delay_1ms(uint x)
- //功能:利用定時器0精確定時1ms; 自加 time_t的值為后面時間調整函數服務
- //調用函數:
- //輸入參數:x,1ms計數
- //輸出參數:
- //說明:延時的時間為1ms乘以x
- /********************************************************************/
- void delay_1ms(uint x)
- {
- TMOD=0X01;//開定時器0,工作方式為1
- TR0=1;//啟動定時器0;
- while(x--)
- {
- TH0=0Xfc;//定時1ms初值的高8位裝入TH0
- TL0=0X18;//定時1ms初值的低8位裝入TL0
- while(!TF0);//等待,直到TF0為1
- TF0=0;
- time_t++;//毫秒統計值自加1
- }
- TR0=0;//停止定時器0;
- }
- /**********************************************************/
- //函數名:display_num(uchar num,dis_w)
- //功能:2位數碼管顯示
- //調用函數:delay_1ms(uint x)
- //輸入參數:num,dis_w
- //輸出參數:
- //說明:P0口做數碼管段選,P2口做位選
- //通過dis_w的值確定num值在數碼管上顯示的位置
- /**********************************************************/
- void display_num(uchar num,dis_w)
- {
- uchar j;
- for(j=0;j<2;j++)
- {
- P0=0xff;//段選口置高,消影
- P2=~dis_w;//裝入位選值
- if(j>0)
- P0=~led[num/10];//顯示num個位
- else
- P0=~led[num%10];//顯示num十位
- dis_w=dis_w<<1;
- delay_1ms(5);//延時5ms
- }
- }
- /**********************************************************/
- //函數名:display_char()
- //功能:顯示時間分隔符“-”
- //調用函數:delay_1ms(uint x)
- //輸入參數:
- //輸出參數:
- //說明:
- /**********************************************************/
- void display_char()
- {
- P0=0xff;//段選口置高,消影
- P2=~0x24;
- P0=~0x02;//顯示字符“-”
- delay_1ms(5);//延時5ms
- }
- /**********************************************************/
- //函數名:display(uchar sec,min,hour)
- //功能:8位數碼管顯示
- //調用函數:display_num(uchar num,dis_w),display_char()
- //輸入參數:sec,min,hour
- //輸出參數:
- //說明:數碼管顯示完整的時間
- /**********************************************************/
- void display(uchar sec,min,hour)
- {
- display_num(sec,0x01);//顯示秒
- display_num(min,0x08);//顯示分
- display_num(hour,0x40);//顯示小時
- display_char();//顯示分隔符“-”
- }
- /**********************************************************/
- //函數名:time_take()
- //功能:時間調整
- //調用函數:
- //輸入參數:
- //輸出參數:
- //說明:通過time_t的值調整個時間單位,24小時制,定時報警
- /**********************************************************/
- void time_take()
- {
- if(((hour_now==hour_a1&min_now==min_a1)|(hour_now==hour_a2&min_now==min_a2))&
- ((sec_now<6&time_cdk==0)|(sec_now>55&time_cdk==1)))//判斷是否到定時值
- beep=0;//到定時值,啟動蜂鳴器
- else
- beep=1;//未到定時值,關蜂鳴器
- if(time_t>=1000)//當總延時數為1s時
- {
- time_t=0;//time_t清零
- if(time_cdk==0)
- {
- sec_now++;//秒加1
- if(sec_now>=60)//當秒值等于60時
- {
- sec_now=0;//秒值清零
- min_now++;//分加1
- if(min_now>=60)//當分等于60時
- {
- min_now=0;//分清零
- hour_now++;//小時加1
- if(hour_now>=24)//當小時等于24時
- hour_now=0;//小時清零
- }
- }
- }
- else
- sec_now--;//秒加1
- if(sec_now<0)//當秒值等于60時
- {
- sec_now=59;//秒值清零
- min_now--;//分加1
- if(min_now<0)//當分等于60時
- {
- min_now=59;//分清零
- hour_now--;//小時加1
- if(hour_now<0)//當小時等于24時
- hour_now=23;//小時清零
- }
- }
- }
- }
- /**********************************************************/
- //函數名:keyscan()
- //功能:得出4x4鍵盤的行列掃描值
- //調用函數:delay_1ms(uint x)
- //輸入參數:
- //輸出參數:
- //說明:通過P1口的掃描得出掃描值key,無鍵按下key為0
- /**********************************************************/
- uchar keyscan()
- {
- uchar code_h;//行編碼
- uchar code_l;//列編碼
- P1=0XF0;
- if((P1&0xF0)!=0XF0)
- {
- delay_1ms(5);//調用定時函數
- if((P1&0xF0)!=0XF0)
- {
-
- code_h=0xfe;
- while((code_h&0x10)!=0x00)
- {
- P1=code_h;
- if((P1&0xF0)!=0XF0)
- {
- code_l=(P1&0xF0|0x0F);
- return((~code_h)+(~code_l));
- }
- else
- code_h=(code_h<<1)|0x01;
- }
- }
- }
- return(0);//無鍵按下返回0
- }
- /**********************************************************/
- //函數名:keynum()
- //功能:得出4x4按鍵的鍵值
- //調用函數:keyscan()
- //輸入參數:
- //輸出參數:
- //說明:通過key的值確定安鍵鍵值
- /**********************************************************/
- void keynum()
- {
- uchar i,j;
- uchar code tab[4][4]={{1,2,3,4},{5,6,7,8},{9,0,11,12},{13,14,15,16}};
- //4x4鍵盤各鍵值標注
- key=0;
- key=keyscan();//引入key值
- if((key&0x01)!=0) i=0;
- if((key&0x02)!=0) i=1;
- if((key&0x04)!=0) i=2;
- if((key&0x08)!=0) i=3;
- if((key&0x10)!=0) j=0;
- if((key&0x20)!=0) j=1;
- if((key&0x40)!=0) j=2;
- if((key&0x80)!=0) j=3;
- if(key!=0) key_num=tab[i][j];//通過比較得出4x4鍵盤的鍵值
- }
- /**********************************************************/
- //函數名:keyplay(uchar sec,min,hour,tkey)
- //功能:時間調整,包括定時時間
- //調用函數:display(uchar sec,min,hour);keynum()
- //輸入參數:
- //輸出參數:
- //說明:tkey的值確定調整的時間類型,帶除錯功能
- /**********************************************************/
- void keyplay(uchar sec,min,hour,tkey)
- {
- uchar data timenum[]={0,0,0,0,0,0};//建立時間各單位數組
- uchar i=0,take_key;
- keynum();//調用鍵值程序
- if(key_num==16)//按鍵值為16時
- {
- time_cdk=1;//倒計時開關置1
- }
- if(key_num==15)//按鍵值為15時
- {
- time_cdk=0;//倒計時開關置0
- }
- if(key_num==tkey)//判斷調整鍵有無按下
- {
- take_key=1;//循環開關值設1
- timenum[0]=hour/10;
- timenum[1]=hour%10;
- timenum[2]=min/10;
- timenum[3]=min%10;//將原時間引入修改模式
- while(take_key)//判斷是否在設定模式中
- {
- keynum();
- while(key!=0)//鍵盤松手檢測
- keynum();
- if(key_num<11)//判斷鍵值是否為0-9數字鍵
- {
- i++;
- timenum[i-1]=key_num;//鍵值賦值于數組
- key_num=17;//鍵值清空
- }
- if(key_num==12)//判斷有無按下確定鍵
- take_key=0;//開關值置0,跳出循環
- if(i==6)
- take_key=0;//6位數調整結束,自動跳出循環
- hour=timenum[0]*10+timenum[1];
- min=timenum[2]*10+timenum[3];
- sec=timenum[4]*10+timenum[5];//調整值賦值于調整時間
- display(sec,min,hour);
- }
- if(sec>59)
- sec=0;
- if(min>59)
- min=0;
- if(hour>23)
- hour=0;//時間溢出排錯
- if(tkey==11)//調整鍵11為實時時間調整
- {
- sec_now=sec;
- min_now=min;
- hour_now=hour;
- }
- if(tkey==13)//調整鍵13為定時值a1調整
- {
- sec_a1=sec;
- min_a1=min;
- hour_a1=hour;
- }
- if(tkey==14)//調整鍵14為定時值a2調整
- {
- sec_a2=sec;
- min_a2=min;
- hour_a2=hour;
- }
- }
- }
- /**********************************************************/
- /**********************************************************/
- void main()
- {
- sec_now=57;
- min_now=59;
- hour_now=23;
- sec_a1=0;
- min_a1=0;
- hour_a1=0;
- sec_a2=1;
- min_a2=1;
- hour_a2=1; //各時間初始化
- time_cdk=0;
- while(1)
- {
- display(sec_now,min_now,hour_now);//顯示實時時間
- time_take();//調用時間調整程序
- keyplay(sec_now,min_now,hour_now,11);//調整的時間為實時時間
- keyplay(sec_a1,min_a1,hour_a1,13);//調整的時間為定時值a1
- keyplay(sec_a2,min_a2,hour_a2,14);//調整的時間為定時值a2
- }
- }
復制代碼 全部資料51hei下載地址:
八位一體時鐘加矩陣鍵盤.zip
(58.54 KB, 下載次數: 38)
2020-7-31 11:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|