實例91 具有校正功能的時鐘1302(LCD1602顯示)
上例時鐘電路是開機顯示PC機時間,無時鐘校正功能,本例具有時鐘校正功能。
⒈ 電路設計
在上例時鐘電路的基礎上,加入3個時鐘修正按鍵:K0(修正)、K1(移位)和K2(加1),分別與80C51P2.7、P2.5和P2.3連接,如圖7-6所示。
⒉ 程序設計
按圖7-6電路,要求開機顯示2012年1月1日13時47分58秒,星期日(7),且要求K0、K1和K2具有時鐘校正功能,其控制過程為:按下K0(帶鎖),進入時鐘修正;首先年數據(12)快速閃爍,表示可被修正;按一次K1(不帶鎖),被修正位(快速閃爍)按年、周、月、日、時、分、秒次序循環往復;按一次K2(不帶鎖),被修正位加1(最大值不超過時鐘規定值,超過復0);時鐘修正期間,計時繼續運行;釋放K0,退出時鐘修正。
#include <reg51.h> //包含訪問sfr庫函數reg51.h
sbit RST=P1^0; //定義RST為P1.0(1302復位/片選端)
sbit SCLK=P1^1; //定義SCLK為P1.1(1302時鐘端)
sbit IO=P1^2; //定義IO為P1.2(1302數據端)
sbit E=P1^3; //定義E為P1.3(1602使能片選端)
sbit RW=P1^4; //定義RW為P1.4(1602讀/寫控制端)
sbit RS=P1^5; //定義RS為P1.5(1602寄存器選擇端)
sbit K0=P2^7; //定義K0為P2.7(時鐘修正標志鍵)
sbit K1=P2^5; //定義K1為P2.5(時鐘修正移位鍵)
sbit K2=P2^3; //定義K2為P2.3(時鐘修正加1鍵)
sbit ACC7=ACC^7; //定義ACC7為累加器A第7位ACC.7
bit f=0; //定義0.15s標志f
unsigned char m=0; //定義50ms計數器m,并賦初值0
unsigned char n=6; //定義修正位序號n,n賦初值6(年序號)
unsigned char b[8]; //定義時鐘數據數組b,內存秒分時日月周年即時讀出值(BCD碼)
unsigned char y[]="2000-00-00-Week0"; //定義1602第一行年月日數組y:20××-××-××-Week×
unsigned char h[]="00:00:00--------"; //定義1602第二行時分秒數組h:××:××:××--------
void Wr8b (unsigned char d); //1302寫8位數據子函數(寫入數據d)。略,見實例90
unsigned char Rd8b (); //1302讀8位數據子函數。略,見實例90
void Cmd_Wr(unsigned char c,d); //1302命令寫一字節子函數。略,見實例90
void Bst_Rd (unsigned char t[]); //1302突發讀時鐘子函數。形參t[]。略,見實例90
void Bst_Wr(unsigned char t[]); //1302突發寫時鐘子函數。略,見實例90
void out (unsigned char x); //1602并行數據輸出子函數。略,見實例61
void init1602 ( ); //1602初始化設置子函數。略,見實例61
void wr1602(unsigned char d[],a); //寫1602子函數。略,見實例61
void chag (unsigned char y[],unsigned char h[],unsigned char b[]); //時鐘數據轉換顯示數子函數
//形參:1602第一行顯示數組y[]、第二行顯示數組h[]、時鐘數據數組b[]。略,見實例90
⒊ Keil調試
本題Keil調試同上例。因涉及外圍元件DS1302和LCD1602,在Keil軟件調試中無法得到外圍元件的有效信號。因此,僅在Keil中,按實例1所述步驟,編譯鏈接,語法糾錯,自動生成Hex文件,并在變量觀察窗口Watch頁中設置(設置方法參閱圖8-30)全局變量b(時鐘數據數組)、y(第一行年月日數組)和h(第二行時分秒數組),獲得數組b[]、y[]和h[]的首地址(分別為0x21、0x3c、0x29,用于在Proteus仿真中觀測)。
需要注意的是,引用前述實例中的9個子函數必須插入,否則Keil調試將顯示出錯。
⒋ Proteus仿真
⑴ 按實例23所述Proteus仿真步驟,打開Proteus ISIS軟件,按表7-4選擇和放置元器件,并連接線路,畫出Proteus仿真電路如圖7-7所示。
⑵ 鼠標左鍵雙擊Proteus ISIS仿真電路中AT89C51,裝入Keil調試后自動生成的Hex文件。
⑶ 全速運行后,1602顯示實時時鐘,初始值為程序中設置的2012年1月1日13時47分58秒,周7(日),并隨后不斷更新實時數值。
⑷ 按下K0(鎖定),進入時鐘修正。
需要說明的是,本例選用的BUTTON按鍵有兩種運行功能:有鎖運行和無鎖運行。作有鎖運行時,鼠標左鍵單擊按鍵圖形中小紅圓點,單擊第一次閉鎖,第二次開鎖。作無鎖運行時,鼠標左鍵單擊按鍵圖形中鍵蓋帽“ ”,單擊一次,鍵閉合后彈開一次,不閉鎖。
① 首先年數據快速閃爍,表示年數據允許修正。此時每按一次K2(鼠標左鍵單擊鍵圖形中鍵蓋帽“ ”,單擊一次,鍵閉合后彈開一次,不閉鎖),年數據顯示數加1,但不超過年最大值2099,超過時復位2000。
② 若再按一次K1(不閉鎖,方法同K2),被修正位(快速閃爍,表示該位允許修正)移至周數據,每按一次K2,周數據顯示數加1,但不超過周最大值7,超過時復位1。
③ 再按一次K1,被修正位(快速閃爍)移至月數據,每按一次K2,月數據顯示數加1,但不超過月最大值12,超過時復位1。
④ 再按一次K1,被修正位(快速閃爍)移至日數據,每按一次K2,日數據顯示數加1,但不超過規定的最大值(閏年2月,日數≤29;非閏年2月,日數≤28;4、6、9、11月,日數≤30;其余月份,日數≤31),超過時復位1。
⑤ 再按一次K1,被修正位(快速閃爍)移至時數據,每按一次K2,時數據顯示數加1,但不超過最大值23,超過時復位0。
⑥ 再按一次K1,被修正位(快速閃爍)移至分數據,每按一次K2,分數據顯示數加1,但不超過最大值59,超過時復位0。
⑦ 再按一次K1,被修正位(快速閃爍)移至秒數據,每按一次K2,秒數據顯示數加1,但不超過最大值59,超過時復位0。
⑧ 再按一次K1,被修正位(快速閃爍)重新移至年數據。這樣,按年周月日時分秒次序循環往復;按一次K2(不帶鎖),被修正位加1(最大值不超過時鐘規定值);釋放K0,退出時鐘修正。
⑸ 再按一次K0,K0釋放,退出時鐘修正。
⑹ 按暫停按鈕,打開80C51片內RAM(主菜單Debug→80C51 CPU→Internal(IDATA)Memory -U1),可看到21H~28H、29H~38H和3CH~4BH中,已經依次存放了時鐘數據數組b[]、第二行時分秒數組h[]和第一行年月日數組y[]的即時數據。
⑺ 終止程序運行,可按停止按鈕。
⒌ 思考與練習
秒、分、時、日、月、周、年數據上限值各不相同,加一超限時如何判別修正?
|