![51基于單片機的電子時鐘設(shè)計課程設(shè)計完整_第1頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/29/86e821b3-4cf6-4e55-bd37-dcb861774caf/86e821b3-4cf6-4e55-bd37-dcb861774caf1.gif)
![51基于單片機的電子時鐘設(shè)計課程設(shè)計完整_第2頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/29/86e821b3-4cf6-4e55-bd37-dcb861774caf/86e821b3-4cf6-4e55-bd37-dcb861774caf2.gif)
![51基于單片機的電子時鐘設(shè)計課程設(shè)計完整_第3頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/29/86e821b3-4cf6-4e55-bd37-dcb861774caf/86e821b3-4cf6-4e55-bd37-dcb861774caf3.gif)
![51基于單片機的電子時鐘設(shè)計課程設(shè)計完整_第4頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/29/86e821b3-4cf6-4e55-bd37-dcb861774caf/86e821b3-4cf6-4e55-bd37-dcb861774caf4.gif)
![51基于單片機的電子時鐘設(shè)計課程設(shè)計完整_第5頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/29/86e821b3-4cf6-4e55-bd37-dcb861774caf/86e821b3-4cf6-4e55-bd37-dcb861774caf5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、 課程設(shè)計報告課程設(shè)計報告 題題 目目 基于單片機的電子時鐘設(shè)計 課課 程程 名名 稱稱 單片機原理及應(yīng)用 院院 部部 名名 稱稱 機電工程學(xué)院 專專 業(yè)業(yè) 電氣工程及其自動化 班班 級級 12 電氣工程及其自動化(單) 學(xué)學(xué) 生生 姓姓 名名 錢 凱 學(xué)學(xué) 號號 1205202032 課程設(shè)計地點課程設(shè)計地點 工科樓 c304 課程設(shè)計學(xué)時課程設(shè)計學(xué)時 20 指指 導(dǎo)導(dǎo) 教教 師師 李國利 金陵科技學(xué)院教務(wù)處制成績目錄目錄一、概述.41.1 設(shè)計任務(wù)與要求:.41.2 設(shè)計目的:.4二、總體設(shè)計方案及說明.4三、系統(tǒng)硬件電路設(shè)計.53.1 at89c51 單片機最小系統(tǒng).53.2ds1302
2、 實時時鐘芯片模塊.63.3 ds18b20 溫度傳感器模塊.73.4 lcd1602 液晶顯示模塊 .83.5 4*4 矩陣按鍵 .9四、系統(tǒng)軟件部分設(shè)計.104.1 軟件流程圖.104.2 系統(tǒng)源程序.13五、系統(tǒng)仿真過程與結(jié)果.295.1 proteus仿真軟件簡介.295.2 keil軟件簡介.295.3 結(jié)合proteus仿真軟件與 keil軟件編譯過程.29六、制作過程與功能實現(xiàn).336.1 實物制.336.2 功能實現(xiàn).34七、總結(jié).35八、參考文獻.36附錄一:.36附錄二:.38摘摘 要要基于at89c51單片機設(shè)計了電子,系統(tǒng)主要包括單片機最小系統(tǒng)、溫度采集電路、顯示電路、
3、時鐘電路等等。系統(tǒng)采用ds18b20溫度傳感器對室內(nèi)進行溫度測量,加上ds1302實時時鐘芯片內(nèi)置時間,同時將當(dāng)前溫度信息和時間發(fā)送到lcd進行顯示。畫出了系統(tǒng)原理圖,進行了軟件設(shè)計,給出了系統(tǒng)流程圖,并編寫了系統(tǒng)程序。最后進行了系統(tǒng)仿真,仿真結(jié)果表明,所設(shè)計的系統(tǒng)能夠滿足要求。本系統(tǒng)具有成本低,可靠性高和安全實用等特點,廣泛應(yīng)用于社會生活的各個領(lǐng)域。 關(guān)鍵詞:關(guān)鍵詞:at89c51 單片機;ds18b20;ds1302 手動時間調(diào)整; 一、概述一、概述1.1 設(shè)計任務(wù)與要求:設(shè)計任務(wù)與要求:設(shè)計一個基于單片機并采用 lcd 顯示的日歷電子鐘,要求:1)系統(tǒng)功能:可進行秒分時、天月年計時、溫度
4、;可進行手動時間調(diào)整。2)給出系統(tǒng)設(shè)計方案,畫出硬件連線圖,并說明工作原理;3)畫出程序框圖并編寫程序。1.2 設(shè)計目的:設(shè)計目的:通過本課程設(shè)計,使學(xué)生掌握控制系統(tǒng)設(shè)計的一般步驟,掌握系統(tǒng)總體控制方案的設(shè)計方法。使學(xué)生進一步掌握微型計算機應(yīng)用系統(tǒng)的硬、軟件開發(fā)方法,輸入/輸出(i/o)接口技術(shù),應(yīng)用程序設(shè)計技術(shù),并能結(jié)合專業(yè)設(shè)計簡單實用的單片機應(yīng)用系統(tǒng)。針對課堂重點講授內(nèi)容使學(xué)生加深對單片機硬件原理的理解及提高 c51 語言程序設(shè)計的能力,為以后的畢業(yè)設(shè)計搭建了單片機系統(tǒng)應(yīng)用平臺,提高學(xué)生的開發(fā)創(chuàng)新能力。二、總體設(shè)計方案及說明二、總體設(shè)計方案及說明本方案以at89c51 單片機為控制核心,由
5、 ds18b20 溫度傳感器模塊,ds1302實時時鐘芯片模塊,lcd1602 液晶顯示模塊, 4*4 矩陣按鍵以及上拉電阻和下拉電阻構(gòu)成。通過 lcd1602 液晶顯示模塊顯示時間及溫度,通過按鍵可以設(shè)置年月日、分時秒。本設(shè)計采用 5v 電源,程序主要是通過單片機下載的軟件來完成。stc89c52rc單片機ds18b20溫度模塊ds1302s時鐘模塊4*4按鍵模塊lcd1602顯示模塊圖 2-1 系統(tǒng)框圖三、系統(tǒng)硬件電路設(shè)計三、系統(tǒng)硬件電路設(shè)計3.13.1 at89c51at89c51 單片機最小系統(tǒng)單片機最小系統(tǒng)(1)時鐘電路單片機工作時,從取指令到譯碼再進行微操作,必須在時鐘信號控制下才
6、能有序地進行,時鐘電路就是為單片機工作提供基本時鐘的。單片機的時鐘信號通常有兩種產(chǎn)生方式:內(nèi)部時鐘方式和外部時鐘方式。內(nèi)部時鐘方式的原理電路如圖所示。在單片機xtal1 和 xtal2 引腳上跨接上一個晶振和兩個穩(wěn)頻電容,可以與單片機片內(nèi)的電路構(gòu)成一個穩(wěn)定的自激振蕩器。晶振的取值范圍一般為 024mhz,常用的晶振頻率有6mhz、12 mhz、11.0592 mhz、24 mhz 等。本次設(shè)計采用 11.0592mhz。一些新型的單片機還可以選擇更高的頻率。外接電容的作用是對振蕩器進行頻率微調(diào),使振蕩信號頻率與晶振頻率一致,同時起到穩(wěn)定頻率的作用,一般選用 2030pf 的瓷片電容。外部時鐘方
7、式則是在單片機 xtal1 引腳上外接一個穩(wěn)定的時鐘信號源,它一般適用于多片單片機同時工作的情況,使用同一時鐘信號可以保證單片機的工作同步。時序是單片機在執(zhí)行指令時 cpu 發(fā)出的控制信號在時間上的先后順序。at89c51 單片機的時序概念有 4 個,可用定時單位來說明,包括振蕩周期、時鐘周期、機器周期和指令周期。振蕩周期:是片內(nèi)振蕩電路或片外為單片機提供的脈沖信號的周期。時序中 1 個振蕩周期定義為 1 個節(jié)拍,用 p 表示。時鐘周期:振蕩脈沖送入內(nèi)部時鐘電路,由時鐘電路對其二分頻后輸出的時鐘脈沖周期稱為時鐘周期。時鐘周期為振蕩周期的2 倍。時序中 1 個時鐘周期定義為 1 個狀態(tài),用 s
8、表示。每個狀態(tài)包括 2 個節(jié)拍,用 p1、p2表示。機器周期:機器周期是單片機完成一個基本操作所需要的時間。一條指令的執(zhí)行需要一個或幾個機器周期。一個機器周期固定的由6 個狀態(tài)s1s6 組成。指令周期:執(zhí)行一條指令所需要的時間稱為指令周期。一般用指令執(zhí)行所需機器周期數(shù)表示。 at89c51 單片機多數(shù)指令的執(zhí)行需要 1 個或 2 個機器周期,只有乘除兩條指令的執(zhí)行需要 4 個機器周期。(2)復(fù)位電路無論是在單片機剛開始接上電源時,還是運行過程中發(fā)生故障都需要復(fù)位。復(fù)位電路用于將單片機內(nèi)部各電路的狀態(tài)恢復(fù)到一個確定的初始值,并從這個狀態(tài)開始工作。單片機的復(fù)位條件:必須使其 rst 引腳上持續(xù)出現(xiàn)
9、兩個(或以上)機器周期的高電平。單片機的復(fù)位形式:上電復(fù)位、按鍵復(fù)位。上電復(fù)位電路中,利用電容充電來實現(xiàn)復(fù)位。在電源接通瞬間,rst 引腳上的電位是高電平( vcc) ,電源接通后對電容進行快速充電,隨著充電的進行,rst 引腳上的電位也會逐漸下降為低電平。只要保證rst 引腳上高電平出現(xiàn)的時間大于兩個機器周期,便可以實現(xiàn)正常復(fù)位。按鍵復(fù)位電路中,當(dāng)按鍵沒有按下時,電路同上電復(fù)位電路。如在單片機運行過程中,按下 reset 鍵,已經(jīng)充好電的電容會快速通過 4.7k 電阻的回路放電,從而使得 rst 引腳上的電位快速變?yōu)楦唠娖?,此高電平會維持到按鍵釋放,從而滿足單片機復(fù)位的條件實現(xiàn)按鍵復(fù)位。圖
10、3-1 單片機復(fù)位電路3.2 ds1302 實時時鐘芯片模塊實時時鐘芯片模塊ds1302 是美國 dallas 公司推出的一種高性能、低功耗的實時時鐘芯片,附加 31 字節(jié)靜態(tài) ram,采用 spi 三線接口與 cpu 進行同步通信,并可采用突發(fā)方式一次傳送多個字節(jié)的時鐘信號和 ram 數(shù)據(jù)。實時時鐘可提供秒、分、時、日、星期、月和年,一個月小與 31 天時可以自動調(diào)整,且具有閏年補償功能。工作電壓寬達 2.55.5v。采用雙電源供電(主電源和備用電源) ,可設(shè)置備用電源充電方式,提供了對后背電源進行涓細電流充電的能力。ds1302 的外部引腳分配如圖,ds1302 用于數(shù)據(jù)記錄,特別是對某些
11、具有特殊意義的數(shù)據(jù)點的記錄上,能實現(xiàn)數(shù)據(jù)與出現(xiàn)該數(shù)據(jù)的時間同時記錄,因此廣泛應(yīng)用于測量系統(tǒng)中。 1.各引腳的功能為: 圖 3-4 時鐘芯片外部引腳vcc1:主電源;vcc2:備份電源。當(dāng) vcc2vcc1+0.2v 時,由 vcc2 向ds1302 供電,當(dāng) vcc2 vcc1 時,由 vcc1 向 ds1302 供電。 sclk:串行時鐘,輸入,控制數(shù)據(jù)的輸入與輸出; i/o:三線接口時的雙向數(shù)據(jù)線; ce:輸入信號,在讀、寫數(shù)據(jù)期間,必須為高。該引腳有兩個功能:第一,ce開始控制字訪問移位寄存器的控制邏輯;其次,ce 提供結(jié)束單字節(jié)或多字節(jié)數(shù)據(jù)傳輸?shù)姆椒āD 3-5 時鐘芯片3.3 ds1
12、8b20 溫度傳感器模塊溫度傳感器模塊ds18b20 工作原理:ds18b20 的溫度檢測與數(shù)字?jǐn)?shù)據(jù)輸出全集成于一個芯片之上,從而抗干擾力更強。其一個工作周期可分為兩個部分,即溫度檢測和數(shù)據(jù)處理。在講解其工作流程之前我們有必要了解 18b20 的內(nèi)部存儲器資源。18b20 共有三種形態(tài)的存儲器資源,它們分別是: rom 只讀存儲器,用于存放 ds18b20id 編碼,其前 8 位是單線系列編碼(ds18b20 的編碼是 19h) ,后面 48 位是芯片唯一的序列號,最后 8 位是以上56 的位的 crc 碼(冗余校驗) 。數(shù)據(jù)在出產(chǎn)時設(shè)置不由用戶更改。ds18b20 共64 位 rom。ram
13、 數(shù)據(jù)暫存器,用于內(nèi)部計算和數(shù)據(jù)存取,數(shù)據(jù)在掉電后丟失,ds18b20共 9 個字節(jié) ram,每個字節(jié)為 8 位。第 1、2 個字節(jié)是溫度轉(zhuǎn)換后的數(shù)據(jù)值信息,第 3、4 個字節(jié)是用戶 eeprom(常用于溫度報警值儲存)的鏡像。在上電復(fù)位時其值將被刷新。第 5 個字節(jié)則是用戶第 3 個 eeprom 的鏡像。第 6、7、8 個字節(jié)為計數(shù)寄存器,是為了讓用戶得到更高的溫度分辨率而設(shè)計的,同樣也是內(nèi)部溫度轉(zhuǎn)換、計算的暫存單元。第 9 個字節(jié)為前 8 個字節(jié)的 crc 碼。eeprom 非易失性記憶體,用于存放長期需要保存的數(shù)據(jù),上下限溫度報警值和校驗數(shù)據(jù),ds18b20 共 3 位 eeprom,
14、并在 ram 都存在鏡像,以方便用戶操作。圖 3-3 溫度傳感器模塊3.4 lcd1602 液晶顯示模塊液晶顯示模塊lcd1602 可以顯示 16*2=32 個字符,也可以用來顯示一些漢字圖片(利用取模軟件提?。?,原理圖中的可調(diào)電阻是用來調(diào)節(jié)字符顯示的亮度的,調(diào)節(jié)是要有耐心,應(yīng)為用到的是精密可調(diào)電阻,這個需要轉(zhuǎn)很多圈,不容易顯示出來,注意不能跳到太亮,要不很容易燒掉液晶,下面為接口說明,一般不顯示很可能是程序的問題和可調(diào)電阻沒有調(diào)節(jié)好。 圖 3-6 lcd1602 液晶的原理圖3.5 4*4 矩陣按鍵矩陣按鍵矩陣鍵盤又稱為行列式鍵盤,它是用 4 條 i/o 線作為行線,4 條 i/o 線作為
15、列線組成的鍵盤。在行線和列線的每一個交叉點上,設(shè)置一個按鍵。這樣鍵盤中按鍵的個數(shù)是 4*4 個。這種行列式鍵盤結(jié)構(gòu)能夠有效地提高單片機系統(tǒng)中i/o 的利用率。圖 3-7 矩陣按鍵電路四、系統(tǒng)軟件部分設(shè)計四、系統(tǒng)軟件部分設(shè)計4.1 軟件流程圖軟件流程圖系統(tǒng)初始化采集溫度采集時間lcd顯示開始圖 4-1 主函數(shù)系統(tǒng)流程圖程序開始,首先先進行系統(tǒng)初始化。然后先進行溫度的采集,時間的采集,最后將溫度和時間送至 lcd 顯示數(shù)據(jù)。開始復(fù)位跳過序列號識別跳過序列號識別啟動溫度轉(zhuǎn)換讀取溫度值結(jié)束復(fù)位圖 4-2 ds18b20 溫度傳感器的讀取流程圖單片機向 ds18b20 溫度傳感器發(fā)送數(shù)據(jù)采集溫度,溫度傳
16、感器首先進行系統(tǒng)的初始化 ds18b20 溫度傳感器每 1 秒鐘進行一次溫度采集,如果溫度有變化則讀取溫度,若溫度沒有變化將繼續(xù)返回上一步循環(huán)。開始ds1302初始化讀取時間是否=200ms時間是否變化返回yesyesnono圖 4-3 ds1302 讀取系統(tǒng)流程圖單片機向 ds1302 時鐘芯片發(fā)送數(shù)據(jù)采集時間,ds1302 時鐘芯片首先進行系統(tǒng)初始化。ds1302 時鐘芯片是 200ms 進行一次時間的數(shù)據(jù)采集。如果時間變化,則讀取時間,如果沒有變化,則返回上一步繼續(xù)循環(huán)。 開始lcd1602初始化讀取溫度和時間是否有按鍵按下lcd顯示返回按鍵設(shè)置時間是否結(jié)束yesyesnono圖 4-4
17、 lcd 顯示器系統(tǒng)流程圖單片機向 lcd 顯示器發(fā)送數(shù)據(jù)要求顯示溫度和時間,lcd 顯示器首先進行初始化。然后讀取溫度和時間。下一步判斷按鍵是否按下,如果按下就將設(shè)置時間送至 lcd 顯示器進行顯示。如果沒有設(shè)置則返回上一步,然后送至 lcd 顯示器進行顯示。4.2 系統(tǒng)源程序系統(tǒng)源程序#include struct stime /日期時間結(jié)構(gòu)體定義日期時間結(jié)構(gòu)體定義 unsigned int year; unsigned char mon; unsigned char day; unsigned char hour; unsigned char min; unsigned char sec
18、; unsigned char week;bit flag1s = 0; /1s 定時標(biāo)志定時標(biāo)志bit flag200ms = 1; /200ms 定時標(biāo)志定時標(biāo)志struct stime buftime; /日期時間緩沖區(qū)日期時間緩沖區(qū)unsigned char setindex = 0; /時間設(shè)置索引時間設(shè)置索引unsigned char t0rh = 0; /t0 重載值的高字節(jié)重載值的高字節(jié)unsigned char t0rl = 0; /t0 重載值的低字節(jié)重載值的低字節(jié)void configtimer0(unsigned int ms);void refreshtimeshow
19、();void getshowtemp();extern void initds1302();extern void getrealtime(struct stime *time);extern void setrealtime(struct stime *time);extern void keyscan();extern void keydriver();extern void initlcd1602();extern void lcdshowstr(unsigned char x, unsigned char y, unsigned char *str);extern void lcds
20、etcursor(unsigned char x, unsigned char y);extern void lcdopencursor();extern void lcdclosecursor();extern bit start18b20();extern bit get18b20temp(int *temp);void main() unsigned char psec=0 xaa; /秒備份,初值秒備份,初值 aa 確保首次讀取時間后會刷新確保首次讀取時間后會刷新顯示顯示 ea = 1; /開總中斷開總中斷 configtimer0(1); /t0 定時定時 1ms start18b2
21、0(); /啟動啟動 ds18b20 initds1302(); /初始化實時時鐘初始化實時時鐘 initlcd1602(); /初始化液晶初始化液晶 /初始化屏幕上固定不變的內(nèi)容初始化屏幕上固定不變的內(nèi)容 lcdshowstr(3, 0, 20 - -); lcdshowstr(1, 1, : : -c); while (1) keydriver(); /調(diào)用按鍵驅(qū)動調(diào)用按鍵驅(qū)動 if (flag200ms & (setindex = 0) /每隔每隔 200ms 且未處于設(shè)置狀態(tài)時,且未處于設(shè)置狀態(tài)時, flag200ms = 0; getrealtime(&buftime
22、); /獲取當(dāng)前時間獲取當(dāng)前時間 if (psec != buftime.sec) /檢測到時間有變化時刷新顯示檢測到時間有變化時刷新顯示 refreshtimeshow(); psec = buftime.sec; /用當(dāng)前值更新上次秒數(shù)用當(dāng)前值更新上次秒數(shù) if (flag1s & (setindex = 0) /每隔每隔 1s 讀取并顯示溫度讀取并顯示溫度 flag1s = 0; getshowtemp(); /* 將一個將一個 bcd 碼字節(jié)顯示到屏幕上,碼字節(jié)顯示到屏幕上,(x,y)-屏幕起始坐標(biāo),屏幕起始坐標(biāo),bcd-待顯示待顯示 bcd 碼碼 */void showbcd
23、byte(unsigned char x, unsigned char y, unsigned char bcd) unsigned char str4; str0 = (bcd 4) + 0; str1 = (bcd&0 x0f) + 0; str2 = 0; lcdshowstr(x, y, str);/* 獲取并顯示溫度獲取并顯示溫度 */void getshowtemp() int temp; unsigned char str4; if (get18b20temp(&temp) /讀取當(dāng)前溫度并判斷是否成功讀取當(dāng)前溫度并判斷是否成功 /讀取成功時,刷新當(dāng)前溫度顯示讀取
24、成功時,刷新當(dāng)前溫度顯示 temp = 4; /右移右移 4 位以舍棄小數(shù)位位以舍棄小數(shù)位 str0 = temp/10 + 0; /顯示為兩位十進制數(shù)字顯示為兩位十進制數(shù)字 str1 = temp%10 + 0; str2 = 0; lcdshowstr(11, 1, str); else /讀取失敗時,提示錯誤信息讀取失敗時,提示錯誤信息 lcdshowstr(11, 1, -); start18b20(); /重新啟動下一次轉(zhuǎn)換重新啟動下一次轉(zhuǎn)換/* 刷新日期時間的顯示刷新日期時間的顯示 */void refreshtimeshow() showbcdbyte(5, 0, buftime
25、.year); showbcdbyte(8, 0, buftime.mon); showbcdbyte(11, 0, buftime.day); showbcdbyte(1, 1, buftime.hour); showbcdbyte(4, 1, buftime.min); showbcdbyte(7, 1, buftime.sec);/* 刷新當(dāng)前設(shè)置位的光標(biāo)指示刷新當(dāng)前設(shè)置位的光標(biāo)指示 */void refreshsetshow() switch (setindex) case 1: lcdsetcursor(5, 0); break; case 2: lcdsetcursor(6, 0)
26、; break; case 3: lcdsetcursor(8, 0); break; case 4: lcdsetcursor(9, 0); break; case 5: lcdsetcursor(11, 0); break; case 6: lcdsetcursor(12, 0); break; case 7: lcdsetcursor(1, 1); break; case 8: lcdsetcursor(2, 1); break; case 9: lcdsetcursor(4, 1); break; case 10: lcdsetcursor(5, 1); break; case 11:
27、 lcdsetcursor(7, 1); break; case 12: lcdsetcursor(8, 1); break; default: break; /* 遞增一個遞增一個 bcd 碼的高位碼的高位 */unsigned char incbcdhigh(unsigned char bcd) if (bcd&0 xf0) 0 x90) bcd += 0 x10; else bcd &= 0 x0f; return bcd;/* 遞增一個遞增一個 bcd 碼的低位碼的低位 */unsigned char incbcdlow(unsigned char bcd) if (b
28、cd&0 x0f) 0 x00) bcd -= 0 x10; else bcd |= 0 x90; return bcd;/* 遞減一個遞減一個 bcd 碼的低位碼的低位 */unsigned char decbcdlow(unsigned char bcd) if (bcd&0 x0f) 0 x00) bcd -= 0 x01; else bcd |= 0 x09; return bcd;/* 遞增時間當(dāng)前設(shè)置位的值遞增時間當(dāng)前設(shè)置位的值 */void incsettime() switch (setindex) case 1: buftime.year = incbcdhi
29、gh(buftime.year); break; case 2: buftime.year = incbcdlow(buftime.year); break; case 3: buftime.mon = incbcdhigh(buftime.mon); break; case 4: buftime.mon = incbcdlow(buftime.mon); break; case 5: buftime.day = incbcdhigh(buftime.day); break; case 6: buftime.day = incbcdlow(buftime.day); break; case 7
30、: buftime.hour = incbcdhigh(buftime.hour); break; case 8: buftime.hour = incbcdlow(buftime.hour); break; case 9: buftime.min = incbcdhigh(buftime.min); break; case 10: buftime.min = incbcdlow(buftime.min); break; case 11: buftime.sec = incbcdhigh(buftime.sec); break; case 12: buftime.sec = incbcdlow
31、(buftime.sec); break; default: break; refreshtimeshow(); refreshsetshow();/* 遞減時間當(dāng)前設(shè)置位的值遞減時間當(dāng)前設(shè)置位的值 */void decsettime() switch (setindex) case 1: buftime.year = decbcdhigh(buftime.year); break; case 2: buftime.year = decbcdlow(buftime.year); break; case 3: buftime.mon = decbcdhigh(buftime.mon); brea
32、k; case 4: buftime.mon = decbcdlow(buftime.mon); break; case 5: buftime.day = decbcdhigh(buftime.day); break; case 6: buftime.day = decbcdlow(buftime.day); break; case 7: buftime.hour = decbcdhigh(buftime.hour); break; case 8: buftime.hour = decbcdlow(buftime.hour); break; case 9: buftime.min = decb
33、cdhigh(buftime.min); break; case 10: buftime.min = decbcdlow(buftime.min); break; case 11: buftime.sec = decbcdhigh(buftime.sec); break; case 12: buftime.sec = decbcdlow(buftime.sec); break; default: break; refreshtimeshow(); refreshsetshow();/* 右移時間設(shè)置位右移時間設(shè)置位 */void rightshifttimeset() if (setindex
34、 != 0) if (setindex 1) setindex-; else setindex = 12; refreshsetshow(); /* 進入時間設(shè)置狀態(tài)進入時間設(shè)置狀態(tài) */void entertimeset() setindex = 2; /把設(shè)置索引設(shè)置為把設(shè)置索引設(shè)置為 2,即可進入設(shè)置狀態(tài),即可進入設(shè)置狀態(tài) leftshifttimeset(); /再利用現(xiàn)成的左移操作移到位置再利用現(xiàn)成的左移操作移到位置 1 并完成顯示刷新并完成顯示刷新 lcdopencursor(); /打開光標(biāo)閃爍效果打開光標(biāo)閃爍效果/* 退出時間設(shè)置狀態(tài),退出時間設(shè)置狀態(tài),save-是否保存當(dāng)前設(shè)
35、置的時間值是否保存當(dāng)前設(shè)置的時間值 */void exittimeset(bit save) setindex = 0; /把設(shè)置索引設(shè)置為把設(shè)置索引設(shè)置為 0,即可退出設(shè)置狀態(tài),即可退出設(shè)置狀態(tài) if (save) /需保存時即把當(dāng)前設(shè)置時間寫入需保存時即把當(dāng)前設(shè)置時間寫入 ds1302 setrealtime(&buftime); lcdclosecursor(); /關(guān)閉光標(biāo)顯示關(guān)閉光標(biāo)顯示/* 按鍵動作函數(shù),根據(jù)鍵碼執(zhí)行相應(yīng)的操作,按鍵動作函數(shù),根據(jù)鍵碼執(zhí)行相應(yīng)的操作,keycode-按鍵鍵碼按鍵鍵碼 */void keyaction(unsigned char keycode
36、) if (keycode=0) & (keycode8); /定時器重載值拆分為高低字節(jié)定時器重載值拆分為高低字節(jié) t0rl = (unsigned char)tmp; tmod &= 0 xf0; /清零清零 t0 的控制位的控制位 tmod |= 0 x01; /配置配置 t0 為模式為模式 1 th0 = t0rh; /加載加載 t0 重載值重載值 tl0 = t0rl; et0 = 1; /使能使能 t0 中斷中斷 tr0 = 1; /啟動啟動 t0/* t0 中斷服務(wù)函數(shù),執(zhí)行按鍵掃描和中斷服務(wù)函數(shù),執(zhí)行按鍵掃描和 200ms 定時定時 */void interru
37、pttimer0() interrupt 1 static unsigned char tmr200ms = 0; static unsigned int tmr1000ms = 0; th0 = t0rh; /重新加載重載值重新加載重載值 tl0 = t0rl; keyscan(); /按鍵掃描按鍵掃描 tmr200ms+; if (tmr200ms = 200) /定時定時 200ms tmr200ms = 0; flag200ms = 1; tmr1000ms+; if (tmr1000ms = 1000) /定時定時 1000ms tmr1000ms = 0; flag1s = 1;
38、/* 文件名:文件名:lcd1602.c* 描描 述:述:1602 字符液晶驅(qū)動模塊字符液晶驅(qū)動模塊* 版本號:版本號:v1.0.0* 備備 注:注:*/#include #define lcd1602_db p0sbit lcd1602_rs = p10;sbit lcd1602_rw = p11;sbit lcd1602_e = p15;/* 等待液晶準(zhǔn)備好等待液晶準(zhǔn)備好 */void lcdwaitready() unsigned char sta; lcd1602_db = 0 xff; lcd1602_rs = 0; lcd1602_rw = 1; do lcd1602_e = 1;
39、 sta = lcd1602_db; /讀取狀態(tài)字讀取狀態(tài)字 lcd1602_e = 0; while (sta & 0 x80); /bit7 等于等于 1 表示液晶正忙,重復(fù)檢測直到其等于表示液晶正忙,重復(fù)檢測直到其等于 0 為為止止/* 向向 lcd1602 液晶寫入一字節(jié)命令,液晶寫入一字節(jié)命令,cmd-待寫入命令值待寫入命令值 */void lcdwritecmd(unsigned char cmd) lcdwaitready(); lcd1602_rs = 0; lcd1602_rw = 0; lcd1602_db = cmd; lcd1602_e = 1; lcd1602
40、_e = 0;/* 向向 lcd1602 液晶寫入一字節(jié)數(shù)據(jù),液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值待寫入數(shù)據(jù)值 */void lcdwritedat(unsigned char dat) lcdwaitready(); lcd1602_rs = 1; lcd1602_rw = 0; lcd1602_db = dat; lcd1602_e = 1; lcd1602_e = 0;/* 設(shè)置顯示設(shè)置顯示 ram 起始地址,亦即光標(biāo)位置,起始地址,亦即光標(biāo)位置,(x,y)-對應(yīng)屏幕上的字符坐標(biāo)對應(yīng)屏幕上的字符坐標(biāo) */void lcdsetcursor(unsigned char x, unsig
41、ned char y) unsigned char addr; if (y = 0) /由輸入的屏幕坐標(biāo)計算顯示由輸入的屏幕坐標(biāo)計算顯示 ram 的地址的地址 addr = 0 x00 + x; /第一行字符地址從第一行字符地址從 0 x00 起始起始 else addr = 0 x40 + x; /第二行字符地址從第二行字符地址從 0 x40 起始起始 lcdwritecmd(addr | 0 x80); /設(shè)置設(shè)置 ram 地址地址/* 在液晶上顯示字符串,在液晶上顯示字符串,(x,y)-對應(yīng)屏幕上的起始坐標(biāo),對應(yīng)屏幕上的起始坐標(biāo),str-字符串指針字符串指針 */void lcdshow
42、str(unsigned char x, unsigned char y, unsigned char *str) lcdsetcursor(x, y); /設(shè)置起始地址設(shè)置起始地址 while (*str != 0) /連續(xù)寫入字符串?dāng)?shù)據(jù),直到檢測到結(jié)束符連續(xù)寫入字符串?dāng)?shù)據(jù),直到檢測到結(jié)束符 lcdwritedat(*str+); /* 打開光標(biāo)的閃爍效果打開光標(biāo)的閃爍效果 */void lcdopencursor()lcdwritecmd(0 x0f);/* 關(guān)閉光標(biāo)顯示關(guān)閉光標(biāo)顯示 */void lcdclosecursor()lcdwritecmd(0 x0c);/* 初始化初始化 1
43、602 液晶液晶 */void initlcd1602() lcdwritecmd(0 x38); /16*2 顯示,顯示,5*7 點陣,點陣,8 位數(shù)據(jù)接口位數(shù)據(jù)接口 lcdwritecmd(0 x0c); /顯示器開,光標(biāo)關(guān)閉顯示器開,光標(biāo)關(guān)閉 lcdwritecmd(0 x06); /文字不動,地址自動文字不動,地址自動+1 lcdwritecmd(0 x01); /清屏清屏/* 文件名:文件名:keyboard.c* 描描 述:述:4*4 矩陣按鍵驅(qū)動模塊矩陣按鍵驅(qū)動模塊* 版本號:版本號:v1.0.0* 備備 注:注:*/#include sbit key_in_1 = p24;sb
44、it key_in_2 = p25;sbit key_in_3 = p26;sbit key_in_4 = p27;sbit key_out_1 = p23;sbit key_out_2 = p22;sbit key_out_3 = p21;sbit key_out_4 = p20;unsigned char code keycodemap44 = /矩陣按鍵編號到標(biāo)準(zhǔn)鍵盤鍵碼的映射矩陣按鍵編號到標(biāo)準(zhǔn)鍵盤鍵碼的映射表表 1, 2, 3, 0 x26 , /數(shù)字鍵數(shù)字鍵 1、數(shù)字鍵、數(shù)字鍵 2、數(shù)字鍵、數(shù)字鍵 3、向上鍵、向上鍵 4, 5, 6, 0 x25 , /數(shù)字鍵數(shù)字鍵 4、數(shù)字鍵、數(shù)字
45、鍵 5、數(shù)字鍵、數(shù)字鍵 6、向左鍵、向左鍵 7, 8, 9, 0 x28 , /數(shù)字鍵數(shù)字鍵 7、數(shù)字鍵、數(shù)字鍵 8、數(shù)字鍵、數(shù)字鍵 9、向下鍵、向下鍵 0, 0 x1b, 0 x0d, 0 x27 /數(shù)字鍵數(shù)字鍵 0、esc 鍵、鍵、 回車鍵、回車鍵、 向右鍵向右鍵;unsigned char pdata keysta44 = /全部矩陣按鍵的當(dāng)前狀態(tài)全部矩陣按鍵的當(dāng)前狀態(tài) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1;extern void keyaction(unsigned char keycode);/* 按鍵驅(qū)動函數(shù),檢測按鍵動作,調(diào)
46、度相應(yīng)動作函數(shù),需在主循環(huán)中調(diào)用按鍵驅(qū)動函數(shù),檢測按鍵動作,調(diào)度相應(yīng)動作函數(shù),需在主循環(huán)中調(diào)用 */void keydriver() unsigned char i, j; static unsigned char pdata backup44 = /按鍵值備份,保存前一次的值按鍵值備份,保存前一次的值 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; for (i=0; i4; i+) /循環(huán)檢測循環(huán)檢測 4*4 的矩陣按鍵的矩陣按鍵 for (j=0; j4; j+) if (backupij != keystaij) /檢測按鍵動作檢測按鍵
47、動作 if (backupij != 0) /按鍵按下時執(zhí)行動作按鍵按下時執(zhí)行動作 keyaction(keycodemapij); /調(diào)用按鍵動作函數(shù)調(diào)用按鍵動作函數(shù) backupij = keystaij; /刷新前一次的備份值刷新前一次的備份值 /* 按鍵掃描函數(shù),需在定時中斷中調(diào)用,推薦調(diào)用間隔按鍵掃描函數(shù),需在定時中斷中調(diào)用,推薦調(diào)用間隔 1ms */void keyscan() unsigned char i; static unsigned char keyout = 0; /矩陣按鍵掃描輸出索引矩陣按鍵掃描輸出索引 static unsigned char keybuf44 =
48、 /矩陣按鍵掃描緩沖區(qū)矩陣按鍵掃描緩沖區(qū) 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff ; /將一行的將一行的 4 個按鍵值移入緩沖區(qū)個按鍵值移入緩沖區(qū) keybufkeyout0 = (keybufkeyout0 1) | key_in_1; keybufkeyout1 = (keybufkeyout1 1) | key_in_2; keybufkeyout2 = (keybufkeyout2 1) | key_in_
49、3; keybufkeyout3 = (keybufkeyout3 1) | key_in_4; /消抖后更新按鍵狀態(tài)消抖后更新按鍵狀態(tài) for (i=0; i4; i+) /每行每行 4 個按鍵,所以循環(huán)個按鍵,所以循環(huán) 4 次次 if (keybufkeyouti & 0 x0f) = 0 x00) /連續(xù)連續(xù) 4 次掃描值為次掃描值為 0,即,即 4*4ms 內(nèi)都是按下狀態(tài)時,可認(rèn)為按內(nèi)都是按下狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的按下鍵已穩(wěn)定的按下 keystakeyouti = 0; else if (keybufkeyouti & 0 x0f) = 0 x0f) /連續(xù)連續(xù) 4
50、 次掃描值為次掃描值為 1,即,即 4*4ms 內(nèi)都是彈起狀態(tài)時,可認(rèn)為按內(nèi)都是彈起狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的彈起鍵已穩(wěn)定的彈起 keystakeyouti = 1; /執(zhí)行下一次的掃描輸出執(zhí)行下一次的掃描輸出 keyout+; /輸出索引遞增輸出索引遞增 keyout &= 0 x03; /索引值加到索引值加到 4 即歸零即歸零 switch (keyout) /根據(jù)索引,釋放當(dāng)前輸出引腳,拉低下次的輸出引腳根據(jù)索引,釋放當(dāng)前輸出引腳,拉低下次的輸出引腳 case 0: key_out_4 = 1; key_out_1 = 0; break; case 1: key_out_1 =
51、1; key_out_2 = 0; break; case 2: key_out_2 = 1; key_out_3 = 0; break; case 3: key_out_3 = 1; key_out_4 = 0; break; default: break; /* 文件名:文件名:ds1302.c* 描描 述:實時時鐘芯片述:實時時鐘芯片 ds1302 驅(qū)動模塊驅(qū)動模塊* 版本號:版本號:v1.0.0* 備備 注:注:*/#include sbit ds1302_ce = p17;sbit ds1302_ck = p35;sbit ds1302_io = p34;struct stime /
52、日期時間結(jié)構(gòu)體定義日期時間結(jié)構(gòu)體定義 unsigned int year; /年年 unsigned char mon; /月月 unsigned char day; /日日 unsigned char hour; /時時 unsigned char min; /分分 unsigned char sec; /秒秒 unsigned char week; /星期星期;/* 發(fā)送一個字節(jié)到發(fā)送一個字節(jié)到 ds1302 通信總線上通信總線上 */void ds1302bytewrite(unsigned char dat) unsigned char mask; for (mask=0 x01; m
53、ask!=0; mask=1) /低位在前,逐位移出低位在前,逐位移出 if (mask&dat) != 0) /首先輸出該位數(shù)據(jù)首先輸出該位數(shù)據(jù) ds1302_io = 1; else ds1302_io = 0; ds1302_ck = 1; /然后拉高時鐘然后拉高時鐘 ds1302_ck = 0; /再拉低時鐘,完成一個位的操作再拉低時鐘,完成一個位的操作 ds1302_io = 1; /最后確保釋放最后確保釋放 io 引腳引腳/* 由由 ds1302 通信總線上讀取一個字節(jié)通信總線上讀取一個字節(jié) */unsigned char ds1302byteread() unsigned
54、 char mask; unsigned char dat = 0; for (mask=0 x01; mask!=0; mask=1) /低位在前,逐位讀取低位在前,逐位讀取 if (ds1302_io != 0) /首先讀取此時的首先讀取此時的 io 引腳,并設(shè)置引腳,并設(shè)置 dat 中的對應(yīng)中的對應(yīng)位位 dat |= mask; ds1302_ck = 1; /然后拉高時鐘然后拉高時鐘 ds1302_ck = 0; /再拉低時鐘,完成一個位的操作再拉低時鐘,完成一個位的操作 return dat; /最后返回讀到的字節(jié)數(shù)據(jù)最后返回讀到的字節(jié)數(shù)據(jù)/* 用單次寫操作向某一寄存器寫入一個字節(jié),
55、用單次寫操作向某一寄存器寫入一個字節(jié),reg-寄存器地址,寄存器地址,dat-待寫入字待寫入字節(jié)節(jié) */void ds1302singlewrite(unsigned char reg, unsigned char dat) ds1302_ce = 1; /使能片選信號使能片選信號 ds1302bytewrite(reg1)|0 x80); /發(fā)送寫寄存器指令發(fā)送寫寄存器指令 ds1302bytewrite(dat); /寫入字節(jié)數(shù)據(jù)寫入字節(jié)數(shù)據(jù) ds1302_ce = 0; /除能片選信號除能片選信號/* 用單次讀操作從某一寄存器讀取一個字節(jié),用單次讀操作從某一寄存器讀取一個字節(jié),reg-寄
56、存器地址,返回值寄存器地址,返回值-讀到的讀到的字節(jié)字節(jié) */unsigned char ds1302singleread(unsigned char reg) unsigned char dat; ds1302_ce = 1; /使能片選信號使能片選信號 ds1302bytewrite(reg1)|0 x81); /發(fā)送讀寄存器指令發(fā)送讀寄存器指令 dat = ds1302byteread(); /讀取字節(jié)數(shù)據(jù)讀取字節(jié)數(shù)據(jù) ds1302_ce = 0; /除能片選信號除能片選信號 return dat;/* 用突發(fā)模式連續(xù)寫入用突發(fā)模式連續(xù)寫入 8 個寄存器數(shù)據(jù),個寄存器數(shù)據(jù),dat-待寫入
57、數(shù)據(jù)指針待寫入數(shù)據(jù)指針 */void ds1302burstwrite(unsigned char *dat) unsigned char i; ds1302_ce = 1; ds1302bytewrite(0 xbe); /發(fā)送突發(fā)寫寄存器指令發(fā)送突發(fā)寫寄存器指令 for (i=0; i8; i+) /連續(xù)寫入連續(xù)寫入 8 字節(jié)數(shù)據(jù)字節(jié)數(shù)據(jù) ds1302bytewrite(dati); ds1302_ce = 0;/* 用突發(fā)模式連續(xù)讀取用突發(fā)模式連續(xù)讀取 8 個寄存器的數(shù)據(jù),個寄存器的數(shù)據(jù),dat-讀取數(shù)據(jù)的接收指針讀取數(shù)據(jù)的接收指針 */void ds1302burstread(unsi
58、gned char *dat) unsigned char i; ds1302_ce = 1; ds1302bytewrite(0 xbf); /發(fā)送突發(fā)讀寄存器指令發(fā)送突發(fā)讀寄存器指令 for (i=0; iyear = buf6 + 0 x2000; time-mon = buf4; time-day = buf3; time-hour = buf2; time-min = buf1; time-sec = buf0; time-week = buf5;/* 設(shè)定實時時間,時間結(jié)構(gòu)體格式的設(shè)定時間轉(zhuǎn)換為數(shù)組并寫入設(shè)定實時時間,時間結(jié)構(gòu)體格式的設(shè)定時間轉(zhuǎn)換為數(shù)組并寫入 ds1302 */vo
59、id setrealtime(struct stime *time) unsigned char buf8; buf7 = 0; buf6 = time-year; buf5 = time-week; buf4 = time-mon; buf3 = time-day; buf2 = time-hour; buf1 = time-min; buf0 = time-sec; ds1302burstwrite(buf);/* ds1302 初始化,如發(fā)生掉電則重新設(shè)置初始時間初始化,如發(fā)生掉電則重新設(shè)置初始時間 */void initds1302() unsigned char dat; struc
60、t stime code inittime = /2013 年年 10 月月 8 日日 12:30:00 星期二星期二 0 x2013,0 x10,0 x08, 0 x12,0 x30,0 x00, 0 x02 ; ds1302_ce = 0; /初始化初始化 ds1302 通信引腳通信引腳 ds1302_ck = 0; dat = ds1302singleread(0); /讀取秒寄存器讀取秒寄存器 if (dat & 0 x80) != 0) /由秒寄存器最高位由秒寄存器最高位 ch 的值判斷的值判斷 ds1302 是否已是否已停止停止 ds1302singlewrite(7, 0 x00); /撤銷寫保護以允許寫入數(shù)據(jù)撤銷寫保護以允許寫入數(shù)據(jù) setrealtime(&inittime); /設(shè)置設(shè)置 ds1302 為默
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 人教版數(shù)學(xué)七年級上冊4.3.2《 角的比較與運算》聽評課記錄
- 魯教版地理七年級下冊8.1《自然特征與農(nóng)業(yè)》聽課評課記錄
- 小學(xué)二年級上冊乘法口算題
- 蘇教版三年級數(shù)學(xué)上冊口算練習(xí)試題全套
- 集團公司戰(zhàn)略合作框架協(xié)議書范本
- 藥店營業(yè)員聘用合同范本
- 2025年度虛擬現(xiàn)實游戲配音音效音樂委托協(xié)議
- 2025年度二零二五年度健身工作室門面店轉(zhuǎn)讓合同
- 大連市物業(yè)管理委托合同
- 2025年度咖啡連鎖品牌檔口轉(zhuǎn)讓及運營管理合同
- 慢性胰腺炎課件
- 北京理工大學(xué)應(yīng)用光學(xué)課件第四章
- 陰道鏡幻燈課件
- 現(xiàn)代漢語詞匯學(xué)精選課件
- PCB行業(yè)安全生產(chǎn)常見隱患及防范措施課件
- 上海音樂學(xué)院 樂理試題
- SAP中國客戶名單
- DB32∕T 186-2015 建筑消防設(shè)施檢測技術(shù)規(guī)程
- 2022年福建泉州中考英語真題【含答案】
- 淺談固定資產(chǎn)的審計
- WZCK-20系列微機直流監(jiān)控裝置使用說明書(v1.02)
評論
0/150
提交評論