基于51单片机的电子时钟
基于51單片機(jī)的電子時(shí)鐘設(shè)計(jì)
目錄
基于51單片機(jī)的電子時(shí)鐘設(shè)計(jì)
一、需求分析
1.1?前言
1.2研究?jī)r(jià)值及意義
1.3 任務(wù)目標(biāo)
一、總體設(shè)計(jì)
2.1 設(shè)計(jì)思路
2.2 總體框架
2.3 主要元件說(shuō)明
2.3.1?AT89C51單片機(jī)
2.3.2 LCD1602液晶顯示器
2.3.3 24C02C存儲(chǔ)芯片
2.3.4 DS1302時(shí)鐘芯片
三、詳細(xì)設(shè)計(jì)
3.1 液晶顯示模塊設(shè)計(jì)
3.1.1 硬件設(shè)計(jì)
3.2 時(shí)間產(chǎn)生模塊設(shè)計(jì)
3.2.1 硬件設(shè)計(jì)
3.2.2 軟件設(shè)計(jì)
3.3 數(shù)據(jù)存儲(chǔ)模塊設(shè)計(jì)
3.3.1 硬件設(shè)計(jì)
3.3.2 軟件設(shè)計(jì)
3.4 按鍵處理模塊設(shè)計(jì)
3.4.1 硬件設(shè)計(jì)
3.4.2 軟件設(shè)計(jì)
四、程序運(yùn)行結(jié)果測(cè)試與分析
4.1 LCD1602功能測(cè)試
4.2 DS1302功能測(cè)試
4.3 24C02C功能測(cè)試
4.4 調(diào)整時(shí)間功能測(cè)試
一、需求分析
1.1?前言
單品微型計(jì)算機(jī)簡(jiǎn)稱單片機(jī),是典型的嵌入式微控制器(Microcontroller Unit),常用英文字母的縮寫MCU表示單片機(jī),單片機(jī)又稱單片微控制器,它不是完成某個(gè)邏輯功能的芯片,而是把一個(gè)計(jì)算機(jī)系統(tǒng)集成到一個(gè)芯片上。相當(dāng)于一個(gè)微型的計(jì)算機(jī),和計(jì)算機(jī)相比,單片機(jī)只缺少了I/O 設(shè)備。
單片機(jī)作為應(yīng)用最廣泛的控制系統(tǒng)之一,具有體積小,易于控制,價(jià)格便宜,安全可靠等等優(yōu)良的性能而被廣泛的關(guān)注。無(wú)論是小到兒童玩具,到工業(yè)控制系統(tǒng),大到航天航空系統(tǒng)的設(shè)計(jì)與操作之中,隨處可見單片機(jī)的蹤影。
由于單片機(jī)在工業(yè)控制領(lǐng)域的廣泛應(yīng)用,單片機(jī)由芯片內(nèi)僅有CPU的專用處理器發(fā)展而來(lái)。最早的設(shè)計(jì)理念是通過(guò)將大量外圍設(shè)備和CPU集成在一個(gè)芯片中,使計(jì)算機(jī)系統(tǒng)更小,更容易集成進(jìn)復(fù)雜的而對(duì)體積要求嚴(yán)格的控制設(shè)備當(dāng)中。
1.2研究?jī)r(jià)值及意義
電子鐘亦稱數(shù)顯鐘(數(shù)字顯示鐘),是一種用數(shù)字電路技術(shù)實(shí)現(xiàn)時(shí)、分、秒計(jì)時(shí)的裝置,與機(jī)械時(shí)鐘相比,直觀性為其主要顯著特點(diǎn),且因非機(jī)械驅(qū)動(dòng),具有更長(zhǎng)的使用壽命,相較石英鐘的石英機(jī)芯驅(qū)動(dòng),更具準(zhǔn)確性。電子鐘已成為人們?nèi)粘I钪斜夭豢缮俚谋匦杵?#xff0c;廣泛用于個(gè)人家庭以及車站、碼頭、劇院、辦公室等公共場(chǎng)所,給人們的生活、學(xué)習(xí)、工作、娛樂帶來(lái)極大地方便。相對(duì)于其他時(shí)鐘類型,它的特點(diǎn)可歸結(jié)為“兩強(qiáng)一弱”: 比機(jī)械鐘強(qiáng)在觀時(shí)顯著,比石英鐘強(qiáng)在走時(shí)準(zhǔn)確,但是它的弱點(diǎn)為顯時(shí)較為單調(diào)。
?
1.3 任務(wù)目標(biāo)
使用DS1302芯片作為計(jì)時(shí)設(shè)備,用6個(gè)7段LED數(shù)碼管或者LCD162作為顯示設(shè)備,實(shí)現(xiàn)時(shí)鐘功能;
功能要求:
(1)可以分別設(shè)定小時(shí)、分鐘和秒,復(fù)位后時(shí)間為00:00:00;
(2)秒鐘復(fù)位功能,秒復(fù)位鍵按下后,秒回到00。
(3)用EEPROM芯片存儲(chǔ)數(shù)據(jù)
?
一、總體設(shè)計(jì)
2.1 設(shè)計(jì)思路
(1)定義一個(gè)表示時(shí)間的數(shù)組,聲明為外部變量,可以在各個(gè)模塊中進(jìn)行訪問,以此來(lái)建立它們之間的關(guān)聯(lián)。
(2)電子時(shí)鐘的時(shí)間數(shù)據(jù)由DS1302實(shí)時(shí)時(shí)鐘芯片來(lái)產(chǎn)生并顯示在LCD1602上顯示;通過(guò)定時(shí)器掃描按鍵的方式得到按鍵按下的鍵值,在主程序中根據(jù)得到的鍵值調(diào)用不同的按鍵處理函數(shù)(調(diào)時(shí)、保存數(shù)據(jù)、讀取數(shù)據(jù)等),當(dāng)要對(duì)時(shí)間數(shù)據(jù)進(jìn)行操作時(shí),可以先對(duì)數(shù)組中的數(shù)進(jìn)行操作,操作完成后再把數(shù)組中的各個(gè)元素寫入DS1302芯片。
(3)把各種模塊需要實(shí)現(xiàn)的功能都封裝成函數(shù)并在頭文件中聲明。例如LCD1602除了需要顯示時(shí)間這個(gè)數(shù)字類型外,還需要顯示字符、字符串等,所以可以定義多個(gè)函數(shù)來(lái)實(shí)現(xiàn)顯示各種數(shù)據(jù)類型。
2.2 總體框架
本項(xiàng)目主要包含這么四個(gè)模塊,分別是DS1302時(shí)鐘模塊、LCD1602顯示模塊、按鍵處理模塊以及EEPROM存儲(chǔ)模塊。總體框架如圖2-1所示,每一個(gè)模塊的詳細(xì)設(shè)計(jì)說(shuō)明會(huì)在下一章進(jìn)行介紹。
圖2-1 總體框架圖
系統(tǒng)的總體流程圖如圖2-2所示。
? ? ??
圖2-2 總體流程圖
?
2.3 主要元件說(shuō)明
2.3.1?AT89C51單片機(jī)
ATC89C51是采用8051 核的ISP (In SystemProgramming)在系統(tǒng)可編程芯片,最高工作時(shí)鐘頻率為80MHz,片內(nèi)含8K Bytes的可反復(fù)擦寫1000 次的Flash只讀程序存儲(chǔ)器,器件兼容標(biāo)準(zhǔn)MCS-51指令系統(tǒng)及80C51引腳結(jié)構(gòu),芯片內(nèi)集成了通用8位中央處理器和ISP Flash存儲(chǔ) 單元,具有在系統(tǒng)可編程(ISP)特性,配合PC端的控制程序即可將用戶的程序代碼下載進(jìn)單片機(jī)內(nèi)部,省去了購(gòu)買通用編程器,而且速度更快。ATC89C51是本系統(tǒng)的核心元件,控制著整個(gè)系統(tǒng)的運(yùn)行。
?
2.3.2 LCD1602液晶顯示器
LCD1602可以顯示2行16個(gè)字符,有8位數(shù)據(jù)總線DO-D7,和RS、R/W、EN三個(gè)控制端口,工作電壓為5V,并且?guī)в凶址麑?duì)比度調(diào)節(jié)和背光。LCD1602引腳說(shuō)明如表2.1所示。LCD1602時(shí)序圖如圖2-3所示。
表2.1 LCD1602引腳說(shuō)明表
| 編號(hào) | 符號(hào) | 引腳說(shuō)明 | 編號(hào) | 符號(hào) | 引腳說(shuō)明 |
| 1 | VSS | 電源地 | 9 | D2 | 數(shù)據(jù) |
| 2 | VDD | 電源正極 | 10 | D3 | 數(shù)據(jù) |
| 3 | VL | 液晶顯示偏壓 | 11 | D4 | 數(shù)據(jù) |
| 4 | RS | 數(shù)據(jù)/命令選擇 | 12 | D5 | 數(shù)據(jù) |
| 5 | R/W | 使能信號(hào) | 13 | D6 | 數(shù)據(jù) |
| 6 | E | 數(shù)據(jù) | 14 | D7 | 數(shù)據(jù) |
| 7 | D0 | 數(shù)據(jù) | 15 | BLA | 背光源正極 |
| 8 | D1 | 數(shù)據(jù) | 16 | BLK | 背光源正極 |
第1引腳:GND為電源地。
第2引腳: VCC接5V電源正極。
第3引腳: V0為液晶顯示器對(duì)比度調(diào)整端,接正電源時(shí)對(duì)比魔最弱。接地電源時(shí)對(duì)比度最離(對(duì)比廈過(guò)離時(shí)會(huì)產(chǎn)生"鬼影”.使用時(shí)可以通過(guò)一個(gè)10K的電位器調(diào)整對(duì)比度)。
第4引腳RS為箭存器選擇,離電平1時(shí)選擇微據(jù)寄存器低電竿0時(shí)選擇指令寄存器.
第5引腳RW為讀寫情號(hào)線,離電平(1)時(shí)進(jìn)行讀操作,以51為例的簡(jiǎn)草原理圖低電平(0)時(shí)進(jìn)行寫操作。
第6引腳: E(或EN)端為使能(enable)端,離電子(1)時(shí)讀取信息,負(fù)眺變時(shí)執(zhí)行指令.
第7-14引腳DO- D7為8位雙向擻據(jù)端。第15-16腳空腳或青燈電源.第15引腳背光正極.
第16引腳背光負(fù)極。
圖2-3 LCD1602時(shí)序圖
2.3.3 24C02C存儲(chǔ)芯片
(1)引腳功能介紹及相關(guān)知識(shí)
24c02是低工作電壓的2k位豐行電可擦除只讀存儲(chǔ)器,內(nèi)部組織為256個(gè)字節(jié),每個(gè)字節(jié)8位,工作電壓為1.8v-5.5v, 輸入\輸出引腳兼窖為5v,該芯片被廣泛應(yīng)用于低電壓及低功耗的工商業(yè)領(lǐng)城。24c02引腳定義如表2.2所示。
表2.2 24c02引腳定義圖
| 引腳名稱 | 引腳功能 |
| A0-A2 | 器件地址輸入 |
| SDA | 串行數(shù)據(jù)輸入輸出 |
| SCL | 串行時(shí)鐘輸入 |
| WP | 寫保護(hù) |
| VCC | 電源 |
| GND | 地 |
(2)I2C總線協(xié)議
只有總線非忙時(shí)才被允許進(jìn)行數(shù)據(jù)傳送,在傳送時(shí),當(dāng)時(shí)鐘線為高電平,數(shù)據(jù)線必須為固定狀態(tài),不允許有跳變。時(shí)鐘線為高電平時(shí)數(shù)據(jù)線的任何電平變化將被當(dāng)作總線的啟動(dòng)或停止條件。
(3)起始條件
起始調(diào)教必須在所有操作命令之前發(fā)送。時(shí)鐘線保持高電平期間,數(shù)據(jù)線電平從高到低跳變作為I2c 總線的啟動(dòng)信號(hào)。CAT24Cxxx一直監(jiān)視SDA和SCL電平信號(hào),直到條件滿足時(shí)才響應(yīng)。
(4)停止條件
時(shí)鐘線保持高電平期間,數(shù)據(jù)線電平從低到高跳變作為I'C 總線的停止信號(hào)。
(5)器件地址約定
主器件在發(fā)送啟動(dòng)命令后開始傳送數(shù)據(jù),主器件發(fā)送相應(yīng)的從器件地址,8位從器件地址的高四位固定為1010, 接下來(lái)的3位用來(lái)定義存儲(chǔ)器的地址,對(duì)于CAT24C021/022,這三位無(wú)意義,對(duì)于CAT24C41/042,接下來(lái)的2位無(wú)意義,第三位是地址高位,CAT24C081/082中,第一位無(wú)意義,后兩位表示地址高位。最后一位為讀寫控制位,“1” 表示對(duì)從器件進(jìn)行讀寫操作,“0” 表示寫操作。在主器件發(fā)送啟動(dòng)命令和一字節(jié)從器件地址后,如果與從器件地址吻合,CAT24C02將發(fā)送一個(gè)應(yīng)答信號(hào),然后再根據(jù)讀/寫控制為進(jìn)行讀或?qū)懖僮鳌?/p>
(6)應(yīng)答信號(hào)
每次數(shù)據(jù)傳送成功后,接收器件將發(fā)送一個(gè)應(yīng)答信號(hào)。當(dāng)?shù)诰艂€(gè)時(shí)鐘信號(hào)產(chǎn)生時(shí),產(chǎn)生應(yīng)答型號(hào)的器件將SDA下拉為低,通知已經(jīng)接受到8位數(shù)據(jù),接收到起始條件和從器件地址后,CAT24C02 發(fā)送一個(gè)應(yīng)答信號(hào),如果為寫操作,每接收到一個(gè)字節(jié)數(shù)據(jù),CAT24C02 發(fā)送一一個(gè)應(yīng)答信號(hào)。如果為讀操作,CAT24C02發(fā)送一個(gè)字節(jié)數(shù)據(jù)后釋放總線等待應(yīng)答信號(hào),一旦接收到應(yīng)答信號(hào),它將繼續(xù)發(fā)發(fā)送數(shù)據(jù),如果接收到主器件發(fā)送非應(yīng)答信號(hào),將結(jié)束數(shù)據(jù)傳送等待停止條件。
(7)寫操作
在寫字節(jié)模式下,助器件發(fā)送起始命令和從器件地址信息給從器件,在從器件響應(yīng)應(yīng)答信號(hào)后,主器件將要寫入的數(shù)據(jù)地址發(fā)送到CAT24C02的地址指針,主器件收到從器件的應(yīng)答信號(hào)后再送數(shù)據(jù)到相應(yīng)的數(shù)據(jù)存儲(chǔ)區(qū)地址,.CAT24C02再響應(yīng)一個(gè)應(yīng)答信號(hào),主器件產(chǎn)生一個(gè)停止信號(hào),然后CAT24C02啟動(dòng)內(nèi)部寫周期,在內(nèi)部寫周期期間,CAT24C02不再響應(yīng)主器件任何請(qǐng)求。寫操作時(shí)序讀如圖2-4所示:
圖2-4 寫時(shí)序圖
(8)讀操作
CAT24C02讀操作的初始化方式和寫操作一樣, 僅把R/w位置1,讀操作有三種方式:立即地址讀、選擇地址讀、連續(xù)讀。選擇地址讀操作時(shí)序圖如圖2-5所示:
圖2-5 讀時(shí)序圖
2.3.4 DS1302時(shí)鐘芯片
DS1302是一個(gè)實(shí)時(shí)時(shí)鐘芯片,可以提供秒、分、小時(shí)、日期、月、年等信息,并且還有軟年自動(dòng)調(diào)整的能力,可以通過(guò)配置AM/PM來(lái)決定采用24小時(shí)格式還是12小時(shí)格式,它的引腳及功能如下表所示。
單字節(jié)寫入時(shí)序如下圖所示。
由圖可見,先拉高使能端,進(jìn)行使能選擇,然后在時(shí)鐘上升沿寫入一個(gè)字節(jié)。DS1302在進(jìn)行讀寫操作時(shí)最少讀寫兩個(gè)字節(jié),第一個(gè)是控制字節(jié),就是一個(gè)命令,說(shuō)明是讀還是寫操作,第二個(gè)時(shí)需要讀寫的數(shù)據(jù)。對(duì)于單字節(jié)寫,只有在SCLK為低電平時(shí)才能將 CE?置高電平,所以剛開始將SCLK?置低,CE置高,然后把需要寫入的字節(jié)送入 IO口,然后跳變SCLK,在SCLK下降沿時(shí),寫入數(shù)據(jù)。
3.1 液晶顯示模塊設(shè)計(jì)三、詳細(xì)設(shè)計(jì)
在液晶顯示模塊需要實(shí)現(xiàn)的功能有:顯示字符串、顯示字符、顯示十進(jìn)制數(shù)字。字符串用來(lái)表示提示信息,字符用來(lái)表示“:”、“-”等特殊符號(hào),時(shí)間數(shù)據(jù)用十進(jìn)制表示。
3.1.1 硬件設(shè)計(jì)
液晶顯示模塊的硬件連接圖如下圖所示,LCD1602的VSS與地相連、VDD與電源相連、RS與單片機(jī)的P2_6口相連、RW與P2_5口相連、E與P2_7口相連、D0-D7通過(guò)上拉電阻連接到單片機(jī)的P0口(VEE用于調(diào)節(jié)對(duì)比度,此處沒必要連接)。所以給LCD1602送入數(shù)據(jù)也就是給單片機(jī)P0口送數(shù)據(jù),再通過(guò)單片機(jī)的P2_5(RW)、P2_6(RS)、P2_7(E)控制LCD的時(shí)序使其正常工作于各個(gè)過(guò)程。
圖3-1 ?LCD1602硬件接線圖
考慮到代碼的可讀性,首先在程序開頭對(duì)一些需要使用到的位變量和數(shù)據(jù)端口進(jìn)行了定義,代碼如下。
sbit LCD1602_RS=P2^6;sbit LCD1602_RW=P2^5;sbit LCD1602_E=P2^7;#define??LCD1602_DATA??P0在使用LCD1602時(shí),我們通過(guò)寫入指令來(lái)控制待顯示數(shù)據(jù)在液晶顯示器上的位置以及設(shè)置LCD1602的參數(shù);通過(guò)寫入數(shù)據(jù)來(lái)表示具體要顯示的內(nèi)容。接下來(lái),依次對(duì)LCD1602模塊中的各個(gè)函數(shù)進(jìn)行介紹。
(1)寫指令函數(shù)。函數(shù)的參數(shù)即為待寫入的指令。通過(guò)改變RS、RW和E這三個(gè)引腳的電平變化來(lái)對(duì)寫指令的時(shí)序進(jìn)行模擬,代碼如下。
void LCD1602_WriteCmd(unsigned char cmd) {LCD1602_RS=0;LCD1602_RW=0;LCD1602_DATA=cmd;LCD1602_E=1;LCD_Delay();LCD1602_E=0;LCD_Delay(); }(2)寫數(shù)據(jù)函數(shù)。函數(shù)的參數(shù)即為待寫入的數(shù)據(jù)。寫入數(shù)據(jù)和寫入指令唯一的區(qū)別是RS 引腳的電平狀態(tài)不同,RS為低電平期間寫入的是指令,為高電平期間寫入的是數(shù)據(jù),具體代碼如下。
void LCD1602_WriteDat(unsigned char dat) {LCD1602_RS=1;LCD1602_RW=0;LCD1602_DATA=dat;LCD1602_E=1;LCD_Delay();LCD1602_E=0;LCD_Delay(); }(3)初始化函數(shù)。LCD1602在使用之前需要對(duì)它的工作方式進(jìn)行配置,具體的代碼和注釋如下。
void LCD1602_Init() {LCD1602_WriteCmd(0x38);//顯示模式設(shè)置LCD1602_WriteCmd(0x0c);//顯示開LCD1602_WriteCmd(0x06);//顯示光標(biāo)LCD1602_WriteCmd(0x01);//顯示清屏LCD1602_WriteCmd(0x80);//顯示位置第1行1列 }(4)其他函數(shù)。上面介紹的都是最基本的函數(shù),為了在其他模塊中調(diào)用方便,我們?cè)谶@些基本函數(shù)的基礎(chǔ)上加以簡(jiǎn)單的邏輯設(shè)計(jì)還編寫了另外三個(gè)函數(shù)。當(dāng)需要用到液晶顯示器的時(shí)候只需要調(diào)用這三個(gè)函數(shù)即可,下面只對(duì)他們的使用進(jìn)行聲明,代碼較多就不全部列出了。
/*在LCD的第x行第y列上顯示十進(jìn)制數(shù)字num,顯示長(zhǎng)度為z*/void LCD1602_ShowNum(unsigned char x,y,z,num ); //顯示十進(jìn)制數(shù)字 /*在LCD的第x行第y列上顯示首地址為dat的字符串*/ void LCD1602_ShowString(unsigned char x,y,char *dat); //顯示字符串 /*在LCD的第x行第y列上顯示字符dat*/void LCD1602_ShowChar(unsigned char x,y,dat);//顯示單個(gè)字符3.2 時(shí)間產(chǎn)生模塊設(shè)計(jì)
時(shí)間產(chǎn)生模塊需要實(shí)現(xiàn)的功能有:通過(guò)DS1302實(shí)時(shí)時(shí)鐘芯片產(chǎn)生時(shí)間信息,能夠把時(shí)間信息寫入DS1302并且讀取出來(lái)。
3.2.1 硬件設(shè)計(jì)
DS1302與單片機(jī)的硬件接線如下圖所示。在DS1302的X1、X2管教處外接了一個(gè)頻率為32.768KHZ的晶振,為時(shí)鐘運(yùn)行提供一個(gè)穩(wěn)定的時(shí)鐘頻率。RST非、SCLK、I/O分別與單片機(jī)的P3_5、P3_6、P3_4連接,串行數(shù)據(jù)通過(guò)I/O引腳在單片機(jī)和DS1302之間進(jìn)行傳輸。
?
圖3-2 ?DS1302硬件接線圖
3.2.2 軟件設(shè)計(jì)
在程序的最開始首先對(duì)需要用到的位變量進(jìn)行定義和DS1302中特殊意義的常量進(jìn)行宏定義,此外還定義了一個(gè)儲(chǔ)存時(shí)間的全局變量,具體代碼及注釋如下。
#define DS1302_SECOND 0x80//秒 #define DS1302_MINUTE 0x82//分 #define DS1302_HOUR 0x84//小時(shí) #define DS1302_DATE 0x86//日 #define DS1302_MONTH 0x88//月 #define DS1302_DAY 0x8A//星期 #define DS1302_YEAR 0x8C//年 #define DS1302_WP 0x8E//寫保護(hù) sbit DS1302_RST=P3^5; sbit DS1302_SCLK=P3^6; sbit DS1302_IO=P3^4; char DS1302_Time[]={20,1,1,0,0,0,3}; //保存時(shí)間信息 年 月 日 時(shí) 分 秒 星期 //所以在單片機(jī)上電之后DS1302默認(rèn)的時(shí)間就是2020-1-1 00:00:00 星期三在此模塊中最重要也是最基本的兩個(gè)函數(shù)是寫入一個(gè)字節(jié)的函數(shù)(即設(shè)置時(shí)間)和讀取一個(gè)字節(jié)的函數(shù),下面分別對(duì)其進(jìn)行介紹。
(1)單字節(jié)寫函數(shù)。函數(shù)的第二個(gè)參數(shù)表示待寫入的數(shù)據(jù),第一個(gè)參數(shù)表示操作指令。兩個(gè)8位數(shù)據(jù)從高位開始一次一位一位的通過(guò)I/O管腳寫入DS1302。具體代碼如下。
void DS1302_WriteByte(unsigned char cmd,dat) {unsigned char i;DS1302_RST=1;for(i=0;i<8;i++){DS1302_IO=cmd&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}for(i=0;i<8;i++){DS1302_IO=dat&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}DS1302_RST=0;DS1302_SCLK=0; }(2)單字節(jié)讀函數(shù)。函數(shù)的參數(shù)是操作指令,返回值為讀取到的數(shù)據(jù)。這里的指令跟單字節(jié)寫函數(shù)的指令有所不同,它要求指令的最后一位必須為1,而單字節(jié)寫要求為0。所以在代碼中對(duì)參數(shù)cmd進(jìn)行了處理,確保末位為1,具體代碼如下。
unsigned char DS1302_ReadByte (unsigned char cmd) {unsigned char i,DATA=0x00;cmd|=0x01;//確保末位為1DS1302_RST=1;for(i=0;i<8;i++){DS1302_IO=cmd&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}for(i=0;i<8;i++){if(DS1302_IO)DATA=DATA|(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}DS1302_RST=0;return DATA; }(3)設(shè)置時(shí)間函數(shù)。在實(shí)際調(diào)用上面兩個(gè)函數(shù)時(shí),指令實(shí)參一般是開頭定義的宏,數(shù)據(jù)實(shí)參一般是數(shù)據(jù)組中的元素。為了在其他模塊中更好的使用這個(gè)模塊,我們另外定義了兩個(gè)函數(shù)分別用于讀取時(shí)間和設(shè)置時(shí)間,這樣避免了過(guò)于繁瑣的調(diào)用單字節(jié)寫和讀函數(shù),不容易出錯(cuò),只需要對(duì)數(shù)組進(jìn)行操作。具體代碼如下。
void setTime () {DS1302_WriteByte(DS1302_WP,0x00);DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);DS1302_WriteByte(DS1302_WP,0x80); }說(shuō)明:由于時(shí)間在DS1302芯片中是以BCD碼的形式進(jìn)行存儲(chǔ)的,而數(shù)組中的元素是十進(jìn)制,所以我們要把十進(jìn)制轉(zhuǎn)化成BCD碼再寫入DS1302;讀取時(shí)間則反過(guò)來(lái)把BCD碼轉(zhuǎn)化成十進(jìn)制。?
?
3.3 數(shù)據(jù)存儲(chǔ)模塊設(shè)計(jì)
本模塊使用基于I2C協(xié)議的存儲(chǔ)芯片24C02C來(lái)保存時(shí)間數(shù)據(jù),需要實(shí)現(xiàn)的功能包括寫入數(shù)據(jù)和讀取數(shù)據(jù)。
3.3.1 硬件設(shè)計(jì)
24C02C與單片機(jī)的鏈接圖如下圖所示,時(shí)鐘線SCK由單片機(jī)P2_1口控制,數(shù)據(jù)線SDA由P2_0口控制,寫保護(hù)管腳WP和表示地址的A0-A2均接地。因此,24C02C的寫保護(hù)處于失能狀態(tài),也就是說(shuō)24C02C始終可讀可寫,且地址碼為1010000X。下面的I2C Debug模塊在仿真中用于驗(yàn)證存儲(chǔ)的信息是否準(zhǔn)確無(wú)誤。
圖3-3 24C02C硬件接線圖
3.3.2 軟件設(shè)計(jì)
首先對(duì)一些需要使用到的位變量進(jìn)行定義,具體的代碼如下。
sbit I2C_SDA=P2^0;
sbit I2C_SCL=P2^1;
24C02C是一種遵循I2C總線協(xié)議的存儲(chǔ)芯片,它的數(shù)據(jù)幀由I2C模塊的函數(shù)拼湊而成。I2C模塊的函數(shù)聲明如表3.1所示。
表3.1 I2C模塊函數(shù)聲明表
| 函數(shù)原型聲明 | 意義 |
| void I2C_Start() | 起始信號(hào) |
| void I2C_Stop() | 終止信號(hào) |
| I2C_SendByte(unsigned char Byte) | 發(fā)生一個(gè)字節(jié) |
| unsigned char I2C_ReceiveByte() | 接收一個(gè)字節(jié) |
| void I2C_SendAck(unsigned char AckBit) | 發(fā)送應(yīng)答信號(hào) |
| unsigned char I2C_ReceiveAck(void) | 接收應(yīng)答信號(hào) |
接下來(lái)正式介紹24C02的發(fā)送和接收數(shù)據(jù)函數(shù)。
(1)發(fā)送數(shù)據(jù)函數(shù)。函數(shù)的第一個(gè)參數(shù)表示的是要發(fā)送的地址,第二個(gè)參數(shù)為待發(fā)送的數(shù)據(jù),ADDRESS表示器件的地址碼,由硬件接線確定,此處為0xA0。具體的代碼如下。
void _24C02_WriteByte(unsigned char WordAddress,Data) {I2C_Start();I2C_SendByte(ADDRESS);//0xA0I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop(); }(2)接收數(shù)據(jù)函數(shù)。參數(shù)為需要接收數(shù)據(jù)的地址,返回值為該地址中的數(shù)據(jù)。在接收數(shù)據(jù)的過(guò)程中要求ADDRESS的末位為1。函數(shù)的具體代碼如下。
unsigned char _24C02_ReadByte(unsigned char WordAddress) {unsigned char Data;I2C_Start();I2C_SendByte(ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(ADDRESS|0x01);I2C_ReceiveAck();Data=I2C_ReceiveByte();I2C_SendAck(1);I2C_Stop();return Data; }3.4 按鍵處理模塊設(shè)計(jì)
按鍵模塊的電路最為簡(jiǎn)單,但他需要實(shí)現(xiàn)的邏輯功能確實(shí)最為復(fù)雜。本模塊需要實(shí)現(xiàn)的功能包括按鍵掃描和按鍵處理。通過(guò)定時(shí)器掃描按鍵的方式對(duì)按下的按鍵進(jìn)行檢測(cè),根據(jù)得到的鍵值調(diào)用不同的方法。
3.4.1 硬件設(shè)計(jì)
按鍵的硬件連接如下圖所示。7個(gè)按鍵一端接單片機(jī)I/O口,另一端接地,當(dāng)有按鍵按下時(shí)對(duì)應(yīng)的I/O口就為低電平。
圖3-4 按鍵接線圖
3.4.2 軟件設(shè)計(jì)
由于按鍵的器件特性,在實(shí)際使用過(guò)程中無(wú)論是在按下按鍵還是松開按鍵的瞬間都會(huì)存在抖動(dòng),我們必須要消抖才能正常使用。按鍵消抖的方式有兩種:硬件消抖和軟件消抖,這里采用的是軟件消抖的方式。抖動(dòng)的時(shí)間一般不會(huì)超過(guò)20ms,我們可以利用單片機(jī)的定時(shí)器中斷函數(shù),每隔20ms對(duì)按鍵進(jìn)行一次掃描,按鍵掃描程序流程圖如下所示。
?
圖3-5 ?按鍵掃描流程圖
按鍵掃描的主要代碼如下。
void key_scan() {static unsigned char oldState,newState;//當(dāng)前的按鍵狀態(tài)和之前的按鍵狀態(tài) oldState=newState;newState=getKeyNum();if(newState==0&&oldState==1) KeyVal=1;if(newState==0&&oldState==2) KeyVal=2;if(newState==0&&oldState==3) KeyVal=3;if(newState==0&&oldState==4) KeyVal=4;if(newState==0&&oldState==5) KeyVal=5;if(newState==0&&oldState==6) KeyVal=6;if(newState==0&&oldState==7) KeyVal=7; }在通過(guò)按鍵掃描程序得到鍵值后,由主程序根據(jù)不同的鍵值調(diào)用不同的功能模塊。例如,按下第一個(gè)鍵(k1=0)進(jìn)入時(shí)間設(shè)置模式、按下第二個(gè)鍵(k2=0)使秒鐘復(fù)位等等。按鍵處理的流程圖如下圖所示。
圖3-6 ?按鍵處理流程圖
按鍵處理的主要代碼如下所示。
if(keyNum==1){if(MODE==0)MODE=1; //選擇設(shè)置時(shí)間或者顯示時(shí)間else if(MODE==1){MODE=0;setTime();} //設(shè)置模式切換至顯示模式后重新設(shè)置時(shí)間}if(keyNum==6){unsigned char i;for(i=0;i<6;i++){_24C02_WriteByte(i,DS1302_Time[i]); //從第0號(hào)地址開始依次寫入時(shí)間數(shù)據(jù)Delay(5);}}if(keyNum==7){unsigned char i;for(i=0;i<6;i++){DS1302_Time[i]=_24C02_ReadByte(i); //依次讀取數(shù)據(jù)到表示時(shí)間的數(shù)組中setTime(); //重新設(shè)置時(shí)間}} switch(MODE){case 0: LCD_ShowTime();break;case 1: LCD_TimeSet();break;}在設(shè)置時(shí)間功能模塊需要對(duì)每一次設(shè)置的時(shí)間的合法性進(jìn)行判斷,判斷的流程圖如下所示。
圖3-7 設(shè)置時(shí)間模塊流程圖
四、程序運(yùn)行結(jié)果測(cè)試與分析
系統(tǒng)的總體原理圖如下所示,接下來(lái)分別對(duì)各個(gè)模塊進(jìn)行測(cè)試。
圖4-1 總體原理圖
4.1 LCD1602功能測(cè)試
(1)顯示字符串。在第一行第一列開始顯示“zhou shuaige”,在第二行第一列開始顯示“yi choubi”。測(cè)試結(jié)果如下所示。
圖4-2 ?LCD1602顯示字符串測(cè)試
(2)顯示數(shù)字。在第一行第一列顯示數(shù)字5,顯示長(zhǎng)度2;在第二行第一列顯示數(shù)字2,顯示長(zhǎng)度3。測(cè)試結(jié)果如下所示。
圖4-3 ?LCD1602顯示數(shù)字測(cè)試
(3)顯示字符。在第一行第二列顯示‘a(chǎn)’,第二行第二列顯示‘b’,測(cè)試結(jié)果如下所示。
圖4-4 ?LCD1602顯示字符測(cè)試
4.2 DS1302功能測(cè)試
(1)設(shè)置時(shí)間。在程序中給DS1302設(shè)置一個(gè)的時(shí)間“20年01月01日00點(diǎn)00時(shí)00分00秒,星期三”,測(cè)試結(jié)果如下。
圖4-5 ?DS1302設(shè)置時(shí)間測(cè)試
(2)讀取時(shí)間。把DS1302中的數(shù)據(jù)讀取出來(lái)顯示在LCD1602上。測(cè)試結(jié)果如下。
圖4-6 ?DS1302讀取時(shí)間測(cè)試
4.3 24C02C功能測(cè)試
(1)寫入數(shù)據(jù)。把時(shí)鐘芯片中目前的時(shí)間寫入24C02C,暫停仿真后打開I2C Debug模塊,測(cè)試結(jié)果如下。
圖4-7 ?24C02C寫入數(shù)據(jù)測(cè)試
說(shuō)明:DS1302的時(shí)間是“20年01月01號(hào)00是01分16秒,星期3”,所有的信息都儲(chǔ)存在24C02C芯片以0號(hào)地址開始的7個(gè)單元中(以十六進(jìn)制存儲(chǔ))。
(2)讀取數(shù)據(jù)。把上一步存儲(chǔ)的信息讀出來(lái)顯示在LCD1602上,測(cè)試結(jié)果如下。
圖4-8 ?24C02C讀取數(shù)據(jù)測(cè)試
4.4 調(diào)整時(shí)間功能測(cè)試
通過(guò)按鍵把時(shí)間設(shè)置成08:08:08,測(cè)試結(jié)果如下。
圖4-9 ?按鍵調(diào)整時(shí)間測(cè)試
總結(jié)
以上是生活随笔為你收集整理的基于51单片机的电子时钟的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安全bios手册(5)
- 下一篇: matlab help函数用法,MATL