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