

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、<p><b> 一、課程設(shè)計名稱</b></p><p><b> 萬年歷</b></p><p><b> 二、課程設(shè)計目的</b></p><p> 1、掌握單片機的原理、應(yīng)用。</p><p> 2、學會利用單片機設(shè)計電路。</p>&
2、lt;p> 3、培養(yǎng)大家的創(chuàng)新意識及動手能力。</p><p><b> 三、課程設(shè)計內(nèi)容</b></p><p><b> ?。ㄒ唬┓桨冈O(shè)計</b></p><p> 我們組設(shè)計的萬年歷是以一片40引腳的單片機AT89C52為主體,結(jié)合16位定時器/計數(shù)器和LED數(shù)碼管等元器件來實現(xiàn)的,主要有幾個單元電路構(gòu)成
3、,分別是復(fù)位電路、振蕩電路、按鍵電路、整點報時電路和顯示電路,下面給出了電路框圖及其分析和說明。</p><p> 1、復(fù)位電路 </p><p> 此單元電路為手動復(fù)位電路,由按鍵、電解電容、電阻等構(gòu)成,與單片機的RST引腳相連接,在單片機運行過程中可以隨時按鍵</p><p> 復(fù)位,電路圖如圖1所示:</p><p>&l
4、t;b> 圖-1 復(fù)位電路</b></p><p><b> 2、振蕩電路 </b></p><p> 此單元電路由晶振和電容構(gòu)成,其中的晶振頻率為12MHz,與單片機的XTAL1和XTAL2引腳相連接,具體電路如圖2所示: </p><p><b>
5、圖-2振蕩電路</b></p><p><b> 3、調(diào)整電路 </b></p><p> 此單元電路主要由多個彈性按鍵構(gòu)成,在所設(shè)計的電路中與單片機的I/O(P1)口相連接,具體電路可參考圖3:</p><p><b> 圖-3按鍵調(diào)整電路</b></p><p> 圖中的按鍵
6、K0、K1、K2、K3分別具有不同的功能,其中K0、K1、K2用于校準,K0調(diào)節(jié)小時(或年)、K1調(diào)節(jié)分(或月)、K2調(diào)節(jié)秒(或日);K3用于切換,啟動時萬年歷顯示的為時分秒,當按下K3時可以切換到年月日顯示界面。</p><p><b> 4、整點報時電路 </b></p><p> 此部分電路通過采用晶體管驅(qū)動蜂鳴器實現(xiàn)的,每當顯示時間出現(xiàn)整點時(如12:00
7、:00),蜂鳴器會發(fā)出短暫響聲,起到整點報時功能。實際電路中與單片機的P1.3相連接,具體電路可參照圖4:</p><p><b> 圖-4整點報時電路</b></p><p><b> 5、顯示電路</b></p><p> 此單元電路為萬年歷的顯示屏,由共陽數(shù)碼管構(gòu)成,采用動態(tài)掃描的方式來顯示年月日和時分秒,示意
8、圖如圖5所示:</p><p> 圖-5數(shù)碼管顯示電路</p><p> 注意:實際中電路與上述電路不同,稍復(fù)雜些,而且采用的是兩個四位一體的數(shù)碼管,還要接限流電阻(較小,如470歐)和晶體管(如9012)。</p><p><b> ?。ǘ┫到y(tǒng)硬件設(shè)計</b></p><p> 該系統(tǒng)主要由時鐘電路部分、中央處
9、理單元、數(shù)碼管顯示部分組成,各組成部分如圖所示。</p><p> 1、AT89C52結(jié)構(gòu)與工作原理</p><p> AT89C52是51系列單片機的一個型號,它是ATMEL公司生產(chǎn)的,是一個低電壓,高性能CMOS 8位單片機,片內(nèi)含8k bytes的可反復(fù)擦寫的Flash只讀程序存儲器和256 bytes的隨機存取數(shù)據(jù)存儲器(RAM),器件采用ATMEL公司的高密度、非易失性存儲技
10、術(shù)生產(chǎn),兼容標準MCS-51指令系統(tǒng),片內(nèi)置通用8位中央處理器和Flash存儲單元,功能強大的AT89C52單片機可為您提供許多較復(fù)雜系統(tǒng)控制應(yīng)用場合。</p><p> AT89C52有40個引腳,32個外部雙向輸入/輸出(I/O)端口,同時內(nèi)含2個外中斷口,3個16位可編程定時計數(shù)器,2個全雙工串行通信口,2個讀寫口線,AT89C52可以按照常規(guī)方法進行編程,但不可以在線編程(S系列的才支持在線編程)。其將
11、通用的微處理器和Flash存儲器結(jié)合在一起,特別是可反復(fù)擦寫的Flash存儲器可有效地降低開發(fā)成本。</p><p> 兼容MCS51指令系統(tǒng) · 8k可反復(fù)擦寫(>1000次)Flash ROM</p><p> · 32個雙向I/O口 · 256x8bit內(nèi)部RAM </p><p> · 3個16位可編程定時
12、/計數(shù)器中斷 · 時鐘頻率0-24MHz </p><p> · 2個串行中斷 · 可編程UART串行通道 </p><p> · 2個外部中斷源 · 共6個中斷源 </p><p> · 2個讀寫中斷口線 · 3級加密位 </p><p> · 低功耗空
13、閑和掉電模式 · 軟件設(shè)置睡眠和喚醒功能 </p><p> 40引腳雙列直插型AT89C52芯片引腳排列如右圖所示;該單片機為8 位通用微處理器,采用工業(yè)標準的C51內(nèi)核,在內(nèi)部功能及管腳排布上與通用的8xc52 相同,其主要用于會聚調(diào)整時的功能控制。功能包括對會聚主IC 內(nèi)部寄存器、數(shù)據(jù)RAM及外部接口等功能部件的初始化,會聚調(diào)整控制,會聚測試圖控制,紅外遙控信號IR的接收解碼及與主板CPU通信等
14、。主要管腳有:XTAL1(19 腳)和XTAL2(18 腳)為振蕩器輸入輸出端口,外接12MHz 晶振。RST/Vpd(9 腳)為復(fù)位輸入端口,外接電阻電容組成的復(fù)位電路。VCC(40 腳)和VSS(20 腳)為供電端口,分別接+5V電源的正負端。P0~P3 為可編程通用I/O 腳,其功能用途由軟件定義,下面詳細介紹一些引腳的主要功能:</p><p><b> ●P0 口</b><
15、/p><p> P0 口是一組8 位漏極開路型雙向I/O 口, 也即地址/數(shù)據(jù)總線復(fù)用口。作為輸出口用時,每位能吸收電流的方式驅(qū)動8 個TTL邏輯門電路,對端口P0 寫“1”時,可作為高阻抗輸入端用,其結(jié)構(gòu)圖如圖6所示</p><p> 圖-6 P0口的一位結(jié)構(gòu)圖</p><p> 在訪問外部數(shù)據(jù)存儲器或程序存儲器時,這組口線分時轉(zhuǎn)換地址(低8 位)和數(shù)據(jù)總線復(fù)用
16、,在訪問期間激活內(nèi)部上拉電阻。</p><p> 在Flash 編程時,P0 口接收指令字節(jié),而在程序校驗時,輸出指令字節(jié),校驗時,要求外接上拉電阻。</p><p><b> ●P1 口</b></p><p> P1 是一個帶內(nèi)部上拉電阻的8 位雙向I/O 口, P1 的輸出緩沖級可驅(qū)動(吸收或輸出電流)4 個TTL 邏輯門電路。對端
17、口寫“1”,通過內(nèi)部的上拉電阻把端口拉到高電平,此時可作輸入口。作輸入口使用時,因為內(nèi)部存在上拉電阻,某個引腳被外部信號拉低時會輸出一個電流,其結(jié)構(gòu)圖如圖7所示:</p><p> 圖-7 P1口的一位結(jié)構(gòu)圖</p><p> 與AT89C51 不同之處是,P1.0 和P1.1 還可分別作為定時/計數(shù)器2 的外部計數(shù)輸入(P1.0/T2)和輸入(P1.1/T2EX),另外Flash 編
18、程和程序校驗期間,P1 接收低8 位地址。</p><p><b> ●P2 口</b></p><p> P2 是一個帶有內(nèi)部上拉電阻的8 位雙向I/O 口,P2 的輸出緩沖級可驅(qū)動(吸收或輸出電流)4 個TTL 邏輯門電路。對端口P2 寫“1”,通過內(nèi)部的上拉電阻把端口拉到高電平,此時可作輸入口,作輸入口使用時,因為內(nèi)部存在上拉電阻,某個引腳被外部信號拉低時會
19、輸出一個電流,其內(nèi)部結(jié)構(gòu)如圖8所示:</p><p> 圖-8 P2口的一位結(jié)構(gòu)圖</p><p> 在訪問外部程序存儲器或16 位地址的外部數(shù)據(jù)存儲器時,P2 口送出高8 位地址數(shù)據(jù)。在訪問8 位地址的外部數(shù)據(jù)存儲器時,P2 口輸出P2 鎖存器的內(nèi)容。Flash 編程或校驗時,P2亦接收高位地址和一些控制信號。</p><p><b> ●P3 口
20、</b></p><p> P3 口是一組帶有內(nèi)部上拉電阻的8 位雙向I/O 口。P3 口輸出緩沖級可驅(qū)動(吸收或輸出電流)4 個TTL 邏輯門電路。對P3口寫入“1”時,它們被內(nèi)部上拉電阻拉高并可作為輸入端口。此時,被外部拉低的P3 口將用上拉電阻輸出電流。P3口的內(nèi)部結(jié)構(gòu)如圖9所示:</p><p> 圖-9 P3口的一位結(jié)構(gòu)圖</p><p>
21、 P3 口除了作為一般的I/O 口線外,更重要的用途是它的第二功能,另外,P3 口還接收一些用于Flash 閃速存儲器編程和程序校驗的控制信號。</p><p> 表-1 P3口的第二功能</p><p><b> ●ALE/PROG</b></p><p> 當訪問外部程序存儲器或數(shù)據(jù)存儲器時,ALE(地址鎖存允許)輸出脈沖用于鎖存地
22、址的低8 位字節(jié)。一般情況下,ALE 仍以時鐘振蕩頻率的1/6 輸出固定的脈沖信號,因此它可對外輸出時鐘或用于定時目的。要注意的是:每當訪問外部數(shù)據(jù)存儲器時將跳過一個ALE 脈沖。對Flash 存儲器編程期間,該引腳還用于輸入編程脈沖(PROG)。如有必要,可通過對特殊功能寄存器(SFR)區(qū)中的8EH 單元的D0 位置位,可禁止ALE 操作。該位置位后,只有一條MOVX 和MOVC指令才能將ALE 激活。此外,該引腳會被微弱拉高,單片機
23、執(zhí)行外部程序時,應(yīng)設(shè)置ALE 禁止位無效。</p><p><b> ●PSEN</b></p><p> 程序儲存允許(PSEN)輸出是外部程序存儲器的讀選通信號,當AT89C52 由外部程序存儲器取指令(或數(shù)據(jù))時,每個機器周期兩次PSEN 有效,即輸出兩個脈沖。在此期間,當訪問外部數(shù)據(jù)存儲器,將跳過兩次PSEN信號。</p><p>
24、<b> ●XTAL1</b></p><p> 振蕩器反相放大器的及內(nèi)部時鐘發(fā)生器的輸入端。</p><p><b> ●XTAL2</b></p><p> 振蕩器反相放大器的輸出端。</p><p><b> 其振蕩方式有兩種;</b></p>&
25、lt;p> 內(nèi)部震蕩方式 外部震蕩方式</p><p><b> ●EA/VPP</b></p><p> 外部訪問允許。欲使CPU 僅訪問外部程序存儲器(地址為0000H—FFFFH),EA 端必須保持低電平(接地)。如EA端為高電平(接Vcc端),CPU 則執(zhí)行內(nèi)部程序存儲器中的指令。</p>&l
26、t;p><b> ●RST</b></p><p> 復(fù)位輸入。當振蕩器工作時,RST引腳出現(xiàn)兩個機器周期以上高電平將使單片機復(fù)位。常見的復(fù)位電路有以下三種方式:</p><p> (a)上電復(fù)位 (b)按鍵電平復(fù)位 (c)按鍵脈沖復(fù)位</p><p> 在此次設(shè)計中,我們組設(shè)計的電路采用的為第二種復(fù)位方式,即按鍵電
27、平復(fù)位,以便在調(diào)試中隨時進行手動復(fù)位。</p><p> 2、四位一體共陽數(shù)碼管的結(jié)構(gòu)及工作原理</p><p> 在介紹四位一體數(shù)碼管之前,先簡單介紹下單個七段LED數(shù)碼管的結(jié)構(gòu)及其工作原理,內(nèi)部結(jié)構(gòu)及引腳圖如下圖所示:</p><p> (a)共陰極數(shù)碼管 (b)共陽極數(shù)碼管 (c)一位數(shù)碼管的管腳配置</p>&
28、lt;p> 上圖(a)中,共陰極的數(shù)碼管的發(fā)光二極管陰極公共端接地,當某個發(fā)光二極管的陽極為高電平時,放光二極管點亮;共陽極的數(shù)碼管的發(fā)光二極管陽極并聯(lián),如上圖(b)所示。</p><p> 通常的七段數(shù)碼管中有八個發(fā)光二極管,故也有人叫做八段數(shù)碼管。其中七個發(fā)光二極管構(gòu)成七筆字形“8”,一個發(fā)光二極管構(gòu)成小數(shù)點。</p><p> 數(shù)碼管與單片機接口簡單,只要講一個8位并行輸
29、出口與顯示塊的發(fā)光二極管引腳相連即可。8位并行輸出口輸出不同的字節(jié)數(shù)據(jù)可獲得不同的數(shù)字或字符。見表-2。通常將控制發(fā)光二極管的8位字節(jié)數(shù)據(jù)稱為段選碼。共陽極與共陰極的段選碼互為補嗎。</p><p> 在實際使用數(shù)碼管時,要分清極性,因為數(shù)碼管的極性不同,其段選碼也不同,而段選碼也決定了其顯示的字符。</p><p> 表-2 七段LED數(shù)碼管段選碼</p><p&
30、gt;<b> 數(shù)碼管的顯示方式</b></p><p> 數(shù)碼管的顯示方式可分為兩種,即靜態(tài)顯示方式和動態(tài)顯示方式,下面分別加以介紹。</p><p><b> ?。?)靜態(tài)顯示方式</b></p><p> LED顯示器工作在靜態(tài)顯示方式下,共陰極點或共陽極點連接在一起接地或+5V;每位LED顯示塊的段選線(a~
31、dp)與一個8位并行口相連。</p><p> 靜態(tài)顯示有并行輸出和串行輸出兩種方式。下面給出并行輸出的一種電路連接,如圖-10所示</p><p> 圖-10 并行輸出靜態(tài)顯示電路</p><p> 該圖表示了一個三位靜態(tài)數(shù)碼管電路,每一位數(shù)碼管可獨立顯示,只要在該位的段選線上保持段選碼電平,該位就能保持相應(yīng)的顯示字符。由于每一位由一個8位輸出口控制段選碼,
32、故在同一時間內(nèi)每一位新字符可以各不相同。</p><p> ?。?)動態(tài)顯示方式 </p><p> 將多個數(shù)碼管所有位的段選碼并聯(lián)在一起,由一個8位I/O口控制,而共陰極點或共陽極點分別由相應(yīng)的I/O口線控制。由于各位的段選線并聯(lián),段選碼的輸出對各位來說都是相同的。因此,同一時刻,如果各位位選線都處于選通狀態(tài)時,8位LED數(shù)碼管將顯示相同的字符。若要各位LED數(shù)碼管能夠顯示出與本位相同
33、的顯示字符,就必須采用掃描顯示方式,即在某一時刻,只讓某一位的位選線處于選通狀態(tài),而其他各位的位選線處于關(guān)閉狀態(tài),同時,段選線上輸出相應(yīng)位要顯示字符的字形碼,這樣同一時刻,8位LED數(shù)碼管中只有選通的那一位顯示出字符,而其他7位則是熄滅的。同樣,在下一時刻, 只讓第二位的位選線處于選通狀態(tài),而其他各位的位選線處于關(guān)閉狀態(tài),,同時,在段選線上輸出相應(yīng)位將要顯示字符的字形碼,則同一時刻,只有選通位顯示出相應(yīng)的字符,而其他各位則是熄滅的。如此
34、循環(huán)下去,就可以使各位顯示出將要顯示的字符。雖然這些字符是在不同時刻出現(xiàn)的,而且同一時刻,只有一位顯示,其他各位熄滅,但由于人眼有視覺暫留現(xiàn)象,只要每位顯示間隔一般為1~4ms之間,則可造成多位同時亮的假象,達到同時顯示的目的。</p><p> 以上就是動態(tài)顯示的工作原理,多位數(shù)碼管的構(gòu)成則是利用此原理,采用動態(tài)掃描進行顯示。下面開始介紹四位一體共陽數(shù)碼管,也是我組設(shè)計的萬年歷中用到的顯示器件,其引腳圖如圖-
35、11所示;</p><p> 圖-11四位一體共陽數(shù)碼管引腳圖</p><p> 圖中的G1、G2、G3、G4引腳為位選端,依次控制第一、第二、第三、第四個(從左到右)數(shù)碼管。設(shè)計中采用了兩個這種四位一體的數(shù)碼管,用來顯示時分秒(或年月日),用P0.0—P0.7作為數(shù)碼管的控制信號(段選信號),中間通過限流電阻連接,由于P0作為輸出,還應(yīng)該加上拉電阻;用P2.0—P2.7作為數(shù)碼管的位
36、選信號, 外接三極管電路,具體連接參見附錄2中的原理圖部分。</p><p><b> 3、元件清單</b></p><p> 元器件名稱 數(shù)量</p><p> AT89C52………………………………………….……….1</p><p> 四位
37、一體共陽數(shù)碼管…………………………………….2</p><p> 蜂鳴器…………………………………………………….1</p><p> PNP型三極管9012………………………………………9</p><p> 電解電容10u……………………………………………..1</p><p> 瓷片電容30p……………………………………………..
38、2</p><p> 排阻10k………………………………………………..…1</p><p> 電阻470……………………………………………………9</p><p> 電阻10k……………………………………………………1</p><p> 電阻1k……………………………………………………..9</p><p>
39、 按鍵開關(guān)…………………………………………………...5</p><p> 晶振12MHz………………………………………………..1</p><p> (三)系統(tǒng)軟件設(shè)計 </p><p> 軟件設(shè)計是一個將需求轉(zhuǎn)變?yōu)檐浖愂龅倪^程,也是設(shè)計中的核心部分,程序設(shè)計的好壞直接決定了硬件電路的功能是否能夠?qū)崿F(xiàn)及其功能的差異。 </p><
40、p> 系統(tǒng)的軟件設(shè)計主要是通過編寫程序?qū)崿F(xiàn)的,此次設(shè)計中我們用的是C語言來編寫的程序。</p><p> C語言是源于編寫UNIX操作系統(tǒng)的一種語言,是一種結(jié)構(gòu)化程序設(shè)計語言,產(chǎn)生的代碼緊湊,可以深入到機器內(nèi)部編程,具備若干匯編語言所具有的特點,又優(yōu)于匯編語言。51C程序結(jié)構(gòu)與一般C語言程序結(jié)構(gòu)并沒有本質(zhì)上的差別,也是只有一個主函數(shù)和若干函數(shù)組成。在51C的頭文件中有其庫函數(shù)的說明,可以通過includ
41、e預(yù)處理指令將頭文件包含在自己的文件中即可調(diào)用。每個函數(shù)的定義及調(diào)用規(guī)則基本上與一般的C一樣,實際上51C程序的設(shè)計過程也就是一系列函數(shù)的定義過程。盡管51C與一般C程序設(shè)計方法基本相同,但畢竟是針對單片機及其硬件系統(tǒng)所進行的程序設(shè)計,與常規(guī)意義上的C編程有所區(qū)別。在進行程序設(shè)計時,必需注意以下幾個問題。</p><p> 存儲區(qū)的定位及訪問。必須了解編譯器的數(shù)據(jù)類型以及與51單片機存儲器結(jié)構(gòu)的對應(yīng)關(guān)系,編譯器
42、定義的任何數(shù)據(jù)類型必須以一定的存儲類型方式定位在單片機的某一存儲區(qū)中,否則沒有任何實際意義。</p><p> 特殊功能寄存器的訪問。對于片內(nèi)特殊功能寄存器SFR 的訪問,編譯器都提供了專門的方法,這些方法與一般C語言是不兼容的,只適用于單片機C編程。</p><p> 并行接口的定義。51單片機有4個8位并行口,共32條I/O線,這是大家熟知的,這4 個口原則上都可以作為I/O使用,
43、只是在需要外部總線擴展時,才將P0用作數(shù)據(jù)低地址總線, P2用作高地址總線。除此之外,還可以在片外擴展硬件I/O口。51單片機沒有專用的I/O指令,所有口地址與數(shù)據(jù)存儲器地址時是統(tǒng)一編址的。</p><p> 說明:具體的C源程序參見附錄1-源程序部分。</p><p> (四)仿真與調(diào)試 </p><p> 我們將設(shè)計好的電路在Proteus編譯環(huán)境中進行
44、仿真,并結(jié)合Keil軟件進行聯(lián)調(diào),經(jīng)過多次修改與編譯程序最終得到了預(yù)期的結(jié)果,達到了預(yù)先的設(shè)計要求。</p><p> 在Proteus環(huán)境下啟動仿真,得到如下的仿真效果圖:</p><p> Proteus仿真圖</p><p> 在我們的設(shè)計中,設(shè)置了一個切換按鍵K3,用于在時分秒和年月日界面間進行切換,并設(shè)有調(diào)整按鍵K0、K1、K2,具體的按鍵功能參見前
45、面的“課程設(shè)計方案”部分中的“調(diào)整電路”。</p><p> 四、課程設(shè)計心得體會</p><p><b> 心得體會</b></p><p> 通過這次萬年歷的課程設(shè)計,加深了我們對51單片機認識,對其基本結(jié)構(gòu)及工作原理有了進一步的認識。同時,這次設(shè)計也是對所學知識的一次實際應(yīng)用,提高了我們的動手能力,收獲頗多。</p>
46、<p> 在這次設(shè)計中,運用到了許多以前學過的知識,是對所學知識的一次靈活運用。在程序設(shè)計之前,首先要對單片機的內(nèi)部結(jié)構(gòu)有一個系統(tǒng)的了解,這樣便于在設(shè)計中形成一個清晰的思路。在此次設(shè)計中,程序的設(shè)計部分是最為不易的,費了我們不少心思,不過令我們感到欣慰的是,程序經(jīng)過反復(fù)的修改和調(diào)試,最終達到了預(yù)期的要求。對于軟件仿真,在繪圖時,應(yīng)特別注意單片機端口和數(shù)碼管的段選、位選的連接,下載程序仿真演示時仔細觀察接線端口的電平變化,操作
47、各功能鍵,觀察功能鍵演示結(jié)果,并結(jié)合程序進行適當調(diào)整,以使仿真效果達到預(yù)期結(jié)果。對于實物焊接,由于之前進行過不止一次的課程設(shè)計,所以這部分相對較容易,但應(yīng)特別注意數(shù)碼管的引腳所對應(yīng)的段選、位選。課程設(shè)計過程中也難免的遇到了一些問題,但經(jīng)過我們不懈的努力,最終設(shè)計成功了我組的萬年歷,并達到了預(yù)期的目標。</p><p> 總之,這次單片機課程設(shè)計,讓我們認識到了理論聯(lián)系實際的重要性, 在培養(yǎng)我們創(chuàng)新意識的同時,也
48、提高了大家發(fā)現(xiàn)并解決問題的能力,這些都將成為我們今后學習和工作中的一筆寶貴財富。 </p><p><b> 附錄1</b></p><p><b> 源程序</b></p><p> #include<reg51.h>//頭文件命令</p><p> #define u
49、char unsigned char//宏定義</p><p> #define uint unsigned int //宏定義</p><p> sbit P1_3=P1^3;//定義P1_3</p><p> sbit K3=P1^4;//定義按鍵</p><p> sbit K0=P1^5;<
50、;/p><p> sbit K1=P1^6;</p><p> sbit K2=P1^7;</p><p> uchar Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,</p><p> 0xf8,0x80,0x90}; // 定義數(shù)組Tab[],即共陽數(shù)碼管0~9的段選碼</p>
51、<p> uint pd[ ]={60,91,121,151,182,213,244,274,305,335,366}; //定義有關(guān)閏年天數(shù)的數(shù)組pd[]</p><p> uint pd0[ ]={0,31,60,91,121,151,182,213,244,274,305,335,366};</p><p> uchar int_time ,t,k,n; /
52、/定義中斷變量次數(shù)變量int_time 及變量t,k,n</p><p> uchar second,minute,hour; //定義秒、分、時變量</p><p> uchar date,month,year;//定義日、月、年變量</p><p> uint year0,day,maxday; //定義year0變量,天數(shù)變量day,最
53、大天數(shù)變量maxday</p><p> void delay(void) //定義延時函數(shù)delay ,延時約0.6ms</p><p><b> {</b></p><p> unsigned char j;</p><p> for(j=0;j<200;j++);</p>
54、<p><b> }</b></p><p> void delayms() //定義延時函數(shù)delayms,,用于按鍵消抖</p><p> {unsigned char i,j;</p><p> for(i=0;i<50;i++)</p><p> for(j=0;j<30;
55、j++);}</p><p> void DisplaySecond(unsigned char s) //定義秒顯示函數(shù),也用來顯示日</p><p><b> {</b></p><p> P2=0xfd; //顯示秒(或日)十位</p><p> P0=Tab[s/10];
56、 </p><p><b> delay();</b></p><p> P2=0xfe; //顯示秒(或日)個位</p><p> P0=Tab[s%10]; </p><p><b> delay();</b></p>
57、<p> P2=0xff; //關(guān)閉所有數(shù)碼管</p><p><b> }</b></p><p> void DisplayMinute(unsigned char m) //定義分顯示函數(shù),也用來顯示月</p><p><b> {</b></p><p
58、> P2=0xef; //顯示分(或月)十位</p><p> P0=Tab[m/10];</p><p><b> delay();</b></p><p> P2=0xf7; //顯示分(或月)個位</p><p> P0=Tab[m%10];</p><p&
59、gt;<b> delay();</b></p><p> P2=0xfb; //顯示分隔符</p><p> P0=0xbf; </p><p><b> delay();</b></p><p> P2=0xff; //關(guān)閉所有數(shù)碼管</p>
60、<p><b> }</b></p><p> void DisplayHour(unsigned char h)//定義小時顯示函數(shù),也用來顯示年</p><p><b> {</b></p><p> P2=0x7f; //顯示時(或年)十位</p>&l
61、t;p> P0=Tab[h/10]; </p><p><b> delay();</b></p><p> P2=0xbf; //顯示時(或年)個位</p><p> P0=Tab[h%10]; </p><p> delay(); </p>
62、<p> P2=0xdf; //顯示分隔符</p><p> P0=0xbf; </p><p><b> delay();</b></p><p> P2=0xff; //關(guān)閉所有數(shù)碼管</p><p><b> }<
63、/b></p><p> void Display(uchar sd, uchar mm, uchar hy)//定義顯示函數(shù)Display,顯示時分秒或年月日</p><p> { DisplaySecond(sd); </p><p><b> delay();</b></p><p>
64、 DisplayMinute(mm); </p><p><b> delay();</b></p><p> DisplayHour(hy); </p><p> delay(); }</p><p> void main(void) //主函數(shù)</p><p
65、><b> {</b></p><p> TMOD=0x01; //使用定時器T0,工作在方式1</p><p> EA=1; //開總中斷</p><p> ET0=1; //允許T0中斷</p><p&g
66、t; TH0=(65536-46083)/256; //定時器高八位賦初值</p><p> TL0=(65536-46083)%256; //定時器低八位賦初值</p><p> TR0=1; //啟動定時器</p><p> int_time=0; //變量賦初值</p><p> se
67、cond=0; //顯示初始化</p><p> minute=58; </p><p><b> hour=19; </b></p><p> year0=2011;</p><p> day=321; </p><p><b> while(1
68、)</b></p><p> {if(n==2) ET0=0; //調(diào)整時關(guān)中斷</p><p> if(n>2) {ET0=1;n=0;} //調(diào)整后開中斷</p><p><b> if(K3==0)</b></p><p> {delayms(); //按鍵消抖</
69、p><p> if(K3==0) //確認K3按下</p><p> k=!k; n++; //k取反,n加1</p><p> while(K3==0)Display(date, month, year);//K3按下時顯示年月日</p><p><b> } </b></p><
70、p> if(k==0) //k=0時,即K3未按下 </p><p> { Display(second, minute, hour); //顯示時分秒</p><p> if((P1&0xe0)!=0xe0)//判斷K0、K1、K2中有無按鍵按下</p><p> {delayms();//按鍵消抖</p
71、><p> if((P1&0xe0)!=0xe0) //確認按鍵按下</p><p><b> { </b></p><p> if(K0==0) //K0按下,用于調(diào)整小時</p><p><b> {hour++;</b></p><p> if(h
72、our==24) hour=0; </p><p> while(K0==0)</p><p> Display(second, minute, hour);</p><p><b> }</b></p><p> if(K1==0)//K1按下,用于調(diào)整分鐘</p><p> {
73、 minute++;</p><p> if(minute==60) minute=0; </p><p> while(K1==0)</p><p> Display(second, minute, hour);</p><p><b> }</b></p><p> if(K2=
74、=0)//K2按下,用于調(diào)整秒</p><p> { second++;</p><p> if(second==60) second=0; </p><p> while(K2==0)</p><p> Display(second, minute, hour);</p><p><b>
75、}</b></p><p><b> }</b></p><p><b> }}</b></p><p> else{ //k!=0,即K3按下</p><p> Display(date, month, year); //顯示年月日</p><
76、;p> if((P1&0xe0)!=0xe0)//判斷K0、K1、K2是否按下</p><p> {delayms();//軟件消抖</p><p> if((P1&0xe0)!=0xe0) //確認按鍵按下</p><p><b> { </b></p><p> if(
77、K0==0) //K0按下,用于調(diào)整年</p><p><b> {year0++;</b></p><p> if(year0==9999) year0=0; </p><p> while(K0==0) </p><p> Display(date, month, year);</p>
78、<p><b> }</b></p><p> if(K1==0) //K1按下,用于調(diào)整月</p><p><b> {</b></p><p> day=day+pd0[month]- pd0[month-1]; </p><p> while(K1==0)<
79、;/p><p> Display(date, month, year);</p><p><b> }</b></p><p> if(K2==0)//K2按下,用于調(diào)整日</p><p><b> { day++;</b></p><p> while(K2=
80、=0)</p><p> Display(date, month, year);</p><p><b> }</b></p><p><b> }</b></p><p> }} </p><p><b> }</b></
81、p><p><b> }</b></p><p> void t0(void ) interrupt 1 using 1 //中斷函數(shù)</p><p><b> {</b></p><p> TH0=(65536-46083)/256; //定時器重新賦初值</p>
82、<p> TL0=(65536-46083)%256;</p><p> int_time++; //中斷次數(shù)加1</p><p> if(int_time==20) //如果中斷次數(shù)滿20次</p><p><b> {</b></p><p> int_time=0; //中斷變
83、量清零</p><p> second++; //秒變量加1</p><p><b> }</b></p><p> if(second==60) //秒變量計滿60</p><p><b> {</b></p><p> second=0; //秒
84、變量清零 </p><p> minute++; //分變量加1 </p><p><b> }</b></p><p> if(minute==60) //分變量計滿60</p><p><b> {</b></p><p> minute=0; //分變
85、量清零 </p><p> hour++; //小時變量加1 </p><p><b> }</b></p><p> if(hour==24) //小時變量計滿24</p><p><b> { </b></p><p> hour=0;//小時變量清
86、零</p><p> day++; //天變量加1 </p><p><b> }</b></p><p> if(minute==0&&second==0)P1_3=0;//整點報時</p><p> else P1_3=1;</p><p> if(day>
87、;=366+!t)day=date; //保證一年天數(shù)<=366 </p><p> if((year0%4==0&&year0%100!=0)||(year0%400==0)){maxday=366;t=0;} //判斷閏年</p><p> else {maxday=365;t=1;}</p>&
88、lt;p> if(0<day&&day<=31){month=1;date=day;} //年月日顯示的計算</p><p> if(31<day&&day<=pd[0]-t){month=2;date=day-31;}</p><p> if(pd[0]-t<day&&day<=pd[
89、1]-t){month=3;date=day-pd[0]+t;}</p><p> if(pd[1]-t<day&&day<=pd[2]-t){month=4;date=day-pd[1]+t;}</p><p> if(pd[2]-t<day&&day<=pd[3]-t){month=5;date=day-pd[2]+t;}&l
90、t;/p><p> if(pd[3]-t<day&&day<=pd[4]-t){month=6;date=day-pd[3]+t;}</p><p> if(pd[4]-t<day&&day<=pd[5]-t){month=7;date=day-pd[4]+t;}</p><p> if(pd[5]-t<
91、;day&&day<=pd[6]-t){month=8;date=day-pd[5]+t;}</p><p> if(pd[6]-t<day&&day<=pd[7]-t){month=9;date=day-pd[6]+t;}</p><p> if(pd[7]-t<day&&day<=pd[8]-t){mon
92、th=10;date=day-pd[7]+t;}</p><p> if(pd[8]-t<day&&day<=pd[9]-t){month=11;date=day-pd[8]+t;}</p><p> if(pd[9]-t<day&&day<=pd[10]-t){month=12;date=day-pd[9]+t;}</p&
93、gt;<p> if(day>=maxday+1){year++;day=1;}</p><p> year=year0%100; //year0求余,用于數(shù)碼管顯示</p><p><b> }</b></p><p><b> 附錄2</b></p><p>&
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單片機萬年歷課程設(shè)計
- 單片機萬年歷課程設(shè)計
- 單片機課程設(shè)計-萬年歷
- 萬年歷單片機課程設(shè)計
- 單片機課程設(shè)計—電子萬年歷
- 單片機萬年歷課程設(shè)計報告
- 單片機課程設(shè)計報告(萬年歷)
- 單片機課程設(shè)計-電子萬年歷
- 單片機萬年歷課程設(shè)計 (2)
- 單片機課程設(shè)計-- 電子萬年歷
- 單片機課程設(shè)計—萬年歷[1]
- 單片機課程設(shè)計---萬年歷顯示設(shè)計
- 單片機課程設(shè)計---電子萬年歷設(shè)計
- 基于單片機的萬年歷課程設(shè)計
- 1602數(shù)字萬年歷單片機課程設(shè)計
- 單片機課程設(shè)計--基于51單片機的萬年歷
- 課程設(shè)計--單片機簡易萬年歷的設(shè)計
- 單片機電子萬年歷課程設(shè)計
- 單片機電子萬年歷課程設(shè)計
- 單片機電子萬年歷課程設(shè)計
評論
0/150
提交評論