《基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)》13000字(論文)_第1頁(yè)
《基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)》13000字(論文)_第2頁(yè)
《基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)》13000字(論文)_第3頁(yè)
《基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)》13000字(論文)_第4頁(yè)
《基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)》13000字(論文)_第5頁(yè)
已閱讀5頁(yè),還剩56頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

PAGEII基于單片機(jī)的數(shù)字時(shí)鐘的硬件結(jié)構(gòu)及軟件系統(tǒng)設(shè)計(jì)摘要電子日歷是一種非常常見的日常計(jì)時(shí)工具,在當(dāng)今社會(huì)中越來越重要。電子日歷的硬件主要采用AT89C51作為主控核心,DS1302時(shí)鐘芯片提供時(shí)鐘和LCD1602液晶顯示器。AT89C51單片機(jī)由STC公司生產(chǎn),功耗低,電壓可達(dá)4~6V;DS1302時(shí)鐘芯片是美國(guó)達(dá)拉斯公司生產(chǎn)的低功耗實(shí)時(shí)時(shí)鐘芯片,可實(shí)現(xiàn)年、月、日、周、時(shí)、分、秒計(jì)時(shí),并具有閏年補(bǔ)償?shù)榷囗?xiàng)功能。此外,DS1302應(yīng)用壽命長(zhǎng),誤差小。它適用于數(shù)字電子日歷取直觀的數(shù)字顯示,數(shù)字顯示是取LCD1602液晶顯示器來顯示,可以同時(shí)顯示年、月、日、周、時(shí)、分、秒等信息。此外,電子日歷還具有時(shí)間校準(zhǔn)功能。軟件方面,主要包括日通程序、時(shí)間調(diào)整程序、顯示程序等,所有程序編寫完成后,在keil軟件中進(jìn)行調(diào)試。在沒有問題之后,它們被燒錄到MCU進(jìn)行測(cè)試。本設(shè)計(jì)主要由時(shí)鐘芯片DS1302和溫度傳感器DS18B20采集數(shù)據(jù)到單片機(jī)進(jìn)行處理,然后通過LCD1602顯示,本文主要討論了液晶顯示器LCD1602與時(shí)鐘芯片DS1302、溫度傳感器DS18B20與單片機(jī)的硬件互聯(lián)和通信,給出了幾種硬件連接方案在日歷計(jì)算的軟件方面,對(duì)該方法進(jìn)行了詳細(xì)的比較。【關(guān)鍵詞】AT89C51LCD1602DS18B20DS1302按鍵目錄11486前言 121075第一章工作原理 2237061.1設(shè)計(jì)目標(biāo) 2314251.1.1基本功能 28838第二章硬件設(shè)計(jì)與原理 3145852.1總設(shè)計(jì)框圖 3202382.2硬件設(shè)計(jì)分析 3144542.2.1電源的設(shè)計(jì) 344682.2.2單片機(jī)最小系統(tǒng) 4159402.2.3顯示系統(tǒng) 10271722.2.4LCD1602的指令說明及時(shí)序 126442.2.5LCD1602的RAM地址映射及標(biāo)準(zhǔn)字庫(kù)表 1432202.2.6DS1302原理及說明 16161972.2.7DS18B20工作原理及說明 1954422.2.8按鍵電路 2026381第三章軟件設(shè)計(jì)與分析 22236973.1軟件設(shè)計(jì)的組成 22186313.2源程序 2613711第四章軟件仿真 56214844.1PROTEUS簡(jiǎn)介 5681714.2仿真圖 5818214.3原理圖 59283274.4元件清單 6025374參考文獻(xiàn) 64前言近年來,隨著通道技術(shù)的飛速發(fā)展,單片機(jī)領(lǐng)域不斷走向社會(huì)的每一個(gè)角落,也推動(dòng)著傳統(tǒng)的主控檢測(cè)技術(shù)日新月異。在單片機(jī)實(shí)時(shí)操作和主動(dòng)控制系統(tǒng)中,單片機(jī)是目前應(yīng)用的核心部件。僅僅掌握單片機(jī)的知識(shí)是不夠的。它還應(yīng)根據(jù)其具體的硬件結(jié)構(gòu)和軟件組合,針對(duì)應(yīng)用對(duì)象的具體特點(diǎn)加以完善。單片機(jī)原理與應(yīng)用課程設(shè)計(jì)是電子類專業(yè)的一門基礎(chǔ)課程。它是繼匯編語(yǔ)言程序設(shè)計(jì)和接口技能課程之后的一門實(shí)踐性課程。

第一章工作原理1.1設(shè)計(jì)目標(biāo)1.1.1基本功能此萬(wàn)年歷主要具有:年、月、日、星期、時(shí)、分、秒、溫度顯示。主要功能:1、萬(wàn)年歷2、時(shí)間3、星期4、溫度顯示(以上四項(xiàng)內(nèi)容同時(shí)顯示)5、四鍵調(diào)時(shí)(設(shè)置鍵、上調(diào)鍵、下調(diào)鍵、關(guān)音按鍵)第二章硬件設(shè)計(jì)與原理以AT89C51單片機(jī)為核心,起著控制作用。系統(tǒng)包括LCD1602液晶顯示電路、復(fù)位電路、時(shí)鐘電路、按鍵電路、溫度傳感器電路、時(shí)鐘芯片電路。設(shè)計(jì)思路分為七個(gè)模塊:復(fù)位電路、晶振電路模塊、AT89C51、LCD1602液晶顯示電路、按鍵電路、溫度傳感器電路、時(shí)鐘芯片電路這七個(gè)模塊。2.1總設(shè)計(jì)框圖2.2硬件設(shè)計(jì)分析2.2.1電源的設(shè)計(jì)系統(tǒng)電源使用直流5伏。由電腦USB接口提供電源。USB是通用串行總線(UniversalSerialBus)接口的簡(jiǎn)稱。它是目前使用比較廣泛的電腦接口之一,主要版本有1.0、1.1和最新的2.0三種版本。根據(jù)USB總線的工業(yè)標(biāo)準(zhǔn),它可以提供額定功率為5V/500mA的電源供USB設(shè)備使用。2.2.2單片機(jī)最小系統(tǒng)51單片機(jī)是所有與intel8031指令系統(tǒng)兼容的單片機(jī)的總稱。這一系列單片機(jī)的鼻祖是英特爾的8031單片機(jī)。后來,隨著同一技術(shù)的發(fā)展,它成為應(yīng)用廣泛的8位單片機(jī)之一。MCU是一種大規(guī)模集成電路,它將CPU、ram、ROM、定時(shí)器/計(jì)數(shù)器、多功能I/O口等計(jì)算機(jī)所需的基本功能部件集成在一塊芯片中,又稱MCU。51系列單片機(jī)包括以下幾個(gè)部分:一個(gè)8位CPU;片上振蕩器和時(shí)鐘電路4KBROM程序存儲(chǔ)器128BRAM數(shù)據(jù)存儲(chǔ)器控制電路尋址64KB外部數(shù)據(jù)存儲(chǔ)器和64KB外部程序存儲(chǔ)器空間32個(gè)可編程I/O端口兩個(gè)16位定時(shí)器/計(jì)數(shù)器一個(gè)可編程全雙工串行端口五個(gè)中止源和兩個(gè)優(yōu)先級(jí)嵌套中止結(jié)構(gòu)As圖2-2-1是AT89C51單片機(jī)的基本結(jié)構(gòu),其基本性能介紹如下:圖2-2-1AT89C51單片機(jī)AT89C51包含40個(gè)引腳、32個(gè)外部雙向輸入/輸出(I/O)端口、2個(gè)外部和中間端口、3個(gè)16位可編程定時(shí)計(jì)數(shù)器和2個(gè)全雙工串行通信端口。AT89C51可以按常規(guī)方法編程,但不能在線編程。它將普通微處理器與flash存儲(chǔ)器相結(jié)合,特別是可擦除flash存儲(chǔ)器,可以有效地降低開發(fā)成本。AT89C51的主要特性如下表所示:兼容MCS—51指令系統(tǒng)32個(gè)可編程I/O線4k字節(jié)可編程閃爍存儲(chǔ)器可編程UARL通道三個(gè)16位可編程定時(shí)/計(jì)數(shù)器中斷時(shí)鐘頻率0-24MHz2個(gè)外部中斷源,共8個(gè)中斷源256×8bit內(nèi)部RAM2個(gè)讀寫中斷口線可直接驅(qū)動(dòng)LED軟件設(shè)置睡眠和喚醒功能低功耗空閑和掉電模式表2-2-1AT89C51主要功能描述AT89C51是一種8位通用微處理器,采用40針雙列直插式封裝。采用工業(yè)級(jí)C51核,內(nèi)部功能和引腳布局與通用型8xc52相似。主要用于掌握收斂調(diào)整功能。主要功能包括會(huì)聚主芯片內(nèi)部存儲(chǔ)器、數(shù)據(jù)RAM和外部接口的初始化、會(huì)聚調(diào)整的掌握、會(huì)聚測(cè)試圖的掌握、紅外遙控信號(hào)的吸收和解碼以及與主板CPU的通信。主要引腳有:xtal1(19引腳)和xtal2(18引腳)是振蕩器的輸入和輸出端口,外置12Mhz晶體振蕩器。Rst/VPD(9針)為復(fù)位輸入端口,復(fù)位電路由外電阻和電容組成。VCC(40針)和VSS(20針)是電源端口,分別連接到+5V電源的正極和負(fù)極端子。在本設(shè)計(jì)中,端口P0(32-39針)被定義為N1功能主端口,與N1的相應(yīng)功能針相連。引腳13被定義為IR輸入端口,引腳10和引腳11被定義為I2C總線主端口,與N1的SDAs(18引腳)和SCLS(19引腳)端口相連。27引腳和28引腳被定義為握手信號(hào)功能端口,與主板CPU的相應(yīng)功能端口相連,用于檢測(cè)電流系統(tǒng)并掌握匯聚調(diào)整功能的端口P0:端口P0是一組8位開漏雙向I/O端口,即地址/數(shù)據(jù)總線復(fù)用端口。當(dāng)用作輸出端口時(shí),每個(gè)TTL邏輯門可以通過吸收電流來驅(qū)動(dòng)。將“1”寫入端口P0時(shí),它可用作高阻抗輸入。當(dāng)訪問外部數(shù)據(jù)存儲(chǔ)器或程序存儲(chǔ)器時(shí),這組端口線分時(shí)地址轉(zhuǎn)換(低8位)和數(shù)據(jù)總線復(fù)用在訪問期間激活內(nèi)部上拉電阻。在flash編程中,端口P0吸收指令字節(jié),而在程序驗(yàn)證中,它輸出指令字節(jié)。在驗(yàn)證中,它請(qǐng)求外部上拉電阻器P1端口:P1是一個(gè)帶有內(nèi)部上拉電阻器的8位雙向I/O端口。P1的輸出緩沖級(jí)可以驅(qū)動(dòng)(吸收或輸出電流)4個(gè)TTL邏輯門。將“1”寫入端口,通過內(nèi)部上拉電阻將端口拉至高電平,即可作為輸入端口。當(dāng)用作輸入端口時(shí),由于內(nèi)部上拉電阻,引腳在被外部信號(hào)下拉時(shí)將輸出電流(IIL)。與AT89C51不同,P1.0和P1.1還可用作定時(shí)器/計(jì)數(shù)器2的外部計(jì)數(shù)輸入(P1.0/T2)和輸入(P1.1/t2ex)。在閃存編程和程序驗(yàn)證期間,P1吸收低8位地址P2端口:P2是一個(gè)帶內(nèi)部上拉電阻器的8位雙向I/O端口。P2的輸出緩沖級(jí)可以驅(qū)動(dòng)(吸收或輸出電流)4個(gè)TTL邏輯門。將“1”寫入端口P2,并通過內(nèi)部上拉電阻將端口拉至高電平。此時(shí),它可以用作輸入端口。當(dāng)它被用作輸入端口時(shí),由于內(nèi)部上拉電阻,當(dāng)它被外部信號(hào)拉低時(shí),引腳將輸出電流(IIL)。當(dāng)訪問具有16位地址的外部程序存儲(chǔ)器或外部數(shù)據(jù)存儲(chǔ)器時(shí)(例如,執(zhí)行MOVX@dptr指令),P2端口發(fā)送高8位地址數(shù)據(jù)。當(dāng)訪問具有8位地址的外部數(shù)據(jù)存儲(chǔ)器(例如執(zhí)行MOVX@RI指令)時(shí),P2端口輸出P2鎖存器的內(nèi)容。在flash編程或驗(yàn)證過程中,P2還吸收高位地址和一些主信號(hào)&P3端口:P3端口是一組帶有內(nèi)部上拉電阻的8位雙向I/O端口。P3端口的輸出緩沖級(jí)可以驅(qū)動(dòng)(吸收或輸出電流)四個(gè)TTL邏輯門。當(dāng)將“1”寫入P3端口時(shí),它們由內(nèi)部上拉電阻器上拉,可用作輸入端口。此時(shí),外部下拉的P3端口將使用上拉電阻器輸出電流(IIL)。除了作為一個(gè)通用的I/O端口外,P3端口的主要用途是它的第二個(gè)功能。P3端口還吸收一些主信號(hào),用于閃存編程和程序驗(yàn)證Rst:復(fù)位輸入。當(dāng)振蕩器工作時(shí),rst引腳輸出超過兩個(gè)機(jī)器周期,并且高電平將重置MCUAle/prog:當(dāng)訪問外部程序存儲(chǔ)器或數(shù)據(jù)存儲(chǔ)器時(shí),Ale(地址鎖存許可)輸出脈沖用于鎖存地址的低8位。通常,ale仍以時(shí)鐘振蕩頻率的1/6輸出一個(gè)固定的脈沖信號(hào),因此可以用來輸出時(shí)鐘或定時(shí)目標(biāo)。應(yīng)當(dāng)注意,每當(dāng)訪問外部數(shù)據(jù)存儲(chǔ)器時(shí),Al脈沖將被跳過。該引腳還用于在閃存編程期間輸入程序脈沖(PROG)。如有必要,可通過在SFR區(qū)域設(shè)置8eh裝置的D0位置來停止ale操作。在此位之后,只有一條MOVX和MOVC指令可以激活ale。此外,銷會(huì)稍微拉高。當(dāng)MCU執(zhí)行外部程序時(shí),ale停止位應(yīng)設(shè)置為無效PSEN:PSEN的輸出是外部程序存儲(chǔ)器的讀出通信號(hào)。當(dāng)AT89C51從外部程序存儲(chǔ)器中獲取指令(或數(shù)據(jù))時(shí),PSEN每機(jī)器周期有效兩次,即輸出兩個(gè)脈沖。在此期間,當(dāng)訪問外部數(shù)據(jù)存儲(chǔ)器時(shí),PSEN信號(hào)將被跳過兩次。EA/VPP:外部訪問權(quán)限。為了使CPU只訪問外部程序存儲(chǔ)器(地址為0000hffffh),EA終端必須堅(jiān)持低電平(接地)。應(yīng)注意,如果加密位Lb1被編程,則在復(fù)位期間EAend狀態(tài)將被內(nèi)部鎖定。如果EA端是高電平(連接到VCC端),CPU執(zhí)行內(nèi)部程序存儲(chǔ)器中的指令。閃存編程時(shí),引腳加上+12V編程許可電源VPP,當(dāng)然這一定是12V編程電壓VPP的應(yīng)用器件。Xtal1:振蕩器反相放大器和內(nèi)部時(shí)鐘發(fā)生器的輸入。Xtal2:振蕩器反相放大器輸出。單片機(jī)最小原理圖如圖2-2-2所示。圖2-2-2單片機(jī)最小系統(tǒng)單片機(jī)最小系統(tǒng)說明:時(shí)鐘信號(hào)產(chǎn)生:MCS-51芯片中有一個(gè)高增益逆變放大器,輸入為xtal1,輸出為xtal2。在芯片外部,xtal1和xtal2與晶體振蕩器和微調(diào)電容器連接,形成穩(wěn)定的自激振蕩器,它是單片機(jī)的時(shí)鐘振蕩電路,時(shí)鐘電路的振蕩脈沖經(jīng)觸發(fā)器分頻后成為單片機(jī)的時(shí)鐘脈沖信號(hào),一般電容C2和C3約為30pf,晶體的振蕩頻率為1.2-12mhz。如果晶體振蕩頻率高,系統(tǒng)的時(shí)鐘頻率也高,單片機(jī)的運(yùn)行速度也快,單片機(jī)復(fù)位使系統(tǒng)中的CPU等功能部件處于一定的初始狀態(tài),并從該狀態(tài)開始工作。MCU復(fù)位條件:必須使9針加上連續(xù)兩個(gè)機(jī)器周期(即24個(gè)振蕩周期)的高電平。2.2.3顯示系統(tǒng)LCD1602分為帶背光和不帶背光兩種,基控制器大部分為HD44780,帶背光的比不帶背光的厚,是否帶背光在應(yīng)用中并無差別,兩者尺寸差別如下圖2-2-3所示:圖圖2-2-3LCD1602尺寸圖LCD1602重要技術(shù)參數(shù):1,顯示容量:16×2字符2,芯片工作電壓:4.5-5.5v3,工作電流:2.0ma(5.0V4,模塊最佳工作電壓:5.0V5,字符大?。?.95×4.35(W×H)Mm引腳功能說明LCD1602采用14引腳(無背光)或16引腳(帶背光)接口。各引腳接口說明如圖2-2-4所示:編號(hào)符號(hào)引腳說明編號(hào)符號(hào)引腳說明1VSS電源地9D2數(shù)據(jù)2VDD電源正極10D3數(shù)據(jù)3VL液晶顯示偏壓11D4數(shù)據(jù)4RS數(shù)據(jù)/命令選擇12D5數(shù)據(jù)5R/W讀/寫選擇13D6數(shù)據(jù)6E使能信號(hào)14D7數(shù)據(jù)7D0數(shù)據(jù)15BLA背光源正極8D1數(shù)據(jù)16BLK背光源負(fù)極圖圖2-2-4引腳接口說明圖2-2-4:引腳接口說明表引腳1:VSS是地面電源。引腳2:VDD連接到5V正極電源。第三個(gè)引腳:VL是LCD比較調(diào)整終端。接正電源時(shí)比較度最弱,接地時(shí)比較度最高。當(dāng)它太高的時(shí)候,鬼魂就會(huì)出現(xiàn)。使用時(shí),可通過10k電位器調(diào)節(jié)比較度。引腳4:RS是存儲(chǔ)設(shè)備、高級(jí)數(shù)據(jù)存儲(chǔ)設(shè)備和低級(jí)指令存儲(chǔ)設(shè)備的選擇。引腳5:R/W是讀/寫信號(hào)線,用于高電平的讀操作和低電平的寫操作。當(dāng)RS和R/W都處于低電平時(shí),它們可以寫指令或顯示地址;當(dāng)RS處于低電平時(shí),R/W處于高電平時(shí),可以讀出忙信號(hào);當(dāng)RS處于高電平時(shí),R/W處于低電平時(shí),它們可以寫入數(shù)據(jù)。引腳6:e端子是啟用端子。當(dāng)e終端從高電平跳到低電平時(shí),LCD模塊執(zhí)行命令。引腳7-14:d0-d7是8位雙向數(shù)據(jù)線。引腳15:背光陰極。引腳16:背光陰極。2.2.4LCD1602的指令說明及時(shí)序1602液晶模塊內(nèi)部的控制器共有11條控制指令,如圖2-2-5所示:序號(hào)指令RSR/WD7D6D5D4D3D2D1D01清顯示00000000012光標(biāo)返回000000001*3置輸入模式00000001I/DS4顯示開/關(guān)控制0000001DCB5光標(biāo)或字符移位000001S/CR/L**6置功能00001DLNF**7置字符發(fā)生存貯器地址0001字符發(fā)生存貯器地址8置數(shù)據(jù)存貯器地址001顯示數(shù)據(jù)存貯器地址9讀忙標(biāo)志或地址01BF計(jì)數(shù)器地址10寫數(shù)到CGRAM或DDRAM)10要寫的數(shù)據(jù)內(nèi)容11從CGRAM或DDRAM讀數(shù)11讀出的數(shù)據(jù)內(nèi)容圖圖2-2-5控制命令表通過指令編程完成1602液晶顯示模塊的讀寫操作、屏幕操作和光標(biāo)操作。(說明:1為高電平,0為低電平)指令1:清除顯示,指令代碼01h,光標(biāo)復(fù)位到地址00h位置命令2:復(fù)位光標(biāo)并將光標(biāo)返回到地址00h命令3:光標(biāo)和顯示模式設(shè)置I/D:光標(biāo)移動(dòng)方向,高電平向右移動(dòng),低電平向左移動(dòng)s:是否所有文本在屏幕上向左或向右移動(dòng)。高電平有效,低電平無效命令4:顯示開關(guān)主控。D:掌握整體顯示的開與關(guān),高電平顯示的開與關(guān),低電平顯示的關(guān)顯示C:掌握光標(biāo)的開與關(guān),高電平顯示有光標(biāo),低電平顯示無光標(biāo)B:掌握光標(biāo)是否發(fā)光,高電平顯示,無光標(biāo)低位顯示Command5:光標(biāo)或顯示移位s/C:高位移動(dòng)顯示文字,低位移動(dòng)光標(biāo)Command6:功能設(shè)置命令DL:高位4位總線,低位8位總線n:低位單行顯示,高位雙線顯示F:低位5x7點(diǎn)陣字符,5x10高位點(diǎn)陣字符Instruction7:字符發(fā)生器RAM地址設(shè)置Instruction8:DDRAM地址設(shè)置Instruction9:讀取忙信號(hào)和光標(biāo)地址BF:忙標(biāo)志位,高位表示忙,此時(shí)模塊無法吸收命令或數(shù)據(jù),如果是低位,則表示不忙Instruction10:寫入數(shù)據(jù)說明11:讀取數(shù)據(jù)。2.2.5LCD1602的RAM地址映射及標(biāo)準(zhǔn)字庫(kù)表圖2-2-6圖2-2-6LCD1602內(nèi)部顯示地址例如,如果第二行第一個(gè)字符的地址是40H,您是否可以直接寫入40H以將光標(biāo)定位在第二行第一個(gè)字符上?這是不可能的,因?yàn)樵趯懭腼@示地址時(shí),請(qǐng)求的最高位D7總是高電平1,因此實(shí)際寫入的數(shù)據(jù)應(yīng)該是01000000B(40H)+10000000B(80h)=11000000B(C0H)。在初始化液晶顯示模塊時(shí),首先要設(shè)置顯示模式,液晶顯示模塊中顯示的字符的時(shí)標(biāo)主動(dòng)向右移動(dòng),不需要人工干預(yù)。每次輸入前確定LCD模塊是否忙。1602液晶顯示模塊中的字符生成存儲(chǔ)器(cgrom)存儲(chǔ)了160種不同的點(diǎn)陣字符圖形。這些字符包括阿拉伯?dāng)?shù)字、英文字母的大小寫、常用符號(hào)和日語(yǔ)假名。每個(gè)字符都有一個(gè)固定的代碼。例如,大寫英文字母“a”的代碼為01000001b(41h)。模塊顯示地址41當(dāng)顯示H中的點(diǎn)陣字符圖時(shí),我們可以看到字母“a”。圖2-2-7液晶顯示電路2.2.6DS1302原理及說明(1)時(shí)鐘芯片DS1302的工作原理:每次讀寫程序前,必須對(duì)DS1302進(jìn)行初始化。首先,將SCLK端設(shè)置為“0”,然后將rst端設(shè)置為“1”,最后給出SCLK脈沖。讀/寫順序如下圖2.2所示。圖2.1顯示了DS1302的主字。主字的第7位必須設(shè)置為1。如果為0,則無法向DS1302讀取或?qū)懭霐?shù)據(jù)。對(duì)于位6,如果ram=1表示程序讀/寫,CK=0表示時(shí)間讀/寫。位1到5表示操作單元的地址。位0是讀/寫操作位。當(dāng)執(zhí)行讀取操作時(shí),位為1;當(dāng)位為0時(shí),執(zhí)行寫操作。主字節(jié)總是從最低位輸入/輸出。表2.2顯示了DS1302的日歷和時(shí)間存儲(chǔ)設(shè)備的內(nèi)容:“ch”是時(shí)鐘暫停標(biāo)記位。位為1時(shí),時(shí)鐘振蕩器停止,DS1302處于低功耗狀態(tài);位為0時(shí),時(shí)鐘開始運(yùn)行。“WP”是寫掩碼位。在對(duì)時(shí)鐘和ram進(jìn)行任何寫操作之前,WP必須為0。當(dāng)“WP”為1時(shí),寫入掩碼位防止寫入任何寄存器。(2)DS1302的主字DS1302的主字如圖2.1所示。主字節(jié)的高有效位(位7)必須是邏輯1。如果為0,則無法將數(shù)據(jù)寫入DS1302。如果位6為0,則可以訪問日歷時(shí)鐘數(shù)據(jù)。如果位1為1,則可以訪問RAM數(shù)據(jù)。位5到1指示操作單元的地址。如果位0為0,則可以執(zhí)行寫操作。如果位1是1,則可以執(zhí)行讀取操作。主字節(jié)總是從最低位終端輸出打開。圖2-2-8DS1302的控制字(3)當(dāng)指令字輸入后的下一個(gè)SCLK時(shí)鐘的上升沿被抓住時(shí),數(shù)據(jù)被寫入DS1302,并且數(shù)據(jù)輸入從低位開始,即位0。類似地,在緊接8位主指令字之后的下一個(gè)SCLK脈沖的下邊緣處讀取DS1302的數(shù)據(jù),并且從低位0到高位7讀取數(shù)據(jù)。如圖2-2-9所示:圖2-2-9DS1302讀與寫的時(shí)序圖(3)DS1302寄存器DS1302有12個(gè)寄存器,其中7個(gè)寄存器與日歷和時(shí)鐘有關(guān)。存儲(chǔ)的數(shù)據(jù)位是BCD碼。日歷、時(shí)間寄存器及其主字見表2.2。表2.2DS1302的日歷、時(shí)間寄存器此外,DS1302還具有年存儲(chǔ)、主存儲(chǔ)、充電存儲(chǔ)、時(shí)鐘突發(fā)存儲(chǔ)和ram相關(guān)存儲(chǔ)。時(shí)鐘突發(fā)存儲(chǔ)設(shè)備可以一次順序地讀寫除充電存儲(chǔ)設(shè)備之外的存儲(chǔ)設(shè)備的所有內(nèi)容。DS1302ram相關(guān)存儲(chǔ)器可分為兩種:一種是單個(gè)ram單元,共31個(gè)字節(jié),每個(gè)單元配置為8位字節(jié),其命令主字為C0H~FDH,奇數(shù)為讀操作,偶數(shù)為寫操作;另一種是突發(fā)方式下的ram存儲(chǔ)器,它可以一次讀寫全部31字節(jié)的RAM,命令主字是FEH(寫)和FFH(讀)。圖2-2-10DS1302電路2.2.7DS18B20工作原理及說明DS18B20的讀寫時(shí)序和測(cè)溫原理與DS1820相同,只是溫度值的位數(shù)因分辨率不同而不同,溫度轉(zhuǎn)換的延遲時(shí)間從2s縮短到750ms,DS18B20測(cè)溫原理如所示圖2-1-10。圖中溫度系數(shù)較低的晶體振蕩器的振蕩頻率受溫度影響不大。它用于產(chǎn)生一個(gè)固定頻率的脈沖信號(hào),并將其發(fā)送到計(jì)數(shù)器1。高溫系數(shù)晶體振蕩器的振蕩速率隨溫度的變化而顯著變化,產(chǎn)生的信號(hào)作為計(jì)數(shù)器2的脈沖輸入。計(jì)數(shù)器1和溫度存儲(chǔ)預(yù)設(shè)為-55℃對(duì)應(yīng)的基值。計(jì)數(shù)器1對(duì)低溫系數(shù)晶體振蕩器產(chǎn)生的脈沖信號(hào)進(jìn)行減法計(jì)數(shù)。當(dāng)計(jì)數(shù)器1的預(yù)置值減為0時(shí),溫度存儲(chǔ)裝置的值將增加1,計(jì)數(shù)器1的預(yù)置值將重新加載。計(jì)數(shù)器1再次開始對(duì)低溫系數(shù)晶體振蕩器產(chǎn)生的脈沖信號(hào)進(jìn)行計(jì)數(shù)。此循環(huán)將停止溫度存儲(chǔ)裝置值的累積,直到計(jì)數(shù)器2計(jì)數(shù)為0,此時(shí),溫度存儲(chǔ)裝置中的值為測(cè)量溫度。圖2-1-10中的斜率累加器用于補(bǔ)償和修正溫度測(cè)量過程中的非線性,其輸出用于修正計(jì)數(shù)器1的預(yù)設(shè)值。

圖2-2-11DS18B20測(cè)溫原理框圖圖2-2-12DS18B20電路2.2.8按鍵電路按鍵是由一組按鍵或觸摸開關(guān)組成的陣列,是一種常用的輸入設(shè)備。鍵盤可分為編碼鍵盤和非編碼鍵盤1。編碼鍵盤通過硬件電路產(chǎn)生按鍵的按鍵代碼。該鍵盤程序簡(jiǎn)單,但硬件電路復(fù)雜,價(jià)格昂貴,單片機(jī)系統(tǒng)一般不采用。在非編碼鍵盤中,一些鍵通常排列成行矩陣。硬件邏輯與密鑰編碼之間沒有嚴(yán)格的對(duì)應(yīng)關(guān)系,但由所用程序決定。非編碼鍵盤的硬件接口簡(jiǎn)單,但占用CPU時(shí)間較長(zhǎng),因此通常采用可編程鍵盤管理芯片來克服這一缺陷。本設(shè)計(jì)采用兩種按鍵,一種是按鍵式非編碼鍵盤,另一種是觸摸式非編碼開關(guān),由于接線中有四個(gè)插腳,因此需要用萬(wàn)用表測(cè)量連接,然后將兩個(gè)插腳連接起來。原理圖如下為了計(jì)算數(shù)據(jù),必須先輸入數(shù)據(jù),還必須確認(rèn)按鍵輸入的值。這需要掃描鍵盤,以便確認(rèn)到底按了哪個(gè)鍵。圖2-2-13按鍵電路第三章軟件設(shè)計(jì)與分析3.1軟件設(shè)計(jì)的組成系統(tǒng)由延時(shí)子功能、LCD1602LCD寫入命令子功能、LCD1602LCD寫入數(shù)據(jù)子功能、DS18B20初始化子功能、DS18B20讀取1位數(shù)據(jù)子功能、讀取字節(jié)數(shù)據(jù)子功能、向DS18B20寫入字節(jié)數(shù)據(jù)子功能、DS18B20啟動(dòng)取溫轉(zhuǎn)換子功能組成,獲取溫度子函數(shù)、初始化子函數(shù)、DS1302地址子函數(shù)、數(shù)據(jù)發(fā)送子函數(shù)發(fā)送子函數(shù)、DS1302數(shù)據(jù)讀取子函數(shù)、DS1302初始化子函數(shù)、顯示年、月、日、周子函數(shù)、按鍵掃描子函數(shù)、主函數(shù)和數(shù)據(jù)定義。圖3-1-1DS1302讀取日期和時(shí)間流程圖圖3-1-2DS18B20溫度傳感器流程圖圖3-1-3時(shí)間調(diào)整程序流程圖圖3-1-4整體流程圖圖3-1-5DS1302讀寫程序流程圖3.2源程序#include<reg51.h>#include"DS18B20.h"uchara,b,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp,miao1,shi1=12,fen1=1,miao1=0,clock=0;//flag用于讀取頭文件中的溫度值,和顯示溫度值#defineyh0x80//LCD第一行的初始位置,因?yàn)長(zhǎng)CD1602字符地址首位D7恒定為1(100000000=80)#defineer0x80+0x40//LCD第二行初始位置(因?yàn)榈诙械谝粋€(gè)字符位置地址是0x40)//液晶屏的與C51之間的引腳連接定義(顯示數(shù)據(jù)線接C51的P0口)sbitrs=P2^0;sbiten=P2^2;sbitrw=P2^1;//如果硬件上rw接地,就不用寫這句和后面的rw=0了sbitled=P2^6;//LCD背光開關(guān)//DS1302時(shí)鐘芯片與C51之間的引腳連接定義sbitIO=P1^1;sbitSCLK=P1^0;sbitRST=P1^2;sbitCLO=P1^4;sbitACC0=ACC^0;sbitACC7=ACC^7;/************************************************************ACC累加器=AACC.0=E0HACC.0就是ACC的第0位。Acc可以位尋址。累加器ACC是一個(gè)8位的存儲(chǔ)單元,是用來放數(shù)據(jù)的。但是,這個(gè)存儲(chǔ)單元有其特殊的地位,是單片機(jī)中一個(gè)非常關(guān)鍵的單元,很多運(yùn)算都要通過ACC來進(jìn)行。以后在學(xué)習(xí)指令時(shí),常用A來表示累加器。但有一些地方例外,比如在PUSH指令中,就必須用ACC這樣的名字。一般的說法,A代表了累加器中的內(nèi)容、而ACC代表的是累加器的地址。***************************************************************///校時(shí)按鍵與C51的引腳連接定義sbitkey1=P1^5;//設(shè)置鍵sbitkey2=P1^6;//加鍵sbitkey3=P1^7;//減鍵sbitbuzzer=P1^3;//蜂鳴器,通過三極管9012驅(qū)動(dòng),端口低電平響/**************************************************************/ucharcodetab1[]={"20--"};//年顯示的固定字符ucharcodetab2[]={"::"};//時(shí)間顯示的固定字符ucharcodetab3[]={"HELLOWELCOME"};//開機(jī)動(dòng)畫//延時(shí)函數(shù),后面經(jīng)常調(diào)用voiddelay(uintxms)//延時(shí)函數(shù),有參函數(shù){ uintx,y; for(x=xms;x>0;x--) for(y=110;y>0;y--);}/********液晶寫入指令函數(shù)與寫入數(shù)據(jù)函數(shù),以后可調(diào)用**************//*在這個(gè)程序中,液晶寫入有關(guān)函數(shù)會(huì)在DS1302的函數(shù)中調(diào)用,所以液晶程序要放在前面*/voidwrite_1602com(ucharcom)//****液晶寫入指令函數(shù)****{ rs=0;//數(shù)據(jù)/指令選擇置為指令 rw=0;//讀寫選擇置為寫 P0=com;//送入數(shù)據(jù) delay(1); en=1;//拉高使能端,為制造有效的下降沿做準(zhǔn)備 delay(1); en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令}voidwrite_1602dat(uchardat)//***液晶寫入數(shù)據(jù)函數(shù)****{ rs=1;//數(shù)據(jù)/指令選擇置為數(shù)據(jù) rw=0;//讀寫選擇置為寫 P0=dat;//送入數(shù)據(jù) delay(1); en=1;//en置高電平,為制造下降沿做準(zhǔn)備 delay(1); en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令}voidlcd_init()//***液晶初始化函數(shù)****{ ucharj;write_1602com(0x0f|0x08); for(a=0;a<17;a++) write_1602dat(tab3[a]); j=17; while(j--) { write_1602com(0x1c);//循環(huán)左移 delay(700); } write_1602com(0x01); delay(10); write_1602com(0x38);//設(shè)置液晶工作模式,意思:16*2行顯示,5*7點(diǎn)陣,8位數(shù)據(jù) write_1602com(0x0c);//開顯示不顯示光標(biāo) write_1602com(0x06);//整屏不移動(dòng),光標(biāo)自動(dòng)右移 write_1602com(0x01);//清顯示 /***開機(jī)動(dòng)畫顯示hellowelcomedianzizhong****/ write_1602com(yh+1);//日歷顯示固定符號(hào)從第一行第1個(gè)位置之后開始顯示 for(a=0;a<14;a++) { write_1602dat(tab1[a]);//向液晶屏寫日歷顯示的固定符號(hào)部分 //delay(3); } write_1602com(er+2);//時(shí)間顯示固定符號(hào)寫入位置,從第2個(gè)位置后開始顯示 for(a=0;a<8;a++) { write_1602dat(tab2[a]);//寫顯示時(shí)間固定符號(hào),兩個(gè)冒號(hào) //delay(3); } write_1602com(er+0); write_1602dat(0x24); write_1602com(er+1); write_1602dat(0x20);}/***************DS1302有關(guān)子函數(shù)********************/voidwrite_byte(uchardat)//寫一個(gè)字節(jié){ ACC=dat; RST=1; for(a=8;a>0;a--) { IO=ACC0; SCLK=0; SCLK=1; ACC=ACC>>1; }}ucharread_byte()//讀一個(gè)字節(jié){ RST=1; for(a=8;a>0;a--) { ACC7=IO; SCLK=1; SCLK=0; ACC=ACC>>1; } return(ACC);}//voidwrite_1302(ucharadd,uchardat)//向1302芯片寫函數(shù),指定寫入地址,數(shù)據(jù){ RST=0; SCLK=0; RST=1; write_byte(add); write_byte(dat); SCLK=1; RST=0;}ucharread_1302(ucharadd)//從1302讀數(shù)據(jù)函數(shù),指定讀取數(shù)據(jù)來源地址{ uchartemp; RST=0; SCLK=0; RST=1; write_byte(add); temp=read_byte(); SCLK=1; RST=0; return(temp);}ucharBCD_Decimal(ucharbcd)//BCD碼轉(zhuǎn)十進(jìn)制函數(shù),輸入BCD,返回十進(jìn)制{ ucharDecimal; Decimal=bcd>>4; return(Decimal=Decimal*10+(bcd&=0x0F));}//voidds1302_init()//1302芯片初始化子函數(shù)(2010-01-07,12:00:00,week4){ RST=0; SCLK=0; write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x80,0x00);//向DS1302內(nèi)寫秒寄存器80H寫入初始秒數(shù)據(jù)00 write_1302(0x82,0x00);//向DS1302內(nèi)寫分寄存器82H寫入初始分?jǐn)?shù)據(jù)00 write_1302(0x84,0x12);//向DS1302內(nèi)寫小時(shí)寄存器84H寫入初始小時(shí)數(shù)據(jù)12 write_1302(0x8a,0x01);//向DS1302內(nèi)寫周寄存器8aH寫入初始周數(shù)據(jù)4 write_1302(0x86,0x08);//向DS1302內(nèi)寫日期寄存器86H寫入初始日期數(shù)據(jù)07 write_1302(0x88,0x07);//向DS1302內(nèi)寫月份寄存器88H寫入初始月份數(shù)據(jù)01 write_1302(0x8c,0x10);//向DS1302內(nèi)寫年份寄存器8cH寫入初始年份數(shù)據(jù)10 write_1302(0x8e,0x80);//打開寫保護(hù)}////溫度顯示子函數(shù)voidwrite_temp(ucharadd,uchardat)//向LCD寫溫度數(shù)據(jù),并指定顯示位置{ uchargw,sw,bw; if(dat>=0&&dat<=128) { gw=dat%10;//取得個(gè)位數(shù)字 sw=dat%100/10;//取得十位數(shù)字 bw=dat/100 ;//取得百位數(shù)字 } else { dat=256-dat; gw=dat%10;//取得個(gè)位數(shù)字 sw=dat%100/10;//取得十位數(shù)字 bw=-3; //0x30-3表示為負(fù)號(hào) } write_1602com(er+add);//er是頭文件規(guī)定的值0x80+0x40 write_1602dat(0x30+bw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 write_1602dat(0x30+sw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 write_1602dat(0x30+gw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼write_1602dat(0xdf);//顯示溫度的小圓圈符號(hào),0xdf是液晶屏字符庫(kù)的該符號(hào)地址碼 write_1602dat(0x43); //顯示"C"符號(hào),0x43是液晶屏字符庫(kù)里大寫C的地址碼 }////時(shí)分秒顯示子函數(shù)voidwrite_sfm(ucharadd,uchardat)//向LCD寫時(shí)分秒,有顯示位置加、現(xiàn)示數(shù)據(jù),兩個(gè)參數(shù){ uchargw,sw; gw=dat%10;//取得個(gè)位數(shù)字 sw=dat/10;//取得十位數(shù)字 write_1602com(er+add);//er是頭文件規(guī)定的值0x80+0x40 write_1602dat(0x30+sw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 write_1602dat(0x30+gw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 }////年月日顯示子函數(shù)voidwrite_nyr(ucharadd,uchardat)//向LCD寫年月日,有顯示位置加數(shù)、顯示數(shù)據(jù),兩個(gè)參數(shù){ uchargw,sw; gw=dat%10;//取得個(gè)位數(shù)字 sw=dat/10;//取得十位數(shù)字 write_1602com(yh+add);//設(shè)定顯示位置為第一個(gè)位置+add write_1602dat(0x30+sw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 write_1602dat(0x30+gw);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 }//voidwrite_week(ucharweek)//寫星期函數(shù){ write_1602com(yh+0x0c);//星期字符的顯示位置 switch(week) { case1: write_1602dat('M');//星期數(shù)為1時(shí),顯示 write_1602dat('O'); write_1602dat('N'); break; case2: write_1602dat('T');//星期數(shù)據(jù)為2時(shí)顯示 write_1602dat('U'); write_1602dat('E'); break; case3: write_1602dat('W');//星期數(shù)據(jù)為3時(shí)顯示 write_1602dat('E'); write_1602dat('D'); break; case4: write_1602dat('T');//星期數(shù)據(jù)為4是顯示 write_1602dat('H'); write_1602dat('U'); break; case5: write_1602dat('F');//星期數(shù)據(jù)為5時(shí)顯示 write_1602dat('R'); write_1602dat('I'); break; case6: write_1602dat('S');//星期數(shù)據(jù)為6時(shí)顯示 write_1602dat('T'); write_1602dat('A'); break; case7: write_1602dat('S');//星期數(shù)據(jù)為7時(shí)顯示 write_1602dat('U'); write_1602dat('N'); break; }}//****************鍵盤掃描有關(guān)函數(shù)**********************voidkeyscan(){ if(key1==0)//key1為功能鍵(設(shè)置鍵) { delay(9);//延時(shí),用于消抖動(dòng) if(key1==0)//延時(shí)后再次確認(rèn)按鍵按下 { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key1); key1n++; if(key1n==12) key1n=1;//設(shè)置按鍵共有秒、分、時(shí)、星期、日、月、年、返回,8個(gè)功能循環(huán) switch(key1n) { case1:TR0=0;//關(guān)閉定時(shí)器 //TR1=0; write_1602com(er+0x09);//設(shè)置按鍵按動(dòng)一次,秒位置顯示光標(biāo) write_1602com(0x0f);//設(shè)置光標(biāo)為閃爍 temp=(miao)/10*16+(miao)%10;//秒數(shù)據(jù)寫入DS1302 write_1302(0x8e,0x00); write_1302(0x80,0x80|temp);//miao write_1302(0x8e,0x80); break; case2:write_1602com(er+6);//按2次fen位置顯示光標(biāo) //write_1602com(0x0f); break; case3:write_1602com(er+3);//按動(dòng)3次,shi //write_1602com(0x0f); break; case4:write_1602com(yh+0x0e);//按動(dòng)4次,week //write_1602com(0x0f); break; case5:write_1602com(yh+0x0a);//按動(dòng)5次,ri //write_1602com(0x0f); break; case6:write_1602com(yh+0x07);//按動(dòng)6次,yue //write_1602com(0x0f); break; case7:write_1602com(yh+0x04);//按動(dòng)7次,nian //write_1602com(0x0f); break; case8:write_1602com(er+1); write_1602dat(0x4d); write_1602com(er+1); break; case9:write_1602com(er+1); write_1602dat(0x46); write_1602com(er+1); break; case10:write_1602com(er+1); write_1602dat(0x53); write_1602com(er+1); break; case11: write_1602com(er+1); write_1602dat(0x20); write_1602com(0x0c);//按動(dòng)到第8次,設(shè)置光標(biāo)不閃爍 TR0=1;//打開定時(shí)器 temp=(miao)/10*16+(miao)%10; write_1302(0x8e,0x00); write_1302(0x80,0x00|temp);//miao數(shù)據(jù)寫入DS1302 write_1302(0x8e,0x80); break; } } } //加鍵key2 if(key1n!=0)//當(dāng)key1按下以下。再按以下鍵才有效(按鍵次數(shù)不等于零) { if(key2==0)//上調(diào)鍵 { delay(10); if(key2==0) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key2); switch(key1n) { case1: miao++;//設(shè)置鍵按動(dòng)1次,調(diào)秒 if(miao==60) miao=0;//秒超過59,再加1,就歸零 write_sfm(0x08,miao);//令LCD在正確位置顯示"加"設(shè)定好的秒數(shù) temp=(miao)/10*16+(miao)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x80,temp);//向DS1302內(nèi)寫秒寄存器80H寫入調(diào)整后的秒數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+0x09);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,光標(biāo)自動(dòng)右移,所以要指定返回 //write_1602com(0x0b); break; case2: fen++; if(fen==60) fen=0; write_sfm(0x05,fen);//令LCD在正確位置顯示"加"設(shè)定好的分?jǐn)?shù)據(jù) temp=(fen)/10*16+(fen)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x82,temp);//向DS1302內(nèi)寫分寄存器82H寫入調(diào)整后的分?jǐn)?shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+6);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case3: shi++; if(shi==24) shi=0; write_sfm(2,shi);//令LCD在正確的位置顯示"加"設(shè)定好的小時(shí)數(shù)據(jù) temp=(shi)/10*16+(shi)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x84,temp);//向DS1302內(nèi)寫小時(shí)寄存器84H寫入調(diào)整后的小時(shí)數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+3);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case4: week++; if(week==8) week=1; write_1602com(yh+0x0C);//指定'加'后的周數(shù)據(jù)顯示位置 write_week(week);//指定周數(shù)據(jù)顯示內(nèi)容 temp=(week)/10*16+(week)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x8a,temp);//向DS1302內(nèi)寫周寄存器8aH寫入調(diào)整后的周數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+0x0e);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case5: ri++; switch(yue) { case1: case3: case5: case7: case8: case10: case12: if(ri>31) ri=1; break; case2: if(nian%4==0||nian%400==0) { if(ri>29) ri=1; } else { if(ri>28) ri=1; } break; case4: case6: case9: case11: ri++; if(ri>30) ri=1; break; } write_nyr(9,ri);//令LCD在正確的位置顯示"加"設(shè)定好的日期數(shù)據(jù) temp=(ri)/10*16+(ri)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x86,temp);//向DS1302內(nèi)寫日期寄存器86H寫入調(diào)整后的日期數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+10);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case6: yue++; if(yue==13) yue=1; write_nyr(6,yue);//令LCD在正確的位置顯示"加"設(shè)定好的月份數(shù)據(jù) temp=(yue)/10*16+(yue)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x88,temp);//向DS1302內(nèi)寫月份寄存器88H寫入調(diào)整后的月份數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+7);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case7: nian++; if(nian==100) nian=0; write_nyr(3,nian);//令LCD在正確的位置顯示"加"設(shè)定好的年份數(shù)據(jù) temp=(nian)/10*16+(nian)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x8c,temp);//向DS1302內(nèi)寫年份寄存器8cH寫入調(diào)整后的年份數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+4);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case8: write_1602com(er+9);//設(shè)置鬧鐘的秒定時(shí) miao1++; if(miao1==60) miao1=0; write_sfm(0x08,miao1);//令LCD在正確位置顯示"加"設(shè)定好秒的數(shù)據(jù) write_1602com(er+9);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case9: write_1602com(er+6);//設(shè)置鬧鐘的分鐘定時(shí) fen1++; if(fen1==60) fen1=0; write_sfm(0x05,fen1);//令LCD在正確位置顯示"加"設(shè)定好的分?jǐn)?shù)據(jù) write_1602com(er+6);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case10:write_1602com(er+3);//設(shè)置鬧鐘的小時(shí)定時(shí) shi1++; if(shi1==24) shi1=0; write_sfm(0x02,shi1);//令LCD在正確的位置顯示"加"設(shè)定好的小時(shí)數(shù)據(jù) write_1602com(er+3);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; } } } //減鍵key3,各句功能參照'加鍵'注釋 if(key3==0) { delay(10);//調(diào)延時(shí),消抖動(dòng) if(key3==0) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key3); switch(key1n) { case1: miao--; if(miao==-1) miao=59;//秒數(shù)據(jù)減到-1時(shí)自動(dòng)變成59 write_sfm(0x08,miao);//在LCD的正確位置顯示改變后新的秒數(shù) temp=(miao)/10*16+(miao)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x80,temp);//向DS1302內(nèi)寫秒寄存器80H寫入調(diào)整后的秒數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+0x09);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 //write_1602com(0x0b); break; case2: fen--; if(fen==-1) fen=59; write_sfm(5,fen); temp=(fen)/10*16+(fen)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x82,temp);//向DS1302內(nèi)寫分寄存器82H寫入調(diào)整后的分?jǐn)?shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+6);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case3: shi--; if(shi==-1) shi=23; write_sfm(2,shi); temp=(shi)/10*16+(shi)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x84,temp);//向DS1302內(nèi)寫小時(shí)寄存器84H寫入調(diào)整后的小時(shí)數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(er+3);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case4: week--; if(week==0) week=7; write_1602com(yh+0x0C);//指定'加'后的周數(shù)據(jù)顯示位置 write_week(week);//指定周數(shù)據(jù)顯示內(nèi)容 temp=(week)/10*16+(week)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x8a,temp);//向DS1302內(nèi)寫周寄存器8aH寫入調(diào)整后的周數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+0x0e);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case5: ri--; switch(yue) { case1: case3: case5: case7: case8: case10: case12: if(ri==0) ri=31; break; case2:if(nian%4==0||nian%400==0) { if(ri==0) ri=29; } else { if(ri==0) ri=28; } break; case4: case6: case9: case11: if(ri==0) ri=30; break; } write_nyr(9,ri); temp=(ri)/10*16+(ri)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x86,temp);//向DS1302內(nèi)寫日期寄存器86H寫入調(diào)整后的日期數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+10);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case6: yue--; if(yue==0) yue=12; write_nyr(6,yue); temp=(yue)/10*16+(yue)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x88,temp);//向DS1302內(nèi)寫月份寄存器88H寫入調(diào)整后的月份數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+7);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case7: nian--; if(nian==-1) nian=99; write_nyr(3,nian); temp=(nian)/10*16+(nian)%10;//十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護(hù) write_1302(0x8c,temp);//向DS1302內(nèi)寫年份寄存器8cH寫入調(diào)整后的年份數(shù)據(jù)BCD碼 write_1302(0x8e,0x80);//打開寫保護(hù) write_1602com(yh+4);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; case8: write_1602com(er+9);//設(shè)置鬧鐘的秒定時(shí) miao1--; if(miao1==-1) miao1=59; write_sfm(0x08,miao1);//令LCD在正確位置顯示"加"設(shè)定好秒的數(shù)據(jù) write_1602com(er+9);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case9: write_1602com(er+6);//設(shè)置鬧鐘的分鐘定時(shí) fen1--; if(fen1==-1) fen1=59; write_sfm(0x05,fen1);//令LCD在正確位置顯示"加"設(shè)定好的分?jǐn)?shù)據(jù) write_1602com(er+6);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,在這里是寫回原來的位置 break; case10:write_1602com(er+3);//設(shè)置鬧鐘的小時(shí)定時(shí) shi1--; if(shi1==-1) shi1=23; write_sfm(0x02,shi1);//令LCD在正確的位置顯示"加"設(shè)定好的小時(shí)數(shù)據(jù) write_1602com(er+3);//因?yàn)樵O(shè)置液晶的模式是寫入數(shù)據(jù)后,指針自動(dòng)加一,所以需要光標(biāo)回位 break; } } } }}//定時(shí)器0初始化程序voidinit()//定時(shí)器、計(jì)數(shù)器設(shè)置函數(shù){ TMOD=0x11;//指定定時(shí)/計(jì)數(shù)器的工作方式為1 TH0=0;//定時(shí)器T0的高四位=0 TL0=0;//定時(shí)器T0的低四位=0 EA=1;//系統(tǒng)允許有開放的中斷 ET0=1;//允許T0中斷 TR0=1;//開啟中斷,啟動(dòng)定時(shí)器}//*******************主函數(shù)**************************//***************************************************voidmain(){ lcd_init();//調(diào)用液晶屏初始化子函數(shù) ds1302_init();//調(diào)用DS1302時(shí)鐘的初始化子函數(shù) init();//調(diào)用定時(shí)計(jì)數(shù)器的設(shè)置子函數(shù) led=0;//打開LCD的背光電源buzzer=0;//蜂鳴器長(zhǎng)響一次delay(80);buzzer=1; while(1)//無限循環(huán)下面的語(yǔ)句: { keyscan();//調(diào)用鍵盤掃描子函數(shù)}}/*************通過定時(shí)中斷實(shí)現(xiàn)定是獨(dú)處并顯示數(shù)據(jù)******************/voidt0()interrupt1//取得并顯示日歷和時(shí)間{ //Init_DS18B20();//溫度傳感器DS18b2初始化子函數(shù),在頭文件中 flag=ReadTemperature();//將18b2頭文件運(yùn)行返回的函數(shù)結(jié)果送到變量FLAG中,用于顯示 //讀取秒時(shí)分周日月年七個(gè)數(shù)據(jù)(DS1302的讀寄存器與寫寄存器不一樣): miao=BCD_Decimal(read_1302(0x81)); fen=BCD_Decimal(read_1302(0x83)); shi=BCD_Decimal(read_1302(0x85)); ri=BCD_Decimal(read_1302(0x87)); yue=BCD_Decimal(read_1302(0x89)); nian=BCD_Decimal(read_1302(0x8d)); week=BCD_Decimal(read_1302(0x8b)); //顯示溫度、秒、時(shí)、分?jǐn)?shù)據(jù): write_temp(12,flag);//顯示溫度,從第二行第12個(gè)字符后開始顯示 write_sfm(8,miao);//秒,從第二行第8個(gè)字后開始顯示(調(diào)用時(shí)分秒顯示子函數(shù)) write_sfm(5,fen);//分,從第二行第5個(gè)字符后開始顯示 write_sfm(2,shi);//小時(shí),從第二行第2個(gè)字符后開始顯示 //顯示日、月、年數(shù)據(jù): write_nyr(9,ri);//日期,從第二行第9個(gè)字符后開始顯示 write_nyr(6,yue);//月份,從第二行第6個(gè)字符后開始顯示 write_nyr(3,nian);//年,從第二行第3個(gè)字符后開始顯示 write_week(week); /***********整點(diǎn)報(bào)時(shí)程序************/ if(fen==0&&miao==0) if(shi<22&&shi>6) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; } /**************鬧鐘程序:將暫停鍵按下停止蜂鳴********************/ if(shi1==shi&&fen1==fen&&miao==0) { clock=1; } if(clock==1) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; } if(CLO==0) /*按下p1.4停止蜂鳴*/ clock=0; }typedefunsignedcharuchar;typedefunsignedintuint;sbitDQ=P3^3;//定義DQ引腳為P3.3/*******************************延時(shí)函數(shù)*********************************功能:在11.059MHz的晶振條件下調(diào)用本函數(shù)需要24μs,然后每次計(jì)數(shù)需16μs**************************************************************************/voidDS18_delay(intuseconds){ ints; for(s=0;s<useconds;s++);}/*******************************復(fù)位函數(shù)********************************功能:完成單總線的復(fù)位操作。*復(fù)位時(shí)間為480μs,因此延時(shí)時(shí)間為(480-24)/16=28.5,取29μs。*經(jīng)過70μs之后檢測(cè)存在脈沖,因此延時(shí)時(shí)間為(70-24)/16=2.875,取3μs。**********************************************************************

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論