155948wdb1ixxzcxbb1chc.png (6.95 KB, 下載次數: 83)
下載附件
2019-7-30 09:07 上傳
基于AT89C52單片機的電子時鐘(LCD)的設計摘要:單片機因將其主要組成部分集成在一個芯片上而得名,就是把中 央 處理器、隨機存儲器、只讀存儲器、中斷系統、定時器/計數器以及 I/O 接口電 路等部件集成在一個芯片上。 基于單片機設計的數字鐘精確度較高, 因為在程序的執行過程中, 任何指 令都不影響定時器的正常計數,即便程序很長也不會影響中斷的時間。數字鐘是采用數字電路實現對日期、時、分、秒,數字顯示的計時裝置,由 于數字集成電路的發展和石英晶體振蕩器的廣泛應用,使得數字鐘的精度,遠遠 超過老式鐘表,鐘表的數字化給人們生產生活帶來了極大的方便,而且大大地擴展了鐘表的報時功能。 數字鐘已成為人們日常生活中的必需品,廣泛應用于家庭、車站、碼頭、劇院、辦公室等場所,給人們的生活、學習、工作帶來極大的方便。 不僅如此,在現代化的進程中,也離不開電子鐘的相關功能和原理,比如機械手 的控制、家務的自動化、定時自動報警、按時自動打鈴、時間程序自動控制、定時廣播、自動起閉路燈、定時開關烘箱、通斷動力設備、甚至各種定時電氣的自 動啟用等,所有這些,都是以鐘表數字化為基礎的。而且是控制的核心部分。因 此,研究數字鐘及擴大其應用,有著非,F實的意義。 本設計使用 12MHZ 晶振與單片機 AT89C52 相連接,以 AT89C52 芯片為核心, 采用動態掃描方式顯示,通過使用該單片機,通過 4 個按鍵進行調時、復位等功能,在實現各功能時LCD進行相應顯示。軟件部分用 C 語言實現,分為顯示、延遲、調時、復位等部分。通過軟硬件結合達到最終目的。 關鍵詞:電子時鐘 AT89C52單片機 LCD1602顯示屏 定時中斷
第一章 設計任務與要求
1.1內容以AT89C52單片機為核心的時鐘,在LCD顯示器上顯示當前的時間。 1.2要求l 使用字符型LCD顯示器顯示當前時間。 l 顯示格式為“時時:分分:秒秒”。 l 用4個功能鍵操作來設置當前時間。 功能鍵K1~K4功能如下: l K1—進入設置現在的時間。 l K2—設置小時。 l K3—設置分鐘。 l K4—確認完成設置。 程序執行后工作指示燈LED閃動,表示程序開始執行,LCD顯示“00:00:00”,然后開始計時。 l 拓展功能:實現整時提示,在08:00---20:00進行提示3秒,在其他的時間段不會提示。 1.3單片機系統運行流程程序首先進行初始化,在主程序的循環程序中首先調用數據處理程 序,然后調用顯示程序,在判斷是否有按鍵按下。啟動仿真,若按下按鍵1,可發現LED停止閃爍,按下按鍵2和按鍵3后,可改變時間,按下按鍵4后,時鐘復位到修改時間。
附錄:源代碼#include<reg52.h> #define uchar unsigned char #define uint unsigned int #define KEY_IO P3 #define LCD_IO P0
sbit LCD_RS = P2^0; sbit LCD_RW = P2^1; sbit LCD_EN = P2^2;
sbit SPK = P1^2;//定義蜂鳴器 sbit LED = P2^4;//定義LED
bit new_s, modify = 0; char t0, sec = 50, min = 59, hour = 07;
char code LCD_line1[] = " a wonderful day "; char code LCD_line2[] = " Time: 00:00:00 "; char Timer_buf[] = "00:00:00";
void delay(uint z)//延時函數 { uint x, y; for(x = z; x > 0; x--) for(y = 100; y > 0; y--); }
void W_LCD_Com(uchar com) //寫指令 { LCD_RS = 0; LCD_IO = com; //RS和RW都為低電平,寫入指令 LCD_EN = 1; //用EN輸入一個高脈沖 delay(5); LCD_EN = 0; }
void W_LCD_Dat(uchar dat) //寫數據 { LCD_RS = 1; LCD_IO = dat; //RS為高電平和RW為低電平,寫入數據 LCD_EN = 1; //用EN輸入一個高脈沖 delay(5); LCD_EN = 0; }
void W_LCD_STR(uchar *s) //寫字符串 { while(*s) W_LCD_Dat(*s++); }
void W_BUFF(void) //時、分、秒顯示 { Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;
Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;
Timer_buf[1] = hour % 10 + 48; Timer_buf[0] = hour / 10 + 48;
W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf); } uchar read_key(void) { uchar x1, x2; KEY_IO = 255; x1 = KEY_IO; if (x1 != 255) { delay(100); x2 = KEY_IO; if (x1 != x2) return 255; while(x2 != 255) x2 = KEY_IO; if (x1 == 0x7f) return 0; else if (x1 == 0xbf) return 1; else if (x1 == 0xdf) return 2; else if (x1 == 0xef) return 3; else if (x1 == 0xf7) return 4; } return 255; }
void Init() { LCD_RW = 0; W_LCD_Com(0x38); delay(50); W_LCD_Com(0x0c); W_LCD_Com(0x06); W_LCD_Com(0x01); W_LCD_Com(0x80); W_LCD_STR(LCD_line1); W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);
TMOD = 0x01; //T0定時方式1 TH0 = 0x4c; TR0 = 1; //啟動T0 ET0 = 1; EA = 1; }
void main() { uint i, j; uchar Key; Init(); while(1) {
if (new_s) { //出現新的一秒,修改時間 new_s = 0; sec++; sec %= 60; if(!sec) { min++; min %= 60; if(!min) { hour++; hour %= 24;} } W_BUFF();
if (!min) {if(hour>=8&&hour<=20&&sec<=3)//當在08:00—20:00之間整點報時 for (i = 0; i < 200;i++) { SPK = 0; for (j = 0; j< 100; j++); SPK = 1; for (j = 0; j< 100; j++); } } }
Key = read_key(); //讀按鍵 switch(Key) { case 0: modify = 1; break;//修改鍵 case 1: if(modify) {min++; min %= 60; W_BUFF(); break;} case 2: if(modify) {hour++; hour %= 24; W_BUFF();break;} case 3: modify = 0; break;//確認鍵 } } } void timer0(void) interrupt 1 //T0中斷,50MS執行一次 { TH0 = 0x4c; t0++; t0 %= 20; if(t0 == 0) //20,一秒 {new_s = 1; LED = ~LED;} if(modify) LED = 0; }
|