
在之前的文章中我們學習了多位數碼管時鐘,既然有了時間,那我們為何不將他變為一個可以定時的鬧鐘呢,這樣不就更加的方便我們了嗎。這一章我們將開始對數碼管定時鬧鐘的學習。
(資料圖)
一、功能概述
既然我們已經可以實現多位數碼管顯示時間,那么我們在這個時間的基礎上加上一個蜂鳴器,用按鍵的方式來調整我們所需要定時的時間,當時間到時進入外部中斷來控制蜂鳴器,而按鍵同樣也是外部中斷的方法。外部中斷的觸發方法有電平觸發和邊沿觸發兩種方式,這兩種方式都可以我們人為的去設定它。
二、顯示原理
使用AT89C51單片機來對數碼管進行時間的顯示,外加蜂鳴器起到鬧鐘的作用。這一章節我們先了解按鍵外部中斷的原理以及如何對按鍵控制時間的增減。
外部中斷分為兩個部分,中斷初始化部分和外部中斷服務函數。初始化部分是對中斷進行設定,確定所選用的中斷是哪一個,以及觸發中斷的條件,還有中斷的優先級順序。
//中斷初始化void Interrupt_eint(){EX0 = 1; //開啟外部中斷0IT0 = 1; //設置外部中斷0觸發模式:下降沿觸發EX1 = 1; //開啟外部中斷1IT1 = 1; //設置外部中斷1觸發模式EA = 1; //開啟總中斷PX0 = 1; //將外部中斷的優先級提高}//外部0中斷服務函數void int0() interrupt 0{uchar j = 0;for(j = 0;j<=3;++j) {DisplayNum(j);delay_ms(1000); }}
我們以代碼的方式進行中斷的解讀,之后的學習我們也可以利用這兩段代碼來進行運用外部中斷。
三、電路連接
這里我們選用P3.0、P3.1、P3.2作為我們三個按鍵控制的引腳
定義代碼如下:
voidkey(){while(key2==0){input();break;}if(key1==0){delayms(200);if(key1==0)//{while(!key1){TR0=0;display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}TR0=1;}{TR0=!TR0;while(!key1)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}//else if(TR0==0)TR0=1;}else if(key1==1){mode++;if(mode==2)mode=0;}}if(key3==0){delayms(200);if(key3==0){if(mode==0{time[0]=0;time[1]=0;time[2]=0;num=0;while(!key3)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}else if(mode==1){time_clk[0]=0;time_clk[1]=0;time_clk[2]=0;while(!key3)display(time_clk[0]/10,time_clk[0]%10,time_clk[1]/10,time_clk[1]%10,time_clk[2]/10,time_clk[2]%10);}}else if(key3==1){buffer=1;/*P1=1;*/} } }
當我們在使用按鍵的時候還需要對按鍵進行掃描,按鍵掃描的目的是為了讓設備知道我們的按鍵是按下了還是松開,避免產生錯誤。
按鍵掃描代碼:
uchar keyscan()//矩陣鍵盤掃描函數{keyvalue=99;P3=0xfe;temp=P3; temp=temp&0xf0;//判斷是否還等于0xf0while(temp!=0xf0){delayms(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xee:{keyvalue=0;keydown=1;break;}case 0xde:{keyvalue=1;keydown=1;break;}case 0xbe:{keyvalue=2;keydown=1;break;}case 0x7e:{keyvalue=3;keydown=1;break;}}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3; temp=temp&0xf0;//判斷是否還等于0xf0while(temp!=0xf0){delayms(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xed:{keyvalue=4;keydown=1;break;}case 0xdd:{keyvalue=5;keydown=1;break;}case 0xbd:{keyvalue=6;keydown=1;break;}case 0x7d:{keyvalue=7;keydown=1;break;}}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3; temp=temp&0xf0;//判斷是否還等于0xf0while(temp!=0xf0){delayms(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xeb:{keyvalue=8;keydown=1;break;}case 0xdb:{keyvalue=9;keydown=1;break;}case 0xbb:{keyvalue=10;keydown=1;break;}case 0x7b:{keyvalue=11;keydown=1;break;}}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3; temp=temp&0xf0;//判斷是否還等于0xf0while(temp!=0xf0){delayms(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xe7:{keyvalue=12;keydown=1;break;}case 0xd7:{keyvalue=13;keydown=1;break;}case 0xb7:{keyvalue=14;keydown=1;break;}case 0x77:{keyvalue=15;keydown=1;break;}}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}return keyvalue;}
同時中斷中也需要對我們每一下按鍵的按下進行一定的描述,當按鍵被觸發情況發生的時候,程序應該干嘛。
代碼如下:
void T0_time() interrupt 1//中斷函數{TH0=(65536-45872)/256;TL0=(65536-45872)%256;num++;if(num==20)//循環20次為一秒{num=0;time[2]++;//秒加一if(time[2]==60)//秒到60進位{time[2]=0;//秒清零分鐘加一time[1]++;if(time[1]==60)//分鐘到60進位{time[1]=0;//分鐘清零小時加一time[0]++; soundTime();//整點報時if(time[0]==24)//小時滿24清零time[0]=0;}}if((time[0]==time_clk[0])&&(time[1]==time_clk[1])&&(time[2]==time_clk[2])){buffer=0;/*P1=0;*/}}}
蜂鳴器也是在中斷中實現的,當到達我們所設定的時間后,對它的電平進行改變就可以實現發聲了。
代碼如下:
voidsoundTime(){buffer=0;delayms(10);buffer=1;}
四、總結
本章我們先對按鍵以及外部中斷進行學習,外部中斷的兩種觸發方式,以及對中斷服務程序的學習,這樣對于將來設計我們的數碼管鬧鐘的時候能提供更加廣闊的思路,不在局限于用一個循環或者一個主函數去完成一個設計,畢竟一個設計都是分為一步一步去完成的,每個模塊相互結合也能讓我們的設計更加的富有邏輯。
標簽: