版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p><b> 萬年歷設(shè)計報告</b></p><p><b> 學(xué)院:機電工程學(xué)院</b></p><p> 一、設(shè)計要求與方案論證3</p><p> 1.1 設(shè)計要求:3</p><p> 1.1.1基本要求3</p><p> 1.1.2
2、發(fā)揮部分3</p><p> 1.2 系統(tǒng)基本方案選擇和論證3</p><p> 1.2.1單片機芯片的選擇方案和論證:3</p><p> 1.2.2 顯示模塊選擇方案和論證:4</p><p> 1.2.3時鐘芯片的選擇方案和論證:4</p><p> 1.3 電路設(shè)計最終方案決定4</
3、p><p> 二、理論分析與計算4</p><p> 2.1,秒數(shù)的產(chǎn)生由定時器T0產(chǎn)生:4</p><p> 三.系統(tǒng)的硬件設(shè)計與實現(xiàn)5</p><p> 3.1 電路設(shè)計框圖:5</p><p> 3.2 系統(tǒng)硬件概述:6</p><p> 3.3 主要單元電路的設(shè)計6&
4、lt;/p><p> 3.3.1單片機主控制模塊的設(shè)計6</p><p> 3.3.2顯示模塊的設(shè)計7</p><p> 3.3.3鬧鐘模塊的設(shè)計9</p><p> 3.3.4電源穩(wěn)壓模塊9</p><p> 四、系統(tǒng)的軟件設(shè)計10</p><p> 4.1程序流程框圖10
5、</p><p> 4.2鬧鐘模塊流程圖:11</p><p> 4.3按鍵調(diào)整模塊流程圖:11</p><p> 五、測試方案與測試結(jié)果分析13</p><p> 5.1 測試儀器13</p><p> 5.2軟件測試平臺 Keil C5113</p><p> 5.3
6、模塊測試13</p><p> 5.3.1顯示模塊測試13</p><p> 5.4測試結(jié)果分析與結(jié)論14</p><p> 5.4.1測試結(jié)果分析14</p><p> 5.4.2 測試結(jié)論14</p><p><b> 六、作品總結(jié)14</b></p>&l
7、t;p><b> 參考文獻(xiàn)14</b></p><p> 附錄一:系統(tǒng)電路圖15</p><p> 附錄三:系統(tǒng)C程序16</p><p> 一、設(shè)計要求與方案論證</p><p><b> 1.1 設(shè)計要求:</b></p><p><b>
8、 1.1.1基本要求</b></p><p> ?。?)準(zhǔn)確顯示:時、分、秒(24小時制)</p><p><b> ?。?)顯示星期</b></p><p><b> (3)顯示公歷</b></p><p> ?。?)時間、日期、星期可調(diào)節(jié)</p><p>
9、<b> ?。?)斷電記憶功能</b></p><p><b> 1.1.2發(fā)揮部分</b></p><p><b> (1)鬧鐘功能</b></p><p><b> ?。?)顯示陰歷</b></p><p><b> ?。?)顯示24節(jié)氣
10、</b></p><p><b> ?。?)其他</b></p><p> 1.2 系統(tǒng)基本方案選擇和論證</p><p> 1.2.1單片機芯片的選擇方案和論證:</p><p><b> 方案一: </b></p><p> 采用89C51芯片作為硬件
11、核心,采用Flash ROM,內(nèi)部具有4KB ROM 存儲空間,能于3V的超低壓工作,而且與MCS-51系列單片機完全兼容,但是運用于電路設(shè)計中時由于不具備ISP在線編程技術(shù), 當(dāng)在對電路進(jìn)行調(diào)試時,由于程序的錯誤修改或?qū)Τ绦虻男略龉δ苄枰獰氤绦驎r,對芯片的多次拔插會對芯片造成一定的損壞。</p><p><b> 方案二:</b></p><p> 采用AT8
12、9S52,片內(nèi)ROM全都采用Flash ROM;能以3V的超底壓工作;同時也與MCS-51系列單片機完全該芯片內(nèi)部存儲器為8KB ROM 存儲空間,同樣具有89C51的功能,且具有在線編程可擦除技術(shù),當(dāng)在對電路進(jìn)行調(diào)試時,由于程序的錯誤修改或?qū)Τ绦虻男略龉δ苄枰獰氤绦驎r,不需要對芯片多次拔插,所以不會對芯片造成損壞。</p><p> 所以選擇采用AT89S52作為主控制系統(tǒng).</p><
13、p> 1.2.2 顯示模塊選擇方案和論證:</p><p><b> 方案一:</b></p><p> 采用點陣式數(shù)碼管顯示,點陣式數(shù)碼管是由八行八列的發(fā)光二極管組成,對于顯示文字比較適合,如采用在顯示數(shù)字顯得太浪費,且價格也相對較高,所以不用此種作為顯示.</p><p><b> 方案二:</b><
14、;/p><p> 采用LED數(shù)碼管動態(tài)掃描,LED數(shù)碼管價格適中,對于顯示數(shù)字最合適,但無法顯示圖形文字,在顯示星期是也只能用數(shù)字表示,而且采用動態(tài)掃描法與單片機連接時,在編程時比較復(fù)雜。所以也不采用了LED數(shù)碼管作為顯示。</p><p><b> 方案三:</b></p><p> 采用LCD液晶顯示屏,液晶顯示屏的顯示功能強大,可顯示文
15、字,圖形,顯示多樣,清晰可見,所以在此設(shè)計中采用LCD液晶顯示屏.</p><p> 1.2.3時鐘芯片的選擇方案和論證:</p><p><b> 方案一:</b></p><p> 采用DS1302時鐘芯片實現(xiàn)時鐘,DS1302芯片是一種高性能的時鐘芯片,可自動對秒、分、時、日、周、月、年以及閏年補償?shù)哪赀M(jìn)行計數(shù),而且精度高,位的RA
16、M做為數(shù)據(jù)暫存區(qū),工作電壓2.5V~5.5V范圍內(nèi),2.5V時耗電小于300nA.但在,題目中明確規(guī)定不能選用不可以使用任何專用的時鐘芯片和模塊,因此不采用此方案。</p><p><b> 方案二:</b></p><p> 直接采用單片機定時計數(shù)器提供秒信號,使用程序?qū)崿F(xiàn)年、月、日、星期、時、分、秒計數(shù)。采用此種方案可以減少芯片的使用,也可以節(jié)約成本。所以采用
17、此方案。</p><p> 1.3 電路設(shè)計最終方案決定</p><p> 綜上各方案所述,對此次作品的方案選定: 采用AT89S52作為主控制系統(tǒng);采用單片機定時器提供時鐘; 液晶顯示屏作為顯示。</p><p><b> 二、理論分析與計算</b></p><p> 2.1,秒數(shù)的產(chǎn)生由定時器T0產(chǎn)生:<
18、;/p><p> T0置10ms定時初值dc00H(2^16=65536D,dc00H=56320D)</p><p> 定時時間=(65536-56320)*(1/11.0592)*12=10ms (單片機晶振f0=11.0592Mhz)</p><p> 用累加的方法讓定時時間累加一百次即可產(chǎn)生一秒時間:100*10ms=1000ms=1s</p>
19、<p> 2.2. 總天數(shù)的算法:首先用if語句判斷定義年到輸入年之間每一年是否為閏年,是閏年,該年的總天數(shù)為366,否則,為355。然后判斷輸入的年是否為定義年,若是,令總天數(shù)S=1,否則,用累加法計算出定義年到輸入年之間的總天數(shù),再把輸入年的一月到要輸出的月份之間的天數(shù)累加起來,若該月是閏年中的月份并且該月還大于二月,再使總天數(shù)加1,否則,不加,既算出從定義年一月一日到輸出年的該月一日的總天數(shù)。2.3 輸出月份第一
20、天為星期幾的算法:使總天數(shù)除以7取余加2得幾既為星期幾,若是7,則為星期日。2.4. 算出輸出月份的完整日歷算法:算出輸出月份第一天為星期幾后,把該日期以前的位置用空格補上,并總該日起一次輸出天數(shù)直到月底,該月中的天數(shù)加上該月一日為星期幾的數(shù)字再除以7得0換行,即可完整的輸出該月的日歷。</p><p> 5,計算某一天是星期幾的算法:蔡勒(Zeller)公式 歷史上的某一天是星期幾?未來的某一
21、天是星期幾?關(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:
22、日;[ ]代表取整,即只要整數(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
23、60;=49+[49/4]+[20/4]-2×20+[2</p><p> 三.系統(tǒng)的硬件設(shè)計與實現(xiàn)</p><p> 3.1 電路設(shè)計框圖:</p><p> 3.2 系統(tǒng)硬件概述:</p><p> 本電路是由AT89S52單片機為控制核心,具有在線編程功能,低功耗,能在3V超低壓工作;顯示部份LCD1602實現(xiàn),能夠同
24、時顯示16x02即32個字符;鬧鐘部分由蜂鳴器構(gòu)成,蜂鳴器是一種一體化結(jié)構(gòu)的電子訊響器,采用直流電壓供電,廣泛應(yīng)用于計算機、打印機、復(fù)印機、報警器、電子玩具、汽車電子設(shè)備、電話機、定時器等電子產(chǎn)品中作發(fā)聲器件。</p><p> 3.3 主要單元電路的設(shè)計</p><p> 3.3.1單片機主控制模塊的設(shè)計</p><p> AT89S52單片機為40引腳雙列
25、直插芯片,有四個I/O口P0,P1,P2,P3, MCS-51單片機共有4個8位的I/O口(P0、P1、P2、P3),每一條I/O線都能獨立地作輸出或輸入。</p><p> 單片機的最小系統(tǒng)如下圖所示,18引腳和19引腳接時鐘電路,XTAL1接外部晶振和微調(diào)電容的一端,在片內(nèi)它是振蕩器倒相放大器的輸入,XTAL2接外部晶振和微調(diào)電容的另一端,在片內(nèi)它是振蕩器倒相放大器的輸出.第9引腳為復(fù)位輸入端,接上電容,電
26、阻及開關(guān)后夠上電復(fù)位電路,20引腳為接地端,40引腳為電源端. 如圖-1 所示</p><p> 圖-1 主控制系統(tǒng) </p><p> 3.3.2顯示模塊的設(shè)計</p><p> LCD1602液晶顯示屏 工業(yè)字符型液晶,能夠同時顯示16x02即32個字符。(16列2行),</p><p> 有16個引腳,通過D0~D7的8位數(shù)
27、據(jù)端傳輸數(shù)據(jù)和指令,引腳圖如圖6-5。</p><p> 圖6-5 LCD1602引腳示意圖</p><p> LCD1602液晶顯示屏引腳功能如表6-5所示:</p><p> 表6-5 LCD1602引腳功能</p><p> 1602液晶模塊內(nèi)部的控制器共有11條控制指令,如表10-14所示:</p><
28、p> 表10-14:控制命令表</p><p> 1602液晶模塊的讀寫操作、屏幕和光標(biāo)的操作都是通過指令編程來實現(xiàn)的。(說明:1為高電平、0為低電平)</p><p> 指令1:清顯示,指令碼01H,光標(biāo)復(fù)位到地址00H位置。</p><p> 指令2:光標(biāo)復(fù)位,光標(biāo)返回到地址00H。</p><p> 指令3:光標(biāo)和顯示模
29、式設(shè)置 I/D:光標(biāo)移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。</p><p> 指令4:顯示開關(guān)控制。 D:控制整體顯示的開與關(guān),高電平表示開顯示,低電平表示關(guān)顯示 C:控制光標(biāo)的開與關(guān),高電平表示有光標(biāo),低電平表示無光標(biāo) B:控制光標(biāo)是否閃爍,高電平閃爍,低電平不閃爍。</p><p> 指令5:光標(biāo)或顯示移位 S/C:高電
30、平時移動顯示的文字,低電平時移動光標(biāo)。</p><p> 指令6:功能設(shè)置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。</p><p> 指令7:字符發(fā)生器RAM地址設(shè)置。</p><p> 指令8:DDRAM地址設(shè)置。</p>
31、<p> 指令9:讀忙信號和光標(biāo)地址 BF:為忙標(biāo)志位,高電平表示忙,此時模塊不能接收命令或者數(shù)據(jù),如果為低電平表示不忙。</p><p><b> 指令10:寫數(shù)據(jù)。</b></p><p><b> 指令11:讀數(shù)據(jù)。</b></p><p> 將lcd的引腳與單片機連接,通過單片機實現(xiàn)對顯示的輸出,
32、電路圖實現(xiàn)如下:</p><p> 3.3.3鬧鐘模塊的設(shè)計</p><p> 鬧鐘模塊采用蜂鳴器實現(xiàn),蜂鳴器是一種一體化結(jié)構(gòu)的電子訊響器,采用直流電壓供電。</p><p> 通過單片機的p3.7引腳輸出的電平變化來控制蜂鳴器的導(dǎo)通與否,設(shè)計如下:</p><p> 3.3.4電源穩(wěn)壓模塊</p><p>
33、 方案一:LM7805穩(wěn)壓</p><p> 方案二:USB接口+5V供電</p><p><b> 四、系統(tǒng)的軟件設(shè)計</b></p><p><b> 4.1程序流程框圖</b></p><p> 4.2鬧鐘模塊流程圖:</p><p> 4.3按鍵調(diào)整模塊流程
34、圖:</p><p> 五、測試方案與測試結(jié)果分析</p><p><b> 5.1 測試儀器</b></p><p> 5.2軟件測試平臺 Keil C51</p><p> Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發(fā)系統(tǒng),與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀
35、性、可維護(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é)
36、構(gòu),其中uVision與Ishell分別是C51 for Windows和for Dos的集成開發(fā)環(huán)境(IDE),可以完成編輯、編譯、連接、調(diào)試、仿真等整個開發(fā)流程。</p><p><b> 5.3 模塊測試</b></p><p> 5.3.1顯示模塊測試</p><p> 出現(xiàn)的問題:LCD1602液晶顯示屏背景燈亮但不顯示內(nèi)容。&
37、lt;/p><p> 解決問題:初步假設(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)容無法顯示,改正后,顯示正常,問
38、題解決。VCC1602MOXx01) //"); </p><p> 5.4測試結(jié)果分析與結(jié)論</p><p> 5.4.1測試結(jié)果分析</p><p> 在測試過程中遇到lcd1602顯示不出來,首先使用萬用表對電路進(jìn)行測試,檢查
39、工作電壓是否正常并查找出電路沒正常工作的部分,再次檢查各引腳接線情況。</p><p> 5.4.2 測試結(jié)論</p><p> 經(jīng)過多次的反復(fù)測試與分析,可以對電路的原理及功能更加熟悉,同時提高了設(shè)計能力與及對電路的分析能力.同時在軟件的編程方面得到更到的提高,對編程能力得到加強.同時對所學(xué)的知識得到很大的提高與鞏固.</p><p><b> 六
40、、作品總結(jié)</b></p><p> 在整個設(shè)計過程中,發(fā)揮團(tuán)隊精神,分工合作,我**負(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è)計中,知道了做凡事要有一顆平
41、常的心,不要想著走捷徑,一步一腳印。也練就了我們的耐心,做什么事都在有耐心。此次比賽中學(xué)到了很多很多東西,這是最重要的??傊瑓⒓与娮痈傎愇覀兊哪芰Φ玫搅巳轿坏奶岣?。</p><p><b> 參考文獻(xiàn)</b></p><p> 新概念51單片機C語言教程 郭天祥編 電子工業(yè)出版社 2009</p><p> 單片機C語言應(yīng)用一百例
42、王東鋒 王會良 董冠強編電子工業(yè)出版社 2009</p><p> 楊子文 編 單片機原理及應(yīng)用 西安電子科技大學(xué)出版社 2006</p><p><b> 附錄一:系統(tǒng)電路圖</b></p><p><b> 附錄二:仿真效果圖</b></p><p><b> 附錄三:系統(tǒng)
43、C程序</b></p><p> #include<reg52.h></p><p> #include<intrins.h></p><p> unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};</p><p&
44、gt; unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月參變數(shù)</p><p> unsigned char data dis_buf1[16]; //lcd上排顯示緩沖區(qū)</p><p> unsigned char data dis_buf2[16]; //lcd下排顯示緩沖區(qū) <
45、/p><p> unsigned char data year,month,date,week;//年、月、日、星期</p><p> unsigned char data armhour,armmin,armsec;//鬧鐘時、分、秒</p><p> unsigned char data hour,min,sec,sec100; //時、分、秒、百分之一秒&l
46、t;/p><p> unsigned char data flag,vkey,skey;//設(shè)置狀態(tài)計數(shù)標(biāo)志、按鍵先前值、按鍵當(dāng)前值 </p><p> bit alarm; //標(biāo)識是否啟用鬧鐘,1--啟用,0--關(guān)閉</p><p> sbit rs = P2^0; //LCD數(shù)據(jù)/命令選擇端(H/L)</p><p> sb
47、it rw = P2^1; //LCD讀/寫選擇端(H/L)</p><p> sbit ep = P2^2; //LCD使能控制</p><p> sbit PRE = P1^6; //調(diào)整鍵(k3)</p><p> sbit SET = P1^7; //調(diào)整鍵(k4)</p><p> sbit SP
48、K = P3^7; </p><p> void delayms(unsigned char ms); //延時程序</p><p> bit lcd_busy(); //測試LCD忙碌狀態(tài)程序</p><p> void lcd_wcmd(char cmd); //寫入指令到LCD程序</p><p> void l
49、cd_wdat(char dat); //寫入數(shù)據(jù)到LCD程序</p><p> void lcd_pos(char pos); //LCD數(shù)據(jù)指針位置程序</p><p> void lcd_init(); //LCD初始化設(shè)定程序</p><p> void pro_timedate(); //時間日期處理程序</p><
50、;p> void pro_display(); //顯示處理程序</p><p> void pro_key(); //按鍵處理程序</p><p> void time_alarm(); //定時報警功能(鬧鐘)</p><p> unsigned char scan_key(); //按鍵掃描程序</p><
51、;p> unsigned char week_proc(); //星期自動計算與顯示函數(shù)</p><p> bit leap_year(); //判斷是否為閏年</p><p> void lcd_sef_chr(); //LCD自定義字符程序</p><p> void update_disbuf(unsigned char t1,un
52、signed char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s); //更新顯示緩沖區(qū)函數(shù)</p><p><b> // 延時程序</b></p><p> void delay(unsigned char ms)</p><p> { whil
53、e(ms--)</p><p> { unsigned char i;</p><p> for(i = 0; i< 250; i++) </p><p><b> {</b></p><p> _nop_(); //執(zhí)行一條_nop_()指令為一個機器周期</p><
54、p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> }</b></p><p><b> }</b>
55、</p><p><b> } </b></p><p> //測試LCD忙碌狀態(tài)</p><p> bit lcd_busy()</p><p><b> { </b></p><p> bit result;</p><p><b
56、> rs = 0;</b></p><p><b> rw = 1;</b></p><p><b> ep = 1;</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b>
57、;</p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p> result =(bit)(P0&0x80); //LCD的D0--D7中,D7=1為忙碌,D7=0為空閑</p><p><b> ep = 0;
58、</b></p><p> return result; </p><p><b> }</b></p><p> //寫入指令到LCD</p><p> void lcd_wcmd(char cmd)</p><p><b> { </b>
59、</p><p> while(lcd_busy()); //當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫指令</p><p><b> rs = 0;</b></p><p><b> rw = 0;</b></p><p><b> ep =
60、 0;</b></p><p><b> _nop_();</b></p><p><b> _nop_(); </b></p><p><b> P0 = cmd;</b></p><p><b> _nop_();</b></
61、p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> ep = 1;</b></p><p><b
62、> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> ep = 0; </
63、b></p><p><b> }</b></p><p> //寫入數(shù)據(jù)到LCD</p><p> void lcd_wdat(char dat) </p><p><b> { </b></p><p> while(lcd_busy());
64、//當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫數(shù)據(jù)</p><p><b> rs = 1;</b></p><p><b> rw = 0;</b></p><p><b> ep = 0;</b></p><p><b>
65、; P0 = dat;</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b&g
66、t;</p><p><b> ep = 1;</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p><b> _nop_();</b></p><p&g
67、t;<b> _nop_();</b></p><p><b> ep = 0; </b></p><p><b> }</b></p><p> //LCD數(shù)據(jù)指針位置程序</p><p> void lcd_pos(char pos)</p><
68、;p><b> { </b></p><p> lcd_wcmd(pos|0x80); //數(shù)據(jù)指針=80+地址碼(00H~27H,40H~67H)</p><p><b> }</b></p><p> //設(shè)定二個自定義字符,(注意:LCD1602中自定義字符的地址為0x00--0x07,即可定
69、義8個字符)</p><p> //這里我們設(shè)定把一個自定義字符放在0x00位置(000),另一個放在0x01位子(001)</p><p> void lcd_sef_chr()</p><p> { //第一個自定義字符</p><p> lcd_wcmd(0x40); //"01 000 000" 第1行地
70、址 (D7D6為地址設(shè)定命令形式D5D4D3為字符存放位置(0--7),D2D1D0為字符行地址(0--7))</p><p> lcd_wdat(0x1f); //"XXX 11111" 第1行數(shù)據(jù)(D7D6D5為XXX,表示為任意數(shù)(一般用000),D4D3D2D1D0為字符行數(shù)據(jù)(1-點亮,0-熄滅)</p><p> lcd_wcmd(0x41); //&
71、quot;01 000 001" 第2行地址</p><p> lcd_wdat(0x11); //"XXX 10001" 第2行數(shù)據(jù)</p><p> lcd_wcmd(0x42); //"01 000 010" 第3行地址</p><p> lcd_wdat(0x15); //"XXX 101
72、01" 第3行數(shù)據(jù)</p><p> lcd_wcmd(0x43); //"01 000 011" 第4行地址</p><p> lcd_wdat(0x11); //"XXX 10001" 第4行數(shù)據(jù)</p><p> lcd_wcmd(0x44); //"01 000 100" 第5行
73、地址</p><p> lcd_wdat(0x1f); //"XXX 11111" 第5行數(shù)據(jù)</p><p> lcd_wcmd(0x45); //"01 000 101" 第6行地址</p><p> lcd_wdat(0x0a); //"XXX 01010" 第6行數(shù)據(jù)</p>
74、<p> lcd_wcmd(0x46); //"01 000 110" 第7行地址</p><p> lcd_wdat(0x1f); //"XXX 11111" 第7行數(shù)據(jù)</p><p> lcd_wcmd(0x47); //"01 000 111" 第8行地址</p><p> l
75、cd_wdat(0x00); //"XXX 00000" 第8行數(shù)據(jù) </p><p> //第二個自定義字符</p><p> lcd_wcmd(0x48); //"01 001 000" 第1行地址 </p><p> lcd_wdat(0x01); //"XXX 00001" 第1行數(shù)據(jù) &
76、lt;/p><p> lcd_wcmd(0x49); //"01 001 001" 第2行地址</p><p> lcd_wdat(0x1b); //"XXX 11011" 第2行數(shù)據(jù)</p><p> lcd_wcmd(0x4a); //"01 001 010" 第3行地址</p>&
77、lt;p> lcd_wdat(0x1d); //"XXX 11101" 第3行數(shù)據(jù)</p><p> lcd_wcmd(0x4b); //"01 001 011" 第4行地址</p><p> lcd_wdat(0x19); //"XXX 11001" 第4行數(shù)據(jù)</p><p> lcd_
78、wcmd(0x4c); //"01 001 100" 第5行地址</p><p> lcd_wdat(0x1d); //"XXX 11101" 第5行數(shù)據(jù)</p><p> lcd_wcmd(0x4d); //"01 001 101" 第6行地址</p><p> lcd_wdat(0x1b);
79、//"XXX 11011" 第6行數(shù)據(jù)</p><p> lcd_wcmd(0x4e); //"01 001 110" 第7行地址</p><p> lcd_wdat(0x01); //"XXX 00001" 第7行數(shù)據(jù)</p><p> lcd_wcmd(0x4f); //"01 001
80、 111" 第8行地址</p><p> lcd_wdat(0x00); //"XXX 00000" 第8行數(shù)據(jù)</p><p><b> }</b></p><p> //LCD初始化設(shè)定</p><p> void lcd_init()</p><p>
81、<b> { </b></p><p> lcd_wcmd(0x38); //設(shè)置LCD為16X2顯示,5X7點陣,八位數(shù)據(jù)借口</p><p><b> delay(1);</b></p><p> lcd_wcmd(0x0c); //LCD開顯示及光標(biāo)設(shè)置(光標(biāo)不閃爍,不顯示"-&quo
82、t;)</p><p><b> delay(1);</b></p><p> lcd_wcmd(0x06); //LCD顯示光標(biāo)移動設(shè)置(光標(biāo)地址指針加1,整屏顯示不移動)</p><p><b> delay(1);</b></p><p> lcd_wcmd(0x01); //清除
83、LCD的顯示內(nèi)容</p><p><b> delay(1);</b></p><p><b> }</b></p><p><b> //閏年的計算</b></p><p> bit leap_year()</p><p><b>
84、 {</b></p><p><b> bit leap;</b></p><p> if((year%4==0&&year%100!=0)||year%400==0)//閏年的條件</p><p><b> leap=1;</b></p><p><b>
85、; else</b></p><p><b> leap=0;</b></p><p> return leap;</p><p><b> }</b></p><p> //星期的自動運算和處理</p><p> unsigned char week
86、_proc()</p><p> { unsigned char num_leap; </p><p> unsigned char c;</p><p> num_leap=year/4-year/100+year/400;//自00年起到y(tǒng)ear所經(jīng)歷的閏年數(shù)</p><p> if( leap_year()&&
87、month<=2 ) //既是閏年且是1月和2月 </p><p><b> c=5;</b></p><p><b> else </b></p><p><b> c=6;</b></p><p> week=(year+para_month[month]
88、+date+num_leap+c)%7;//計算對應(yīng)的星期</p><p> return week;</p><p><b> }</b></p><p><b> //更新顯示緩沖區(qū)</b></p><p> void update_disbuf(unsigned char t1,uns
89、igned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s) </p><p> { dis_buf1[0]=t1; //</p><p> dis_buf1[1]=0x20; //空格</p><p> dis_buf1[2]=50; //'
90、2' </p><p> dis_buf1[3]=48; //'0'</p><p> dis_buf1[4]=year/10+48; </p><p> dis_buf1[5]=year%10+48; </p><p> dis_buf1[6]=0x2d;</p><
91、;p> dis_buf1[7]=month/10+48;</p><p> dis_buf1[8]=month%10+48; </p><p> dis_buf1[9]=0x2d; //'-'</p><p> dis_buf1[10]=date/10+48;</p><p> dis_buf1[11]=
92、date%10+48;</p><p> dis_buf1[12]=0x20;</p><p> dis_buf1[13]=dis_week[4*week];</p><p> dis_buf1[14]=dis_week[4*week+1];</p><p> dis_buf1[15]=dis_week[4*week+2];</
93、p><p> dis_buf2[0]=t2[0]; </p><p> dis_buf2[1]=t2[1]; </p><p> dis_buf2[2]=t2[2]; </p><p> dis_buf2[3]=t2[3];</p><p> dis_buf2[4]=t2[4]; </p><
94、p> dis_buf2[5]=t2[5];</p><p> dis_buf2[6]=0x20; //空格</p><p> if (alarm)</p><p> dis_buf2[7]=0x01; //alarm=1,顯示鬧鐘啟用標(biāo)致(第二個自定義字符)</p><p><b> else</b>
95、;</p><p> dis_buf2[7]=0x20; //alarm=0,不顯示鬧鐘啟用標(biāo)致</p><p> dis_buf2[8]=dis_h/10+48; </p><p> dis_buf2[9]=dis_h%10+48; </p><p> dis_buf2[10]=0x3a; //':'</
96、p><p> dis_buf2[11]=dis_m/10+48;</p><p> dis_buf2[12]=dis_m%10+48;</p><p> dis_buf2[13]=0x3a;</p><p> dis_buf2[14]=dis_s/10+48;</p><p> dis_buf2[15]=dis_
97、s%10+48;</p><p><b> }</b></p><p> //時間和日期處理程序</p><p> void pro_timedate()</p><p><b> { </b></p><p><b> sec++;</b>&
98、lt;/p><p> if(sec > 59)</p><p><b> {sec = 0;</b></p><p><b> min++;</b></p><p> if(min>59)</p><p><b> {min=0;</b>
99、;</p><p><b> hour++;</b></p><p> if(hour>23)</p><p><b> {hour=0;</b></p><p><b> date++;</b></p><p> if (month==
100、1||month==3||month==5||month==7||month==8||month==10||month==12)</p><p> if (date>31) {date=1;month++;} //大月31天</p><p> if (month==4||month==6||month==9||month==11) </p><p&g
101、t; if (date>30) {date=1;month++;} //小月30天</p><p> if (month==2) </p><p> {if( leap_year()) //閏年的條件</p><p> {if (date>29) {date=1;month++;}} //閏年2月為29天</p
102、><p><b> else</b></p><p> {if (date>28) {date=1;month++;}} //平年2月為28天 </p><p><b> } </b></p><p> if (month>12) {month=1;year++;}<
103、/p><p> if (year>99) year=0;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> week_proc();</p>&l
104、t;p> if (sec==armsec && min==armmin && hour==armhour) </p><p> {if (alarm)</p><p> TR1=1; //鬧鐘啟用時,報警時間到,啟動Timer1</p><p><b> }</b></p>
105、<p><b> }</b></p><p><b> //顯示處理程序</b></p><p> void pro_display()</p><p> { unsigned char i;</p><p> lcd_pos(0x00);</p><p&
106、gt; for (i=0;i<=15;i++)</p><p> {lcd_wdat(dis_buf1[i]);}</p><p> lcd_pos(0x40);</p><p> for (i=0;i<=15;i++)</p><p> {lcd_wdat(dis_buf2[i]);}</p><p
107、><b> }</b></p><p> //Timer0中斷處理程序,秒的產(chǎn)生</p><p> void timer0() interrupt 1 </p><p><b> {</b></p><p> TH0=0xdc; //Timer0置10ms定時初值dc00H(2^
108、16=65536D,dc00H=56320D)</p><p> TL0=0x00; //定時時間=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)</p><p><b> sec100++;</b></p><p> if(sec100 >= 100) //1秒時間 (100
109、*10ms=1000ms=1s)</p><p> {sec100 = 0;</p><p> pro_timedate();//調(diào)用時間和日期處理程序</p><p><b> }</b></p><p> if (sec&0x01) // 一秒顯示“hello”,一秒顯示“kitty
110、”</p><p> update_disbuf(0x00,"KITTY",hour,min,sec); //0x00表示顯示00位置的自定義字符 </p><p><b> else </b></p><p> update_disbuf(0x00,"HELLO",hour,min,sec
111、); </p><p> pro_display(); //調(diào)用顯示處理函數(shù)</p><p><b> } </b></p><p><b> //按鍵掃描程序</b></p><p> unsigned char scan_key()</p><p><b
112、> { </b></p><p> skey=0x00; //給變量vkey置初值</p><p> skey|=PRE; //讀取PRE鍵的狀態(tài)</p><p> skey=skey<<1; //將PRE鍵的狀態(tài)存于skey的B1位</p><p> sk
113、ey|=SET; //讀取SET鍵的狀態(tài),并存于skey的B0位</p><p> return skey; //返回skey的鍵值(即PRE,SET的狀態(tài))</p><p><b> }</b></p><p> //外部中斷INT0中斷處理程序</p><p> void int
114、0() interrupt 0 </p><p><b> { </b></p><p> TR0=0; //禁止Timer0</p><p> IE=0; //禁止中斷</p><p> lcd_wcmd(0x0e); //顯示光標(biāo)"_",整個光
115、標(biāo)不閃爍</p><p><b> alarm=1;</b></p><p> update_disbuf(0x50,"alarm:",armhour,armmin,armsec); //更新顯示數(shù)據(jù),0x50表示要顯示"P" </p><p> pro_display(); //調(diào)用顯
116、示處理程序</p><p> lcd_pos(0x47); //使光標(biāo)位于第一個調(diào)整項下 </p><p> flag=0; </p><p> vkey=0x03;</p><p> while(flag^0x0a)</p><p> {skey = scan_k
117、ey(); //掃描按鍵狀態(tài)</p><p> if (skey^vkey) //若skey與vkey相同,跳出循環(huán),相異執(zhí)行循環(huán)體</p><p> { delay(10); //去按鍵抖動 </p><p> skey = scan_key(); //轉(zhuǎn)回掃描按鍵狀態(tài) </p><p> if (
118、skey^vkey) //若skey與vkey相同,跳出循環(huán),相異執(zhí)行循環(huán)體 </p><p> { vkey=skey; //將skey的值付給vkey </p><p> if (skey==0x01) //PRE鍵按下</p><p> { flag++; //調(diào)整標(biāo)志位加1 </p><p> switch (
119、flag) //將光標(biāo)置于相應(yīng)調(diào)整位置</p><p><b> { </b></p><p> case 1: lcd_pos(0x49);break; //光標(biāo)置小時報警設(shè)置位置 </p><p> case 2: lcd_pos(0x4c);break; //光標(biāo)置分鐘報警設(shè)置位置 </p>&
120、lt;p> case 3: lcd_pos(0x4f);break; //光標(biāo)置秒時報警設(shè)置位置</p><p> case 4: update_disbuf(0x50,"time: ",hour,min,sec);</p><p> pro_display();</p><p> lcd_pos(0x05);break; //
121、光標(biāo)置年調(diào)整位置 </p><p> case 5: lcd_pos(0x08);break; //光標(biāo)置月調(diào)整位置</p><p> case 6: lcd_pos(0x0b);break; //光標(biāo)置日調(diào)整位置</p><p> case 7: lcd_pos(0x49);break; //光標(biāo)置時調(diào)整位置</p>
122、<p> case 8: lcd_pos(0x4c);break; //光標(biāo)置分調(diào)整位置</p><p> case 9: lcd_pos(0x4f);break; //光標(biāo)置秒調(diào)整位置</p><p> default:break;</p><p><b> }</b></p><p><
123、;b> }</b></p><p> if (skey==0x02) //SET鍵按下</p><p> { pro_key(); //轉(zhuǎn)設(shè)置按鍵處理程序</p><p><b> }</b></p><p><b> }</b></p><
124、;p> } </p><p> } </p><p> lcd_wcmd(0x0c); //設(shè)置LCD開顯示及光標(biāo)不閃爍,不顯示"-"</p><p> lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容</p><p> IE=0x8f;
125、 //CPU開中斷,INT0,INT1,開中斷</p><p> TR0=1; //Timer0啟動</p><p><b> }</b></p><p> //主程序,初始化及初值設(shè)定</p><p> void main()</p><p>&l
126、t;b> { </b></p><p> lcd_init(); //初始化LCD</p><p> lcd_sef_chr(); //寫入自定義字符號</p><p> hour=10;min=30;sec=0; //開機時的時,分,秒顯示</p><p
127、> armhour=10;armmin=29;armsec=0; //開機時的時,分,秒報警初值</p><p> year=11; month=5;date=9; //開機時的年,月,日,星期顯示</p><p> week_proc();</p><p> alarm=1; //初始開機,啟用鬧鐘</p>&
128、lt;p> IE = 0x8f; //CPU開中斷,INT0,INT1,Timer0,Timer1開中斷</p><p> IP = 0x04; //設(shè)置INT0為中斷最高優(yōu)先級</p><p> IT0=0;IT1=0; //外部INT0,INT1設(shè)置為電平觸發(fā)方式(注意,觸發(fā)不要選邊沿方式,易誤動)</p><p>
129、 TMOD = 0x11; //Timer0,Timer1工作于模式1, 16位定時方式</p><p> TH0 = 0xdc;TL0 = 0x00; //Timer0置10ms定時初值 </p><p> TH1 = 0xff;TL1 = 0x00; //Timer1置初值 </p><p> TR0 = 1; //
130、Timer0啟動</p><p><b> TR1 = 0;</b></p><p><b> SPK=0;</b></p><p><b> while(1);</b></p><p><b> }</b></p><p>
131、; //設(shè)置按鍵處理程序</p><p> void pro_key()</p><p><b> {</b></p><p> switch (flag)</p><p><b> { </b></p><p> case 0:alarm=!alarm; /
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單片機課程設(shè)計報告(萬年歷)
- 單片機課程設(shè)計--萬年歷
- 單片機萬年歷課程設(shè)計
- 單片機萬年歷課程設(shè)計
- 單片機課程設(shè)計-萬年歷
- 萬年歷單片機課程設(shè)計
- 單片機課程設(shè)計—電子萬年歷
- 單片機課程設(shè)計-電子萬年歷
- 單片機萬年歷課程設(shè)計 (2)
- 單片機課程設(shè)計-- 電子萬年歷
- 單片機課程設(shè)計—萬年歷[1]
- 單片機課程設(shè)計---萬年歷顯示設(shè)計
- 單片機課程設(shè)計---電子萬年歷設(shè)計
- 基于單片機的萬年歷課程設(shè)計
- 單片機課程設(shè)計報告----電子萬年歷的設(shè)計
- 1602數(shù)字萬年歷單片機課程設(shè)計
- 單片機課程設(shè)計--基于51單片機的萬年歷
- 課程設(shè)計--單片機簡易萬年歷的設(shè)計
- 單片機電子萬年歷課程設(shè)計
- 單片機電子萬年歷課程設(shè)計
評論
0/150
提交評論