版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
設(shè)計(jì)要求:一.設(shè)計(jì)一個基于單片機(jī)的智能電子時鐘,并且能夠?qū)崿F(xiàn)時分秒和年月日的實(shí)現(xiàn)和調(diào)節(jié)。二.設(shè)計(jì)出硬件電路;1.原理圖設(shè)計(jì)要符合項(xiàng)目的工作原理,連線要正確,端了要不得有標(biāo)號。2.圖中所使用的元器件要合理選用,電阻,電容等器件的參數(shù)要正確標(biāo)明。3.原理圖要完整,CPU,外圍器件,擴(kuò)器接口,輸入/輸出裝置要一應(yīng)俱全。三.設(shè)計(jì)出軟件編程方法,并寫出源代碼;1.根據(jù)要求,將總體項(xiàng)能分解成若干個子功能模塊,每個功能模塊完成一個特定的功能。2.根據(jù)總體要求及分解的功能模塊,確定各功能模塊之間的關(guān)系,設(shè)直出完整的程序流程圖。3.利用查表,中斷等方式實(shí)現(xiàn)目的。4.系統(tǒng)的各各功能模塊要清楚,有序。四.程序運(yùn)行時有友好的用戶界面.摘要單片計(jì)算機(jī)即單片微型計(jì)算機(jī)。由RAM,ROM,CPU構(gòu)成,定時,計(jì)數(shù)和多種接口于一體的微控制器。它體積小,成本低,功能強(qiáng),廣泛應(yīng)用于智能產(chǎn)業(yè)和工業(yè)自動化上。而51系列單片機(jī)是各單片機(jī)中最為典型和最有代表性的一種。這次課程設(shè)計(jì)通過對它的學(xué)習(xí),應(yīng)用,從而達(dá)到學(xué)習(xí)、設(shè)計(jì)、開發(fā)軟、硬的能力。本設(shè)計(jì)主要設(shè)計(jì)了一個基于AT89C52單片機(jī)的電子時鐘。并在1602上顯示相應(yīng)的時間。并通過一個控制鍵用來實(shí)現(xiàn)時間的調(diào)節(jié)和是否進(jìn)入省電模式的轉(zhuǎn)換。具有時鐘和日歷的功能,時鐘依賴時、分、秒寄存器來跟蹤,具有鬧鐘功能,日歷依賴日期、星期、月和年寄存器來跟蹤,日歷可正確通過2099年,具有自動閏年修正。
關(guān)鍵字:單片機(jī);子時鐘;鍵盤控制;LCD1602。目錄摘要-------------------------------------------------------------1單片機(jī)的相關(guān)知識---------------------------------------------51.1單片機(jī)的簡介----------------------------------------------------51.2單片機(jī)的特點(diǎn)----------------------------------------------------61.3AT89C52單片機(jī)的基本特點(diǎn)----------------------------------------62電子時鐘-------------------------------------------------------72.1電子時鐘的基本特點(diǎn)----------------------------------------------72.2電子時鐘的原理--------------------------------------------------83控制系統(tǒng)的硬件設(shè)計(jì)-------------------------------------------83.1單片機(jī)型號的選擇------------------------------------------------83.2lcd1602工作的原理-----------------------------------------------83.3鍵盤電路的設(shè)計(jì)--------------------------------------------------93.4整個電路的原理圖------------------------------------------------94控制系統(tǒng)的軟件的設(shè)計(jì)-----------------------------------------94.1程序的設(shè)計(jì)-----------------------------------------------------104.2程序流程圖-----------------------------------------------------11參考文獻(xiàn)---------------------------------------------------------11附錄-------------------------------------------------------------12實(shí)物圖像---------------------------------------------------------241單片機(jī)識的相關(guān)知識1.1單片機(jī)簡介MCS-51是INTEL公司在成功推廣的MCS-48單片機(jī)基礎(chǔ)上加以改進(jìn)而成的8位單片機(jī)。這種單片機(jī)大約是上世紀(jì)70年代末推出的,內(nèi)部程序可重寫的為8751,外擴(kuò)程序的是8031,一次性生產(chǎn),不可改變程序的是8051。外形一般為DIP40封裝。不久又推出了增強(qiáng)型的8052,其資源更加豐富。以后又采用CHMOS技術(shù)推出了80c51,耗電大大降低。到了90年代,INTEL公司把精力放到更賺錢的計(jì)算機(jī)上,將51單片機(jī)技術(shù)轉(zhuǎn)讓給了一此其它公司,如ATMELPhilips等半導(dǎo)體制造公司,使51系列單片機(jī)的市場份額不斷擴(kuò)大。盡管十多年前就有人認(rèn)為51單片機(jī)會很快淘汰,但事實(shí)證明51單片機(jī)經(jīng)過不斷的改進(jìn)后,由于技術(shù)成熟,使用方便,至今在8位單片機(jī)市場仍然擁有龐大的用戶。特別是MCS-51技術(shù)的20年專利期限到期后,大量的兼容型號不斷推出。從上世紀(jì)90年代后期開始,美國ATMEL公司在掌握快速擦寫的存儲器后,推出了AT89C系列,此系列在中國獲得了廣泛的應(yīng)用。在此之前,由于可擦寫的8751價格昂貴,國內(nèi)長時間采用8031+27C64這樣的外擴(kuò)存程序儲器方式。51單片機(jī)最初只有DIP40這種很古老的封裝,后來推出了CHMOS工藝的80C51后開始有了PLCC44這種相對較小的方形封裝。AT89C系列中開始有20腳的DIP20的精簡型封裝,這極大方便了在一些相對簡單的單片機(jī)應(yīng)用,縮小了PCB的體積。20腳的有AT89C1051、AT89C1051、AT89C1051,對應(yīng)程序存儲器分別為1K、2K、4K。標(biāo)準(zhǔn)的51為4K程序空間,128字節(jié)的RAM,32條端口,5個中斷,2個定時/計(jì)數(shù)器,12個時鐘周期執(zhí)行一條基本指令,最長的除法為48個周期。52為8K程序空間,256字節(jié)的RAM,32條端口,6個中斷,3個定時/計(jì)數(shù)器。AT89S51是可在板上直接下載程序的改進(jìn)型號,并增加了看門狗功能,AT89C51只能在編程器下寫入程序,所以經(jīng)常會有人在PCB上安裝IC插座,以便取下來編程更新程序。AT的51系列后來也推出了單周期的51,但價格沒什么優(yōu)勢,國內(nèi)很少使用。最近幾年宏晶在國內(nèi)大量推廣STC51系列單片機(jī),最近又推出不少所謂1T的單片機(jī),價格較低STC采用串口直接下載程序,寫入程序很方便。1.2單片機(jī)的特點(diǎn)1.單片機(jī)的存儲器ROM和RAM時嚴(yán)格區(qū)分的。ROM稱為程序存儲器,只存放程序,固定常數(shù),及數(shù)據(jù)表格。RAM則為數(shù)據(jù)存儲器,用作工作區(qū)及存放用戶數(shù)據(jù)。2.采用面向控制的指令系統(tǒng)。為滿足控制需要,單片機(jī)有更強(qiáng)的邏輯控制能力,特別是單片機(jī)具有很強(qiáng)的位處理能力。3.單片機(jī)的I/O口通常時多功能的。由于單片機(jī)芯片上引腳數(shù)目有限,為了解決實(shí)際引腳數(shù)和需要的信號線的矛盾,采用了引腳功能復(fù)用的方法,引腳處于何種功能,可由指令來設(shè)置或由機(jī)器狀態(tài)來區(qū)分。4.單片機(jī)的外部擴(kuò)展能力很強(qiáng)。在內(nèi)部的各種功能部件不能滿足應(yīng)用的需求時,均可在外部進(jìn)行擴(kuò)展,與許多通用的微機(jī)接口芯片兼容,給應(yīng)用系統(tǒng)設(shè)計(jì)帶來了很大的方便。1.389C52單片機(jī)介紹P0口:P0口為一個8位漏級開路雙向I/O口,每腳可吸收8TTL門電流。當(dāng)P1口的管腳第一次寫1時,被定義為高阻輸入。P0能夠用于外部程序數(shù)據(jù)存儲器,它可以被定義為數(shù)據(jù)/地址的第八位。在FIASH編程時,P0口作為原碼輸入口,當(dāng)FIASH進(jìn)行校驗(yàn)時,P0輸出原碼,此時P0外部必須被拉高。P1口:P1口是一個內(nèi)部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接收輸出4TTL門電流。P1口管腳寫入1后,被內(nèi)部上拉為高,可用作輸入,P1口被外部下拉為低電平時,將輸出電流,這是由于內(nèi)部上拉的緣故。在FLASH編程和校驗(yàn)時,P1口作為第八位地址接收。P2口:P2口為一個內(nèi)部上拉電阻的8位雙向I/O口,P2口緩沖器可接收,輸出4個TTL門電流,當(dāng)P2口被寫“1”時,其管腳被內(nèi)部上拉電阻拉高,且作為輸入。并因此作為輸入時,P2口的管腳被外部拉低,將輸出電流。這是由于內(nèi)部上拉的緣故。P2口當(dāng)用于外部程序存儲器或16位地址外部數(shù)據(jù)存儲器進(jìn)行存取時,P2口輸出地址的高八位。在給出地址“1”時,它利用內(nèi)部上拉優(yōu)勢,當(dāng)對外部八位地址數(shù)據(jù)存儲器進(jìn)行讀寫時,P2口輸出其特殊功能寄存器的內(nèi)容。P2口在FLASH編程和校驗(yàn)時接收高八位地址信號和控制信號。P3口:P3口管腳是8個帶內(nèi)部上拉電阻的雙向I/O口,可接收輸出4個TTL門電流。當(dāng)P3口寫入“1”后,它們被內(nèi)部上拉為高電平,并用作輸入。作為輸入,由于外部下拉為低電平,P3口將輸出電流(ILL)這是由于上拉的緣故。P3口也可作為AT89C52的一些特殊功能口,如下表所示:口管腳備選功能P3.0RXD(串行輸入口)P3.1TXD(串行輸出口)P3.2/INT0(外部中斷0)P3.3/INT1(外部中斷1)P3.4T0(記時器0外部輸入)P3.5T1(記時器1外部輸入)P3.6/WR(外部數(shù)據(jù)存儲器寫選通)P3.7/RD(外部數(shù)據(jù)存儲器讀選通)P3口同時為閃爍編程和編程校驗(yàn)接收一些控制信號。RST:復(fù)位輸入。當(dāng)振蕩器復(fù)位器件時,要保持RST腳兩個機(jī)器周期的高電平時間。ALE/PROG:當(dāng)訪問外部存儲器時,地址鎖存允許的輸出電平用于鎖存地址的地位字節(jié)。在FLASH編程期間,此引腳用于輸入編程脈沖。在平時,ALE端以不變的頻率周期輸出正脈沖信號,此頻率為振蕩器頻率的1/6。因此它可用作對外部輸出的脈沖或用于定時目的。然而要注意的是:每當(dāng)用作外部數(shù)據(jù)存儲器時,圖2.189C52單片機(jī)將跳過一個ALE脈沖。如想禁止ALE的輸出可在SFR8EH地址上置0。此時,ALE只有在執(zhí)行MOVX,MOVC指令是ALE才起作用。另外,該引腳被略微拉高。如果微處理器在外部執(zhí)行狀態(tài)ALE禁止,置位無效。PSEN:外部程序存儲器的選通信號。在由外部程序存儲器取指期間,每個機(jī)器周期兩次/PSEN有效。但在訪問外部數(shù)據(jù)存儲器時,這兩次有效的/PSEN信號將不出現(xiàn)。EA/VPP:當(dāng)/EA保持低電平時,則在此期間外部程序存儲(0000H-FFFFH),不管是否有內(nèi)部程序存儲器。注意加密方式1時,/EA將內(nèi)部鎖定為RESET;當(dāng)/EA端保持高電平時,此間內(nèi)部程序存儲器。在FLASH編程期間,此引腳也用于施加12V編程電源(VPP)。2.電子時鐘2.1電子時鐘的基本特點(diǎn)現(xiàn)在高精度的計(jì)時工具大多數(shù)都使用了石英晶體振蕩器,由于電子鐘、石英鐘、石英表都采用了石英技術(shù),因此走時精度高,穩(wěn)定性好,使用方便,不需要經(jīng)常調(diào)試,數(shù)字式電子鐘用集成電路計(jì)時時,譯碼代替機(jī)械式傳動,用用液晶顯示器代替指針顯示進(jìn)而顯示時間,減小了計(jì)時誤差,這種表具有時、分、秒顯示時間的功能,還可以進(jìn)行時和分的校對,片選的靈活性好。2.2電子時鐘的原理該電子時鐘由89C52,x1226實(shí)時時鐘器件,1602液晶等構(gòu)成,采用晶振電路作為驅(qū)動電路,由延時程序和循環(huán)程序產(chǎn)生的一秒定時,達(dá)到時分秒的計(jì)時,六十秒為一分鐘,六十分鐘為一小時,滿二十四小時為一天。而電路中唯一的一個控制鍵卻擁有多種不同的功能,按下又松開,可以實(shí)現(xiàn)屏蔽數(shù)碼管顯示的功能,達(dá)到省電的目的;直接按下不松開,則可以通過按鍵實(shí)現(xiàn)分鐘的累加,每按一次分鐘加一;而連續(xù)兩次按下按鍵不放松,則可實(shí)現(xiàn)小時的調(diào)節(jié),同樣每按一次小時加一。3控制系統(tǒng)的硬件設(shè)計(jì)3.1單片機(jī)型號的選擇通過對多種單片機(jī)性能的分析,最終認(rèn)為89C52是最理想的電子時鐘開發(fā)芯片。89C5是一種帶8K字節(jié)閃爍可編程可擦除只讀存儲器的低電壓,高性能CMOS8位微處理器,器件采用ATMEL高密度非易失存儲器制造技術(shù)制造,與工業(yè)標(biāo)準(zhǔn)的MCS-52指令集和輸出管腳相兼容。由于將多功能8位CPU和閃爍存儲器組合在單個芯片中,ATMEL的89C52是一種高效微控制器,而且它與MCS-52兼容,且具有8K字節(jié)可編程閃爍存儲器和1000寫/擦循環(huán),數(shù)據(jù)保留時間為10年等特點(diǎn),是最好的選擇。3.21602工作原理字符型LCD通常有14條引腳線或16條引腳線的LCD,多出來的2條線是背光電源線VCC(15腳)和地線GND(16腳),其控制原理與14腳的LCD完全一樣1602液晶的基本的操作分為以下四種:狀態(tài)字讀操作:輸入RS=低、RW=高、EP=高;輸出:DB0~7讀出為狀態(tài)字;數(shù)據(jù)讀出操作:輸入RS=高、RW=高、EP=高;輸出:DB0~7讀出為數(shù)據(jù);指令寫入操作:輸入RS=低、RW=低、EP=上升沿;輸出:無;數(shù)據(jù)寫入操作:輸入RS=高、RW=低、EP=上升沿;輸出:無。如圖3.21602模塊的引腳3.3鍵盤電路設(shè)計(jì)該設(shè)計(jì)只用了一個鍵盤,但實(shí)現(xiàn)的功能卻是比較完善,減少了硬件資源的損耗,該鍵盤可以實(shí)現(xiàn)小時和分鐘的調(diào)節(jié)以及控制是否進(jìn)入省電模式。當(dāng)按鍵按下又松開,可以實(shí)現(xiàn)屏蔽數(shù)碼管顯示的功能,達(dá)到省電的目的;直接按下不松開,則可以通過按鍵實(shí)現(xiàn)分鐘的累加,每按一次分鐘加一;而連續(xù)兩次按下按鍵不放松,則可實(shí)現(xiàn)小時的調(diào)節(jié),同樣每按一次小時加一。達(dá)到時間調(diào)節(jié)的目的。圖3.23多功能控制鍵3.4整個電路原理圖圖3.4系統(tǒng)整個電路4控制系統(tǒng)的軟件設(shè)計(jì)4.1程序設(shè)計(jì)由于C語言程序設(shè)計(jì)較匯編可讀性強(qiáng),可移植性,且可以大大降低編程的難度和縮短開發(fā)周期,本系統(tǒng)程序采用c語言設(shè)計(jì)。這里以LCD運(yùn)作和鍵盤為例,主程序見附錄。//測試LCD忙碌狀態(tài)bitlcd_busy(){ bitresult; rs=0;rw=1;ep=1; _nop_();_nop_();_nop_();_nop_(); result=(bit)(P0&0x80); //LCD的D0--D7中,D7=1為忙碌,D7=0為空閑 ep=0;returnresult; }//寫入指令到LCDvoidlcd_wcmd(charcmd){ while(lcd_busy()); //當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫指令 rs=0;rw=0;ep=0;_nop_();_nop_(); P0=cmd;_nop_();_nop_();_nop_();_nop_(); ep=1;_nop_();_nop_();_nop_();_nop_();ep=0; }//寫入數(shù)據(jù)到LCDvoidlcd_wdat(chardat) { 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; }//按鍵掃描程序unsignedcharscan_key(){ skey=0x00; //給變量vkey置初值 skey|=PRE; //讀取PRE鍵的狀態(tài) skey=skey<<1; //將PRE鍵的狀態(tài)存于skey的B1位 skey|=SET; //讀取SET鍵的狀態(tài),并存于skey的B0位 returnskey; //返回skey的鍵值(即PRE,SET的狀態(tài))}4.2程序流程圖系統(tǒng)的流程圖如圖4.1所示:開始開始初始化LCD1602初始化LCD1602LCD1602的啟動和顯示LCD1602的啟動和顯示中斷T0,T1,INT0,INT1中斷T0,T1,INT0,INT1時間、日期的設(shè)置時間、日期的設(shè)置運(yùn)用查表字符的方法 報(bào)警或加1按下監(jiān)測的鍵盤按下鍵盤的設(shè)置監(jiān)測的鍵盤按下鍵盤的設(shè)置AN3和AN4參考文獻(xiàn)[1]吳金戎,沈慶陽,郭庭吉.8051單片機(jī)實(shí)踐與應(yīng)用[.北京:清華大學(xué)出版社,2002[2]胡漢才.單片機(jī)原理及其接口技術(shù)[M].北京:清華大學(xué)出版社,1995[3]郭天祥.新概念51單片機(jī)C語言教程——入門,提高,開發(fā),拓展全攻略[M].北京:電子工業(yè)出版社,2009.[4]韓廣興.電子元器件與實(shí)用電路基礎(chǔ)[M].北京:電子工業(yè)出版社,2005.6附錄//按AN3,依次進(jìn)入鬧鐘功能是否啟用,鬧鐘時,分秒,年,月,日及時間時,分,秒的設(shè)置,直到退出設(shè)置狀態(tài)//按AN4,調(diào)整是否起用鬧鐘和調(diào)節(jié)鬧鐘時,分,秒,年,月,日,時間的時,分,秒的數(shù)字//LCD第二排中間顯示小喇叭,表示啟用鬧鐘功能,無則禁止鬧鐘功能(可在調(diào)整狀態(tài)進(jìn)行設(shè)置)//正常狀態(tài),LCD上排最前面顯示自定義字符,LCD下排最前面閃動"RICHMCU"http://設(shè)置狀態(tài),LCD上排最前面顯示"P",下排最前面在設(shè)置鬧鐘時間時顯示"alarm:",其它狀態(tài)顯示"time"http://年代變化2000--2099,星期自動轉(zhuǎn)換//程序中有自定義字符寫入#include<reg51.h>#include<intrins.h>unsignedcharcodedis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};unsignedcharcodepara_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月參變數(shù)unsignedchardatadis_buf1[16]; //lcd上排顯示緩沖區(qū)unsignedchardatadis_buf2[16]; //lcd下排顯示緩沖區(qū) unsignedchardatayear,month,date,week;//年、月、日、星期unsignedchardataarmhour,armmin,armsec;//鬧鐘時、分、秒unsignedchardatahour,min,sec,sec100; //時、分、秒、百分之一秒unsignedchardataflag,vkey,skey;//設(shè)置狀態(tài)計(jì)數(shù)標(biāo)志、按鍵先前值、按鍵當(dāng)前值 bit alarm; //標(biāo)識是否啟用鬧鐘,1--啟用,0--關(guān)閉sbit rs=P3^0; //LCD數(shù)據(jù)/命令選擇端(H/L)sbit rw=P3^1; //LCD讀/寫選擇端(H/L)sbit ep=P2^2; //LCD使能控制sbit PRE=P1^1; //調(diào)整鍵(AN3)sbit SET=P1^2; //調(diào)整鍵(AN4)sbit SPK=P2^1; voiddelayms(unsignedcharms); //延時程序bitlcd_busy(); //測試LCD忙碌狀態(tài)程序voidlcd_wcmd(charcmd); //寫入指令到LCD程序voidlcd_wdat(chardat); //寫入數(shù)據(jù)到LCD程序voidlcd_pos(charpos); //LCD數(shù)據(jù)指針位置程序voidlcd_init(); //LCD初始化設(shè)定程序voidpro_timedate(); //時間日期處理程序voidpro_display(); //顯示處理程序voidpro_key(); //按鍵處理程序voidtime_alarm(); //定時報(bào)警功能(鬧鐘)unsignedcharscan_key(); //按鍵掃描程序unsignedcharweek_proc(); //星期自動計(jì)算與顯示函數(shù)bitleap_year(); //判斷是否為閏年voidlcd_sef_chr(); //LCD自定義字符程序voidupdate_disbuf(unsignedchart1,unsignedchart2[],unsignedchardis_h,unsignedchardis_m,unsignedchardis_s); //更新顯示緩沖區(qū)函數(shù)//延時程序voiddelay(unsignedcharms){ while(ms--) { unsignedchari; for(i=0;i<250;i++) { _nop_(); //執(zhí)行一條_nop_()指令為一個機(jī)器周期 _nop_(); _nop_(); _nop_(); } }} //測試LCD忙碌狀態(tài)bitlcd_busy(){ bitresult; rs=0; rw=1; ep=1; _nop_();_nop_();_nop_();_nop_(); result=(bit)(P0&0x80); //LCD的D0--D7中,D7=1為忙碌,D7=0為空閑 ep=0; returnresult; }//寫入指令到LCDvoidlcd_wcmd(charcmd){ while(lcd_busy()); //當(dāng)lcd_busy為1時,再次檢測LCD忙碌狀態(tài),lcd-busy為0時,開始寫指令 rs=0; rw=0; ep=0; _nop_();_nop_(); P0=cmd; _nop_();_nop_();_nop_();_nop_(); ep=1; _nop_();_nop_();_nop_();_nop_(); ep=0; }//寫入數(shù)據(jù)到LCDvoidlcd_wdat(chardat) { 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ù)指針位置程序voidlcd_pos(charpos){ lcd_wcmd(pos|0x80); //數(shù)據(jù)指針=80+地址碼(00H~27H,40H~67H)}//設(shè)定二個自定義字符,(注意:LCD1602中自定義字符的地址為0x00--0x07,即可定義8個字符)//這里我們設(shè)定把一個自定義字符放在0x00位置(000),另一個放在0x01位子(001)voidlcd_sef_chr(){ //第一個自定義字符 lcd_wcmd(0x40); //"01000000"第1行地址(D7D6為地址設(shè)定命令形式D5D4D3為字符存放位置(0--7),D2D1D0為字符行地址(0--7)) lcd_wdat(0x1f); //"XXX11111" 第1行數(shù)據(jù)(D7D6D5為XXX,表示為任意數(shù)(一般用000),D4D3D2D1D0為字符行數(shù)據(jù)(1-點(diǎn)亮,0-熄滅) lcd_wcmd(0x41); //"01000001" 第2行地址 lcd_wdat(0x11); //"XXX10001" 第2行數(shù)據(jù) lcd_wcmd(0x42); //"01000010" 第3行地址 lcd_wdat(0x15); //"XXX10101" 第3行數(shù)據(jù) lcd_wcmd(0x43); //"01000011" 第4行地址 lcd_wdat(0x11); //"XXX10001" 第4行數(shù)據(jù) lcd_wcmd(0x44); //"01000100" 第5行地址 lcd_wdat(0x1f); //"XXX11111" 第5行數(shù)據(jù) lcd_wcmd(0x45); //"01000101" 第6行地址 lcd_wdat(0x0a); //"XXX01010" 第6行數(shù)據(jù) lcd_wcmd(0x46); //"01000110" 第7行地址 lcd_wdat(0x1f); //"XXX11111" 第7行數(shù)據(jù) lcd_wcmd(0x47); //"01000111" 第8行地址 lcd_wdat(0x00); //"XXX00000" 第8行數(shù)據(jù) //第二個自定義字符 lcd_wcmd(0x48); //"01001000"第1行地址 lcd_wdat(0x01); //"XXX00001" 第1行數(shù)據(jù) lcd_wcmd(0x49); //"01001001" 第2行地址 lcd_wdat(0x1b); //"XXX11011" 第2行數(shù)據(jù) lcd_wcmd(0x4a); //"01001010" 第3行地址 lcd_wdat(0x1d); //"XXX11101" 第3行數(shù)據(jù) lcd_wcmd(0x4b); //"01001011" 第4行地址 lcd_wdat(0x19); //"XXX11001" 第4行數(shù)據(jù) lcd_wcmd(0x4c); //"01001100" 第5行地址 lcd_wdat(0x1d); //"XXX11101" 第5行數(shù)據(jù) lcd_wcmd(0x4d); //"01001101" 第6行地址 lcd_wdat(0x1b); //"XXX11011" 第6行數(shù)據(jù) lcd_wcmd(0x4e); //"01001110" 第7行地址 lcd_wdat(0x01); //"XXX00001" 第7行數(shù)據(jù) lcd_wcmd(0x4f); //"01001111" 第8行地址 lcd_wdat(0x00); //"XXX00000" 第8行數(shù)據(jù)}//LCD初始化設(shè)定voidlcd_init(){ lcd_wcmd(0x38); //設(shè)置LCD為16X2顯示,5X7點(diǎn)陣,八位數(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);}//閏年的計(jì)算bitleap_year(){ bitleap; if((year%4==0&&year%100!=0)||year%400==0)//閏年的條件 leap=1; else leap=0; returnleap;}//星期的自動運(yùn)算和處理unsignedcharweek_proc(){ unsignedcharnum_leap; unsignedcharc; num_leap=year/4-year/100+year/400;//自00年起到y(tǒng)ear所經(jīng)歷的閏年數(shù) if(leap_year()&&month<=2) //既是閏年且是1月和2月 c=5; else c=6; week=(year+para_month[month]+date+num_leap+c)%7;//計(jì)算對應(yīng)的星期 returnweek;} //更新顯示緩沖區(qū)voidupdate_disbuf(unsignedchart1,unsignedchart2[],unsignedchardis_h,unsignedchardis_m,unsignedchardis_s) { dis_buf1[0]=t1; // dis_buf1[1]=0x20; //空格 dis_buf1[2]=50; //'2' dis_buf1[3]=48;//'0' dis_buf1[4]=year/10+48; dis_buf1[5]=year%10+48; dis_buf1[6]=0x2d; dis_buf1[7]=month/10+48; dis_buf1[8]=month%10+48; dis_buf1[9]=0x2d; //'-' dis_buf1[10]=date/10+48; dis_buf1[11]=date%10+48; dis_buf1[12]=0x20; dis_buf1[13]=dis_week[4*week]; dis_buf1[14]=dis_week[4*week+1]; dis_buf1[15]=dis_week[4*week+2]; dis_buf2[0]=t2[0]; dis_buf2[1]=t2[1]; dis_buf2[2]=t2[2]; dis_buf2[3]=t2[3]; dis_buf2[4]=t2[4]; dis_buf2[5]=t2[5]; dis_buf2[6]=t2[6]; //空格 if(alarm) dis_buf2[7]=0x01; //alarm=1,顯示鬧鐘啟用標(biāo)致(第二個自定義字符) else dis_buf2[7]=0x20; //alarm=0,不顯示鬧鐘啟用標(biāo)致 dis_buf2[8]=dis_h/10+48; dis_buf2[9]=dis_h%10+48; dis_buf2[10]=0x3a; //':' dis_buf2[11]=dis_m/10+48; dis_buf2[12]=dis_m%10+48; dis_buf2[13]=0x3a; dis_buf2[14]=dis_s/10+48; dis_buf2[15]=dis_s%10+48;}//時間和日期處理程序voidpro_timedate(){ sec++; if(sec>59) {sec=0; min++; if(min>59) {min=0; hour++; if(hour>23) {hour=0; date++; if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) if(date>31){date=1;month++;} //大月31天 if(month==4||month==6||month==9||month==11) if(date>30){date=1;month++;} //小月30天 if(month==2) {if(leap_year()) //閏年的條件 {if(date>29){date=1;month++;}} //閏年2月為29天 else {if(date>28){date=1;month++;}} //平年2月為28天 } if(month>12){month=1;year++;} if(year>99)year=0; } } } week_proc(); if(sec==armsec&&min==armmin&&hour==armhour) {if(alarm) TR1=1; //鬧鐘啟用時,報(bào)警時間到,啟動Timer1 }}//顯示處理程序voidpro_display(){ unsignedchari; lcd_pos(0x00); for(i=0;i<=15;i++) {lcd_wdat(dis_buf1[i]);} lcd_pos(0x40); for(i=0;i<=15;i++) {lcd_wdat(dis_buf2[i]);}}//Timer0中斷處理程序,秒的產(chǎn)生voidtimer0()interrupt1{ TH0=0xD8; TL0=0xF0; sec100++; if(sec100>=100) //1秒時間(100*10ms=1000ms=1s) {sec100=0; pro_timedate();//調(diào)用時間和日期處理程序 } if(sec&0x01) //"RICHMCU"閃一秒,停一秒 update_disbuf(0x00,"",hour,min,sec); //0x00表示顯示00位置的自定義字符 elseupdate_disbuf(0x00,"RICHMCU",hour,min,sec);pro_display();//調(diào)用顯示處理函數(shù)} //按鍵掃描程序unsignedcharscan_key(){ skey=0x00; //給變量vkey置初值 skey|=PRE; //讀取PRE鍵的狀態(tài) skey=skey<<1; //將PRE鍵的狀態(tài)存于skey的B1位 skey|=SET; //讀取SET鍵的狀態(tài),并存于skey的B0位 returnskey; //返回skey的鍵值(即PRE,SET的狀態(tài))}//外部中斷INT0中斷處理程序voidint0()interrupt0{ 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)整項(xiàng)下 flag=0; vkey=0x03; while(flag^0x0a) {skey=scan_key(); //掃描按鍵狀態(tài) if(skey^vkey) //若skey與vkey相同,跳出循環(huán),相異執(zhí)行循環(huán)體 { delay(10); //去按鍵抖動 skey=scan_key(); //轉(zhuǎn)回掃描按鍵狀態(tài) if(skey^vkey) //若skey與vkey相同,跳出循環(huán),相異執(zhí)行循環(huán)體 { vkey=skey; //將skey的值付給vkey if(skey==0x01) //PRE鍵按下 { flag++; //調(diào)整標(biāo)志位加1 switch(flag) //將光標(biāo)置于相應(yīng)調(diào)整位置 { case1:lcd_pos(0x49);break; //光標(biāo)置小時報(bào)警設(shè)置位置 case2: lcd_pos(0x4c);break; //光標(biāo)置分鐘報(bào)警設(shè)置位置 case3: lcd_pos(0x4f);break; //光標(biāo)置秒時報(bào)警設(shè)置位置 case4: update_disbuf(0x50,"time:",hour,min,sec); pro_display(); lcd_pos(0x05);break; //光標(biāo)置年調(diào)整位置 case5: lcd_pos(0x08);break; //光標(biāo)置月調(diào)整位置 case6: lcd_pos(0x0b);break; //光標(biāo)置日調(diào)整位置 case7:lcd_pos(0x49);break; //光標(biāo)置時調(diào)整位置 case8: lcd_pos(0x4c);break; //光標(biāo)置分調(diào)整位置 case9: lcd_pos(0x4f);break; //光標(biāo)置秒調(diào)整位置 default:break; } } if(skey==0x02) //SET鍵按下 { pro_key(); //轉(zhuǎn)設(shè)置按鍵處理程序 } } } } lcd_wcmd(0x0c); //設(shè)置LCD開顯示及光標(biāo)不閃爍,不顯示"-" lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容 IE=0x8f; //CPU開中斷,INT0,INT1,開中斷 TR0=1; //Timer0啟動}//主程序,初始化及初值設(shè)定voidmain(){ lcd_init(); //初始化LCD lcd_sef_chr(); //寫入自定義字符號 hour=0;min=0;sec=0; //開機(jī)時的時,分,秒顯示 armhour=0;armmin=0;armsec=0; //開機(jī)時的時,分,秒報(bào)警初值 year=5;month=1;date=1; //開機(jī)時的年,月,日,星期顯示 week_proc(); alarm=1; //初始開機(jī),啟用鬧鐘 IE=0x8f; //CPU開中斷,INT0,INT1,Timer0,Timer1開中斷 IP=0x04; //設(shè)置INT0為中斷最高優(yōu)先級 IT0=0;IT1=0; //外部INT0,INT1設(shè)置為電平觸發(fā)方式(注意,觸發(fā)不要選邊沿方式,易誤動) TMOD=0x11; //Timer0,Timer1工作于模式1,16位定時方式 TH0=0xdc;TL0=0x00; //Timer0置10ms定時初值 TH1=0xff;TL1=0x00; //Timer1置初值 TR0=1; //Timer0啟動 TR1=0; while(1);}//設(shè)置按鍵處理程序voidpro_key(){ switch(flag) { case0:alarm=!alarm; //啟用或關(guān)閉鬧鐘(alarm=1:啟用,alarm=0:關(guān)閉) update_disbuf(0x50,"alarm:",armhour,armmin,armsec);//更新顯示數(shù)據(jù) pro_display(); //調(diào)用顯示處理 lcd_pos(0x47);break; //光標(biāo)回到原調(diào)整位置 case1:armhour++; if(armhour>23)armhour=0; update_disbuf(0x50,"alarm:",armhour,armmin,armsec);//更新顯示數(shù)據(jù) pro_display(); //調(diào)用顯示處理 lcd_pos(0x49);break; //光標(biāo)回到原調(diào)整位置 case2:armmin++; if(armmin>59)armmin=0; update_disbuf(0x50,"alarm:",armhour,armmin,armsec); pro_display(); lcd_pos(0x4c);break; case3:armsec++; if(armsec>59)armsec=0; update_disbuf(0x50,"alarm:",armhour,armmin,armsec); pro_display(); lcd_pos(0x4f);break; case4:year++; if (year>99)year=0; week_proc();//星期自動運(yùn)算 update_disbuf(0x50,"time:",hour
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 五年級的英語題目及答案
- 微積分考試題目及答案
- 22春“土木工程”專業(yè)《鋼結(jié)構(gòu)》在線作業(yè)含答案參考9
- 初中小說知識點(diǎn)課件
- 2025 四年級科學(xué)上冊昆蟲觸角類型識別課件
- 部編人教版小學(xué)二年級數(shù)學(xué)上冊練習(xí)題(含答案解析)
- 分體空調(diào)安裝技術(shù)要領(lǐng)
- 儲能系統(tǒng)技術(shù)方法
- 手術(shù)室??瓶荚囶}及答案
- 山西省植物學(xué)試題及答案
- 氫能源汽車2026年維修培訓(xùn)
- 南京南京市建鄴區(qū)2025年9月政府購崗人員招聘筆試歷年參考題庫附帶答案詳解
- 2025年企業(yè)內(nèi)部培訓(xùn)課程體系
- 鉆井公司冬季安全培訓(xùn)內(nèi)容課件
- 瓶裝礦泉水代工協(xié)議書
- 2026年浙江高考數(shù)學(xué)考試卷含答案
- 炎德·英才·名校聯(lián)考聯(lián)合體2026屆高三年級1月聯(lián)考生物試卷(含答及解析)
- 2025年7月新疆普通高中學(xué)業(yè)水平考試化學(xué)試卷(含答案及解析)
- 2025中國遠(yuǎn)洋海運(yùn)集團(tuán)內(nèi)部招聘中遠(yuǎn)海運(yùn)能源運(yùn)輸股份有限公司招聘筆試參考題庫附帶答案詳解(3卷)
- 2026年工程材料企業(yè)物資采購人員考試大綱
- 硅素行業(yè)分析報(bào)告
評論
0/150
提交評論