單片機萬年歷電子鐘設(shè)計報告.docx_第1頁
單片機萬年歷電子鐘設(shè)計報告.docx_第2頁
單片機萬年歷電子鐘設(shè)計報告.docx_第3頁
單片機萬年歷電子鐘設(shè)計報告.docx_第4頁
單片機萬年歷電子鐘設(shè)計報告.docx_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

單片機萬年歷電子鐘設(shè)計報告萬年歷設(shè)計報告 學(xué)院:機械與電子工程學(xué)院 班級:09通信2班 組員:李培文1 一、設(shè)計要求與方案論證 . 3 1.1 設(shè)計要求: . 3 1.1.1基本要求 . 3 1.1.2發(fā)揮部分 . 3 1.2 系統(tǒng)基本方案選擇和論證 . 3 1.2.1單片機芯片的選擇方案和論證: . 3 1.2.2 顯示模塊選擇方案和論證: . 4 1.2.3時鐘芯片的選擇方案和論證: . 4 1.3 電路設(shè)計最終方案決定 . 4 二、理論分析與計算 . 4 2.1,秒數(shù)的產(chǎn)生由定時器T0產(chǎn)生: . 4 三.系統(tǒng)的硬件設(shè)計與實現(xiàn) . 5 3.1 電路設(shè)計框圖: . 5 3.2 系統(tǒng)硬件概述: . 6 3.3 主要單元電路的設(shè)計 . 6 3.3.1單片機主控制模塊的設(shè)計 . 6 3.3.2顯示模塊的設(shè)計 . 7 3.3.3鬧鐘模塊的設(shè)計 . 9 3.3.4電源穩(wěn)壓模塊 . 9 四、系統(tǒng)的軟件設(shè)計 . 10 4.1程序流程框圖 . 10 4.2鬧鐘模塊流程圖: . 11 4.3按鍵調(diào)整模塊流程圖: . 11 五、測試方案與測試結(jié)果分析 . 13 5.1 測試儀器 . 13 5.2軟件測試平臺 Keil C51 . 13 5.3 模塊測試 . 13 5.3.1顯示模塊測試 . 13 5.4測試結(jié)果分析與結(jié)論 . 14 5.4.1測試結(jié)果分析 . 14 5.4.2 測試結(jié)論 . 14 六、作品總結(jié) . 14 參考文獻(xiàn) . 14 附錄一:系統(tǒng)電路圖 . 15 附錄三:系統(tǒng)C程序 . 16 2 一、設(shè)計要求與方案論證 1.1 設(shè)計要求: 1.1.1基本要求 (1)準(zhǔn)確顯示:時、分、秒(24小時制) (2)顯示星期 (3)顯示公歷 (4)時間、日期、星期可調(diào)節(jié) (5)斷電記憶功能 1.1.2發(fā)揮部分 (1)鬧鐘功能 (2)顯示陰歷 (3)顯示24節(jié)氣 (4)其他 1.2 系統(tǒng)基本方案選擇和論證 1.2.1單片機芯片的選擇方案和論證: 方案一: 采用89C51芯片作為硬件核心,采用Flash ROM,內(nèi)部具有4KB ROM 存儲空間,能于3V的超低壓工作,而且與MCS-51系列單片機完全兼容,但是運用于電路設(shè)計中時由于不具備ISP在線編程技術(shù), 當(dāng)在對電路進(jìn)行調(diào)試時,由于程序的錯誤修改或?qū)Τ绦虻男略龉δ苄枰獰氤绦驎r,對芯片的多次拔插會對芯片造成一定的損壞。 方案二: 采用AT89S52,片內(nèi)ROM全都采用Flash ROM;能以3V的超底壓工作;同時也與MCS-51系列單片機完全該芯片內(nèi)部存儲器為8KB ROM 存儲空間,同樣具有89C51的功能,且具有在線編程可擦除技術(shù),當(dāng)在對電路進(jìn)行調(diào)試時,由于程序的錯誤修改或?qū)Τ绦虻男略龉δ苄枰獰氤绦驎r,不需要對芯片多次拔插,所以不會對芯片造成損壞。 所以選擇采用AT89S52作為主控制系統(tǒng). 3 1.2.2 顯示模塊選擇方案和論證: 方案一: 采用點陣式數(shù)碼管顯示,點陣式數(shù)碼管是由八行八列的發(fā)光二極管組成,對于顯示文字比較適合,如采用在顯示數(shù)字顯得太浪費,且價格也相對較高,所以不用此種作為顯示. 方案二: 采用LED數(shù)碼管動態(tài)掃描,LED數(shù)碼管價格適中,對于顯示數(shù)字最合適,但無法顯示圖形文字,在顯示星期是也只能用數(shù)字表示,而且采用動態(tài)掃描法與單片機連接時,在編程時比較復(fù)雜。所以也不采用了LED數(shù)碼管作為顯示。 方案三: 采用LCD液晶顯示屏,液晶顯示屏的顯示功能強大,可顯示文字,圖形,顯示多樣,清晰可見,所以在此設(shè)計中采用LCD液晶顯示屏. 1.2.3時鐘芯片的選擇方案和論證: 方案一: 采用DS1302時鐘芯片實現(xiàn)時鐘,DS1302芯片是一種高性能的時鐘芯片,可自動對秒、分、時、日、周、月、年以及閏年補償?shù)哪赀M(jìn)行計數(shù),而且精度高,位的RAM做為數(shù)據(jù)暫存區(qū),工作電壓2.5V,5.5V范圍內(nèi),2.5V時耗電小于300nA.但在,題目中明確規(guī)定不能選用不可以使用任何專用的時鐘芯片和模塊,因此不采用此方案。 方案二: 直接采用單片機定時計數(shù)器提供秒信號,使用程序?qū)崿F(xiàn)年、月、日、星期、時、分、秒計數(shù)。采用此種方案可以減少芯片的使用,也可以節(jié)約成本。所以采用此方案。 1.3 電路設(shè)計最終方案決定 綜上各方案所述,對此次作品的方案選定: 采用AT89S52作為主控制系統(tǒng);采用單片機定時器提供時鐘; 液晶顯示屏作為顯示。 二、理論分析與計算 2.1,秒數(shù)的產(chǎn)生由定時器T0產(chǎn)生: T0置10ms定時初值dc00H(216=65536D,dc00H=56320D) 定時時間=(65536-56320)*(1/11.0592)*12=10ms (單片機晶振f0=11.0592Mhz) 用累加的方法讓定時時間累加一百次即可產(chǎn)生一秒時間:100*10ms=1000ms=1s 4 2.2. 總天數(shù)的算法:首先用if語句判斷定義年到輸入年之間每一年是否為閏年,是閏年,該年的總天數(shù)為366,否則,為355。然后判斷輸入的年是否為定義年,若是,令總天數(shù)S=1,否則,用累加法計算出定義年到輸入年之間的總天數(shù),再把輸入年的一月到要輸出的月份之間的天數(shù)累加起來,若該月是閏年中的月份并且該月還大于二月,再使總天數(shù)加1,否則,不加,既算出從定義年一月一日到輸出年的該月一日的總天數(shù)。 2.3 輸出月份第一天為星期幾的算法:使總天數(shù)除以7取余加2得幾既為星期幾,若是7,則為星期日。 2.4. 算出輸出月份的完整日歷算法:算出輸出月份第一天為星期幾后,把該日期以前的位置用空格補上,并總該日起一次輸出天數(shù)直到月底,該月中的天數(shù)加上該月一日為星期幾的數(shù)字再除以7得0換行,即可完整的輸出該月的日歷。 5,計算某一天是星期幾的算法:蔡勒(Zeller)公式 歷史上的某一天是星期幾,未來的某一天是星期幾,關(guān)于這個問題,有很多計算公式(兩個通用計算公式和一些分段計算公式),其中最著名的是蔡勒(Zeller)公式。 即:w=y+y/4+c/4-2c+26(m+1)/10+d-1 公式中的符號含義如下,w:星期;c:世紀(jì)-1;y:年(兩位數(shù));m:月(m大于等于5,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月來計算,比如2003年1月1日要看作2002年的13月1日來計算);d:日; 代表取整,即只要整數(shù)部分。(C是世紀(jì)數(shù)減一,y是年份后兩位,M是月份,d是日數(shù)。1月和2月要按上一年的13月和 14月來算,這時C和y均按上一年取值。)算出來的W除以7,余數(shù)是幾就是星期幾。如果余數(shù)是0,則為星期日。以2049年10月1日(100周年國慶)為例,用蔡勒(Zeller)公式進(jìn)行計算,過程如下: 蔡勒(Zeller)公式:w=y+y/4+c/4-2c+26(m+1)/10+d-1 =49+49/4+20/4-220+26 (10+1)/10+1-1 =49+12.25+5-40+28.6 =49+12+5-40+28 =54 (除以7余5) 即2049年10月1日(100周年國慶)是星期5。 三.系統(tǒng)的硬件設(shè)計與實現(xiàn) 3.1 電路設(shè)計框圖: 5 AT89S52 液晶顯示模塊 鍵盤模塊 主控制 模 塊 鬧鐘模塊 3.2 系統(tǒng)硬件概述: 本電路是由AT89S52單片機為控制核心,具有在線編程功能,低功耗,能在3V超低壓工作;顯示部份LCD1602實現(xiàn),能夠同時顯示16x02即32個字符;鬧鐘部分由蜂鳴器構(gòu)成,蜂鳴器是一種一體化結(jié)構(gòu)的電子訊響器,采用直流電壓供電,廣泛應(yīng)用于計算機、打印機、復(fù)印機、報警器、電子玩具、汽車電子設(shè)備、電話機、定時器等電子產(chǎn)品中作發(fā)聲器件。 3.3 主要單元電路的設(shè)計 3.3.1單片機主控制模塊的設(shè)計 AT89S52單片機為40引腳雙列直插芯片,有四個I/O口P0,P1,P2,P3, MCS-51單片機共有4個8位的I/O口(P0、P1、P2、P3),每一條I/O線都能獨立地作輸出或輸入。 單片機的最小系統(tǒng)如下圖所示,18引腳和19引腳接時鐘電路,XTAL1接外部晶振和微調(diào)電容的一端,在片內(nèi)它是振蕩器倒相放大器的輸入,XTAL2接外部晶振和微調(diào)電容的另一端,在片內(nèi)它是振蕩器倒相放大器的輸出.第9引腳為復(fù)位輸入端,接上電容,電阻及開關(guān)后夠上電復(fù)位電路,20引腳為接地端,40引腳為電源端. 如圖-1 所示 6 圖-1 主控制系統(tǒng) 3.3.2顯示模塊的設(shè)計 LCD1602液晶顯示屏 工業(yè)字符型液晶,能夠同時顯示16x02即32個字符。(16列2行), 有16個引腳,通過D0D7的8位數(shù)據(jù)端傳輸數(shù)據(jù)和指令,引腳圖如圖6-5。 圖6-5 LCD1602引腳示意圖 LCD1602液晶顯示屏引腳功能如表6-5所示: 表6-5 LCD1602引腳功能 管腳1 V 一般接地 ss管腳2 V 接電源(+5V) dd管腳3 V 液晶顯示器對比度調(diào)整端,接正電源時對比度最弱,接地電源時對0比度最高 管腳4 RS RS為寄存器選擇,高電平1時選擇數(shù)據(jù)寄存器、低電平0時選擇指令寄存器 管腳5 R/W R/W為讀寫信號線,高電平(1)時進(jìn)行讀操作,低電平(0)時進(jìn)行寫操作。 管腳6 E E(或EN)端為使能(enable)端,下降沿使能。 管腳7 DB 底4位三態(tài)、 雙向數(shù)據(jù)總線 0位 0管腳8 DB 底4位三態(tài)、 雙向數(shù)據(jù)總線 1位 17 管腳9 DB 底4位三態(tài)、 雙向數(shù)據(jù)總線 2位 2管腳10 DB 底4位三態(tài)、 雙向數(shù)據(jù)總線 3位 3管腳11 DB 高4位三態(tài)、 雙向數(shù)據(jù)總線 4位 4管腳12 DB 高4位三態(tài)、 雙向數(shù)據(jù)總線 5位 5管腳13 DB 高4位三態(tài)、 雙向數(shù)據(jù)總線 6位 6管腳14 DB 高4位三態(tài)、 雙向數(shù)據(jù)總線 7位 7管腳15 BLA 背光電源正極 管腳16 BLK 背光 電源負(fù)極 1602液晶模塊內(nèi)部的控制器共有11條控制指令,如表10-14所示: 序號 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0 1 清顯示 0 0 0 0 0 0 0 0 0 1 2 光標(biāo)返回 0 0 0 0 0 0 0 0 1 * 3 置輸入模式 0 0 0 0 0 0 0 1 I/D S 4 顯示開/關(guān)控制 0 0 0 0 0 0 1 D C B 5 光標(biāo)或字符移位 0 0 0 0 0 1 S/C R/L * * 6 置功能 0 0 0 0 1 DL N F * * 置字符發(fā)生存貯器地字符發(fā)生存貯器地址 7 0 0 0 1 址 8 置數(shù)據(jù)存貯器地址 0 0 1 顯示數(shù)據(jù)存貯器地址 9 讀忙標(biāo)志或地址 0 1 BF 計數(shù)器地址 寫數(shù)到CGRAM或要寫的數(shù)據(jù)內(nèi)容 10 1 0 DDRAM) 11 從CGRAM或DDRAM讀數(shù) 1 1 讀出的數(shù)據(jù)內(nèi)容 表10-14:控制命令表 1602液晶模塊的讀寫操作、屏幕和光標(biāo)的操作都是通過指令編程來實現(xiàn)的。(說明:1為高電平、0為低電平) 指令1:清顯示,指令碼01H,光標(biāo)復(fù)位到地址00H位置。 指令2:光標(biāo)復(fù)位,光標(biāo)返回到地址00H。 指令3:光標(biāo)和顯示模式設(shè)置 I/D:光標(biāo)移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。 指令4:顯示開關(guān)控制。 D:控制整體顯示的開與關(guān),高電平表示開顯示,低電平表示關(guān)顯示 C:控制光標(biāo)的開與關(guān),高電平表示有光標(biāo),低電平表示無光標(biāo) B:控制光標(biāo)是否閃爍,高電平閃爍,低電平不閃爍。 指令5:光標(biāo)或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標(biāo)。 8 指令6:功能設(shè)置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。 指令7:字符發(fā)生器RAM地址設(shè)置。 指令8:DDRAM地址設(shè)置。 指令9:讀忙信號和光標(biāo)地址 BF:為忙標(biāo)志位,高電平表示忙,此時模塊不能接收命令或者數(shù)據(jù),如果為低電平表示不忙。 指令10:寫數(shù)據(jù)。 指令11:讀數(shù)據(jù)。 將lcd的引腳與單片機連接,通過單片機實現(xiàn)對顯示的輸出,電路圖實現(xiàn)如下: 3.3.3鬧鐘模塊的設(shè)計 鬧鐘模塊采用蜂鳴器實現(xiàn),蜂鳴器是一種一體化結(jié)構(gòu)的電子訊響器,采用直流電壓供電。 通過單片機的p3.7引腳輸出的電平變化來控制蜂鳴器的導(dǎo)通與否,設(shè)計如下: 3.3.4電源穩(wěn)壓模塊 方案一:LM7805穩(wěn)壓 9 方案二:USB接口+5V供電 四、系統(tǒng)的軟件設(shè)計 開始 初始化LCD、時間日期處理程序 4.1程序流程框圖 允許LCD顯 示, YES NO LCD關(guān)閉 讀取時間 LCD顯示 掃描按鍵 時間設(shè)定 鬧鐘設(shè)定 10 開始 初始化 掃描按鍵 4.2鬧鐘模塊流程圖: 鬧鐘設(shè)定 數(shù)據(jù)保存 返回 4.3按鍵調(diào)整模塊流程圖: 11 12 五、測試方案與測試結(jié)果分析 5.1 測試儀器 序號 名稱 作用 KELL 51 軟件 編寫調(diào)試C程序并生成可燒錄hex文件 1 仿真軟件Proteus 對電路進(jìn)行焊接前的仿真與測試 2 變壓器 提供5伏輸出電源 3 數(shù)字萬用表 測試工作電源檢測電路運行狀況 4 5.2軟件測試平臺 Keil C51 Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發(fā)系統(tǒng),與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢,因而易學(xué)易用。用過匯編語言后再使用C來開發(fā),體會更加深刻。Keil C51軟件提供豐富的庫函數(shù)和功能強大的集成開發(fā)調(diào)試工具,全Windows界面。另外重要的一點,只要看一下編譯后生成的匯編代碼,就能體會到Keil C51生成的目標(biāo)代碼效率非常之高,多數(shù)語句生成的匯編代碼很緊湊,容易理解。在開發(fā)大型軟件時更能體現(xiàn)高級語言的優(yōu)勢。下面詳細(xì)介紹Keil C51開發(fā)系統(tǒng)各部分功能和使用。Keil C51工具包的整體結(jié)構(gòu),其中uVision與Ishell分別是C51 for Windows和for Dos的集成開發(fā)環(huán)境(IDE),可以完成編輯、編譯、連接、調(diào)試、仿真等整個開發(fā)流程。 5.3 模塊測試 5.3.1顯示模塊測試 出現(xiàn)的問題:LCD1602液晶顯示屏背景燈亮但不顯示內(nèi)容。 解決問題:初步假設(shè)電源已經(jīng)供電但單片機沒有工作。用萬用表測試LCD使能端6引腳和寫命令選擇端4引腳,均有電位變化,推出單片機已經(jīng)工作。再次假設(shè),LCD1602的顯示屏對比度沒調(diào)好。讓電路工作,慢慢旋轉(zhuǎn)變阻器,但仍無內(nèi)容顯示。三次假設(shè),LCD1602某些引腳短路,經(jīng)檢測各引腳電平,發(fā)現(xiàn)6腳線路某地方與電源VCC相連,導(dǎo)致數(shù)據(jù)命令無法寫入LCD1602顯示器,導(dǎo)致內(nèi)容無法顯示,改正后,顯示正常,問題解決。VCC1602MOXx01) /); 13 5.4測試結(jié)果分析與結(jié)論 5.4.1測試結(jié)果分析 在測試過程中遇到lcd1602顯示不出來,首先使用萬用表對電路進(jìn)行測試,檢查工作電壓是否正常并查找出電路沒正常工作的部分,再次檢查各引腳接線情況。 5.4.2 測試結(jié)論 經(jīng)過多次的反復(fù)測試與分析,可以對電路的原理及功能更加熟悉,同時提高了設(shè)計能力同時在軟件的編程方面得到更到的提高,對編程能力得到加強.同時與及對電路的分析能力.對所學(xué)的知識得到很大的提高與鞏固. 六、作品總結(jié) 在整個設(shè)計過程中,發(fā)揮團隊精神,分工合作,我吳余壯健負(fù)責(zé)電路設(shè)計,軟件編程,設(shè)計報告的編寫,李培文負(fù)責(zé)網(wǎng)上查閱相關(guān)有用資料,王文龍負(fù)責(zé)電路的焊接,充分發(fā)揮人的主觀能動性,自主學(xué)習(xí),學(xué)到了許多沒學(xué)到的知識。較好的完成了作品。達(dá)到了預(yù)期的目的,在最初的設(shè)計中,發(fā)揮“三個臭皮匠,頂個諸葛亮”的作用。相互學(xué)習(xí)、相互討論、研究。完了最初的設(shè)想。在此次設(shè)計中,知道了做凡事要有一顆平常的心,不要想著走捷徑,一步一腳印。也練就了我們的耐心,做什么事都在有耐心。此次比賽中學(xué)到了很多很多東西,這是最重要的。總之,參加電子競賽我們的能力得到了全方位的提高。 參考文獻(xiàn) 新概念51單片機C語言教程 郭天祥編 電子工業(yè)出版社 2009 單片機C語言應(yīng)用一百例 王東鋒 王會良 董冠強編電子工業(yè)出版社 2009 楊子文 編 單片機原理及應(yīng)用 西安電子科技大學(xué)出版社 2006 14 附錄一,系統(tǒng)電路圖 附錄二,仿真效果圖 15 附錄三,系統(tǒng)C程序 #include #include unsigned char code dis_week=SUN,MON,TUE,WED,THU,FRI,SAT; unsigned char code para_month13=0,0,3,3,6,1,4,6,2,5,0,3,5; /星期月參變數(shù) unsigned char data dis_buf116; /lcd上排顯示緩沖區(qū) unsigned char data dis_buf216; /lcd下排顯示緩沖區(qū) unsigned char data year,month,date,week;/年、月、日、星期 unsigned char data armhour,armmin,armsec;/鬧鐘時、分、秒 unsigned char data hour,min,sec,sec100; /時、分、秒、百分之一秒 unsigned char data flag,vkey,skey;/設(shè)置狀態(tài)計數(shù)標(biāo)志、按鍵先前值、按鍵當(dāng)前值 bit alarm; /標(biāo)識是否啟用鬧鐘,1-啟用,0-關(guān)閉 sbit rs = P20; /LCD數(shù)據(jù)/命令選擇端(H/L) sbit rw = P21; /LCD讀/寫選擇端(H/L) sbit ep = P22; /LCD使能控制 sbit PRE = P16; /調(diào)整鍵(k3) sbit SET = P17; /調(diào)整鍵(k4) sbit SPK = P37; void delayms(unsigned char ms); /延時程序 bit lcd_busy(); /測試LCD忙碌狀態(tài)程序 void lcd_wcmd(char cmd); /寫入指令到LCD程序 void lcd_wdat(char dat); /寫入數(shù)據(jù)到LCD程序 void lcd_pos(char pos); /LCD數(shù)據(jù)指針位置程序 void lcd_init(); /LCD初始化設(shè)定程序 void pro_timedate(); /時間日期處理程序 void pro_display(); /顯示處理程序 void pro_key(); /按鍵處理程序 void time_alarm(); /定時報警功能(鬧鐘) unsigned char scan_key(); /按鍵掃描程序 unsigned char week_proc(); /星期自動計算與顯示函數(shù) bit leap_year(); /判斷是否為閏年 void lcd_sef_chr(); /LCD自定義字符程序 void update_disbuf(unsigned char t1,unsigned char t2,unsigned char dis_h,unsigned char dis_m,unsigned char dis_s); /更新顯示緩沖區(qū)函數(shù) 16 / 延時程序 void delay(unsigned char ms) while(ms-) unsigned char i; for(i = 0; i 250; i+) _nop_(); /執(zhí)行一條_nop_()指令為一個機器周期 _nop_(); _nop_(); _nop_(); /測試LCD忙碌狀態(tài) bit lcd_busy() bit result; rs = 0; rw = 1; ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); result =(bit)(P0&0x80); /LCD的D0-D7中,D7=1為忙碌,D7=0為空閑 ep = 0; return result; /寫入指令到LCD void lcd_wcmd(char cmd) while(lcd_busy(); /當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫指令 rs = 0; rw = 0; ep = 0; _nop_(); _nop_(); 17 P0 = cmd; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; /寫入數(shù)據(jù)到LCD void lcd_wdat(char dat) while(lcd_busy(); /當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫數(shù)據(jù) rs = 1; rw = 0; ep = 0; P0 = dat; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; /LCD數(shù)據(jù)指針位置程序 void lcd_pos(char pos) lcd_wcmd(pos|0x80); /數(shù)據(jù)指針=80+地址碼(00H27H,40H67H) /設(shè)定二個自定義字符,(注意:LCD1602中自定義字符的地址為0x00-0x07,18 即可定義8個字符) /這里我們設(shè)定把一個自定義字符放在0x00位置(000),另一個放在0x01位子(001) void lcd_sef_chr() /第一個自定義字符 lcd_wcmd(0x40); /01 000 000 第1行地址 (D7D6為地址設(shè)定命令形式D5D4D3為字符存放位置(0-7),D2D1D0為字符行地址(0-7) lcd_wdat(0x1f); /XXX 11111 第1行數(shù)據(jù)(D7D6D5為XXX,表示為任意數(shù)(一般用000),D4D3D2D1D0為字符行數(shù)據(jù)(1-點亮,0-熄滅) lcd_wcmd(0x41); /01 000 001 第2行地址 lcd_wdat(0x11); /XXX 10001 第2行數(shù)據(jù) lcd_wcmd(0x42); /01 000 010 第3行地址 lcd_wdat(0x15); /XXX 10101 第3行數(shù)據(jù) lcd_wcmd(0x43); /01 000 011 第4行地址 lcd_wdat(0x11); /XXX 10001 第4行數(shù)據(jù) lcd_wcmd(0x44); /01 000 100 第5行地址 lcd_wdat(0x1f); /XXX 11111 第5行數(shù)據(jù) lcd_wcmd(0x45); /01 000 101 第6行地址 lcd_wdat(0x0a); /XXX 01010 第6行數(shù)據(jù) lcd_wcmd(0x46); /01 000 110 第7行地址 lcd_wdat(0x1f); /XXX 11111 第7行數(shù)據(jù) lcd_wcmd(0x47); /01 000 111 第8行地址 lcd_wdat(0x00); /XXX 00000 第8行數(shù)據(jù) /第二個自定義字符 lcd_wcmd(0x48); /01 001 000 第1行地址 lcd_wdat(0x01); /XXX 00001 第1行數(shù)據(jù) lcd_wcmd(0x49); /01 001 001 第2行地址 lcd_wdat(0x1b); /XXX 11011 第2行數(shù)據(jù) lcd_wcmd(0x4a); /01 001 010 第3行地址 lcd_wdat(0x1d); /XXX 11101 第3行數(shù)據(jù) lcd_wcmd(0x4b); /01 001 011 第4行地址 lcd_wdat(0x19); /XXX 11001 第4行數(shù)據(jù) lcd_wcmd(0x4c); /01 001 100 第5行地址 lcd_wdat(0x1d); /XXX 11101 第5行數(shù)據(jù) lcd_wcmd(0x4d); /01 001 101 第6行地址 lcd_wdat(0x1b); /XXX 11011 第6行數(shù)據(jù) lcd_wcmd(0x4e); /01 001 110 第7行地址 lcd_wdat(0x01); /XXX 00001 第7行數(shù)據(jù) 19 lcd_wcmd(0x4f); /01 001 111 第8行地址 lcd_wdat(0x00); /XXX 00000 第8行數(shù)據(jù) /LCD初始化設(shè)定 void lcd_init() lcd_wcmd(0x38); /設(shè)置LCD為16X2顯示,5X7點陣,八位數(shù)據(jù)借口 delay(1); lcd_wcmd(0x0c); /LCD開顯示及光標(biāo)設(shè)置(光標(biāo)不閃爍,不顯示-) delay(1); lcd_wcmd(0x06); /LCD顯示光標(biāo)移動設(shè)置(光標(biāo)地址指針加1,整屏顯示不移動) delay(1); lcd_wcmd(0x01); /清除LCD的顯示內(nèi)容 delay(1); /閏年的計算 bit leap_year() bit leap; if(year%4=0&year%100!=0)|year%400=0)/閏年的條件 leap=1; else leap=0; return leap; /星期的自動運算和處理 unsigned char week_proc() unsigned char num_leap; unsigned char c; num_leap=year/4-year/100+year/400;/自00年起到y(tǒng)ear所經(jīng)歷的閏年數(shù) if( leap_year()& month 59) sec = 0; min+; if(min59) min=0; hour+; if(hour23) hour=0; date+; if (month=1|month=3|month=5|month=7|month=8|month=10|month=12) if (date31) date=1;month+; /大月31天 if (month=4|month=6|month=9|month=11) if (date30) date=1;month+; /小月30天 if (month=2) if( leap_year() /閏年的條件 if (date29) date=1;month+; /閏年2月為29天 else if (date28) date=1;month+; /平年2月為28天 if (month12) month=1;year+; if (year99) year=0; week_proc(); if (sec=armsec & min=armmin & hour=armhour) if (alarm) TR1=1; /鬧鐘啟用時,報警時間到,啟動Timer1 22 /顯示處理程序 void pro_display() unsigned char i; lcd_pos(0x00); for (i=0;i=15;i+) lcd_wdat(dis_buf1i); lcd_pos(0x40); for (i=0;i= 100) /1秒時間 (100*10ms=1000ms=1s) sec100 = 0; pro_timedate();/調(diào)用時間和日期處理程序 if (sec&0x01) / 一秒顯示“hello”,一秒顯示“kitty” update_disbuf(0x00,KITTY,hour,min,sec); /0x00表示顯示00位置的自定義字符 else update_disbuf(0x00,HELLO,hour,min,sec); pro_display(); /調(diào)用顯示處理函數(shù) /按鍵掃描程序 unsigned char scan_key() skey=0x00; /給變量vkey置初值 skey|=PRE; /讀取PRE鍵的狀態(tài) skey=skey1; /將PRE鍵的狀態(tài)存于skey的B1位 skey|=SET; /讀取SET鍵的狀態(tài),并存于skey的B0位 return skey; /返回skey的鍵值(即PRE,SET的狀態(tài)) 23 /外部中斷INT0中斷處理程序 void int0() interrupt 0 TR0=0; /禁止Timer0 IE=0; /禁止中斷 lcd_wcmd(0x0e); /顯示光標(biāo)_,整個光標(biāo)不閃爍 alarm=1; update_disbuf(0x50,alarm:,armhour,armmin,armsec); /更新顯示數(shù)據(jù),0x50表示要顯示P pro_display(); /調(diào)用顯示處理程序 lcd_pos(0x47); /使光標(biāo)位于第一個調(diào)整項下 flag=0; vkey=0x03; while(flag0x0a) skey = scan_key(); /掃描按鍵狀態(tài) if (skeyvkey) /若skey與vkey相同,跳出循環(huán),相異執(zhí)行循環(huán)體 delay(10); /去按鍵抖動 skey = scan_key(); /轉(zhuǎn)回掃描按鍵狀態(tài) if (skeyvk

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論