LED數(shù)顯溫度控制器設(shè)計(jì)論述
現(xiàn)代社會(huì), 單片機(jī)技術(shù)已經(jīng)成為一種比較成熟的技術(shù), 它已經(jīng)普及到我們生活、 工作、科研、 各個(gè)領(lǐng)域中, 溫度也是日常生活中最基本的環(huán)境參數(shù), 它與我們的生活工作密切相關(guān), 本文主要介紹了一個(gè)基于AT89C51單片機(jī)的溫度控制報(bào)警系統(tǒng), 采用溫度傳感器DS18B20的溫度上下限報(bào)警器, 能夠自動(dòng)測(cè)量當(dāng)前環(huán)境溫度, 由單片機(jī)AT89C2051控制, 并通過(guò)三位段數(shù)碼管顯示提示, 如果目前環(huán)境溫度超過(guò)此溫度, 系統(tǒng)會(huì)發(fā)出報(bào)警。 采用的單片機(jī)AT89C51做信號(hào)處理單元, 其成本低廉, 精確度高, LED顯示測(cè)量數(shù)值, 選用紅外傳感器采集人體信號(hào), 經(jīng)過(guò)放大整形電路后傳送給單片機(jī)AT89C51來(lái)處理, 最后該信號(hào)傳送至LED顯示屏。
該系統(tǒng)能夠方便的實(shí)現(xiàn)溫度的采集和顯示, 并根據(jù)需要可任意設(shè)定報(bào)警溫度, 它使用起來(lái)非常方便, 具有體積小、 精度高、 量程寬、 靈敏度高、 功耗低等優(yōu)點(diǎn), 適用于我們?nèi)粘I詈凸ぁ?農(nóng)業(yè)生產(chǎn)中的溫度控制, 也可以作為其他主系統(tǒng)的輔助擴(kuò)展, 當(dāng)作溫度處理模塊嵌入其它系統(tǒng)中。 DS18B20與AT89C51的結(jié)合實(shí)現(xiàn)了最簡(jiǎn)溫度控制系統(tǒng), 該系統(tǒng)抗干擾能力強(qiáng), 結(jié)構(gòu)簡(jiǎn)單, 對(duì)惡劣環(huán)境下進(jìn)行現(xiàn)場(chǎng)溫度的控制也適合, 應(yīng)用前景較為廣泛。
關(guān)鍵詞 : 單片機(jī); 溫度控制; AT89C51; DS18B20;
1 引言
1.1 研究的背景與意義
無(wú)論是在日常生活中, 還是在工業(yè)生產(chǎn)過(guò)程中溫度控制都起著非常重要的作用。 本次畢業(yè)設(shè)計(jì)選題的目的主要是讓生活在信息發(fā)達(dá)時(shí)代的我們, 把所學(xué)的知識(shí)應(yīng)用于生活生產(chǎn)當(dāng)中, 熟練掌握系統(tǒng)總體設(shè)計(jì)的流程, 方案的論證, 選擇, 實(shí)施與完善。 隨著社會(huì)經(jīng)濟(jì)的快速發(fā)展, 現(xiàn)在越來(lái)越多的生產(chǎn)部門(mén)及生產(chǎn)環(huán)節(jié)對(duì)溫度控制精度的可靠性和穩(wěn)定性等有了更高的要求。 由于苛刻的生產(chǎn)環(huán)節(jié)對(duì)溫度要求較高, 而傳統(tǒng)的溫度控制器控制精度卻普遍不高, 已經(jīng)不能滿足其要求。當(dāng)今社會(huì), 溫度是工業(yè)對(duì)象中的一個(gè)重要的被控參數(shù), 它的測(cè)量與控制系統(tǒng)在生產(chǎn)與生活的各個(gè)領(lǐng)域中扮演著越來(lái)越重要的角色, 大到工業(yè)煉金, 環(huán)境檢測(cè), 分離物質(zhì), 機(jī)房電力, 糧倉(cāng), 凍庫(kù), 衛(wèi)生醫(yī)療等方面, 小到家庭空調(diào), 冰箱, 電飯煲, 太陽(yáng)能熱水器等方面都得到了廣泛的應(yīng)用, 溫度控制系統(tǒng)的廣泛應(yīng)用也使得這方面研究意義非常的重要。
1.2 國(guó)內(nèi)外研究現(xiàn)狀
雖然溫度控制系統(tǒng)在國(guó)內(nèi)各行各業(yè)己經(jīng)得到廣泛應(yīng)用, 但從國(guó)內(nèi)生產(chǎn)的溫度控制器來(lái)說(shuō), 總體發(fā)展水平仍然不高, 同美國(guó)、 日本、 德國(guó)等先進(jìn)發(fā)達(dá)國(guó)家相比, 仍有著較大的差距。 20世紀(jì)70年代, 國(guó)外就對(duì)溫度控制技術(shù)有研究。 先是采用模擬式的組合儀表, 采集現(xiàn)場(chǎng)信息并進(jìn)行指示、 記錄和控制。 80年代末就出現(xiàn)了分布式控制系統(tǒng)。 現(xiàn)在正在開(kāi)發(fā)和研制計(jì)算機(jī)數(shù)據(jù)采集控制系統(tǒng)的多因子綜合控制系統(tǒng)。 現(xiàn)在世界各國(guó)的溫度測(cè)控技術(shù)發(fā)展很快, 一些國(guó)家在實(shí)現(xiàn)自動(dòng)化的基礎(chǔ)上正向著完全自動(dòng)化、 無(wú)人化的方向發(fā)展。 我國(guó)研究溫度測(cè)控技術(shù)較晚, 20世紀(jì)80年代開(kāi)始, 在吸收發(fā)達(dá)國(guó)家溫度測(cè)控技術(shù)的基礎(chǔ)上, 我國(guó)工程技術(shù)人員才掌握了溫度室內(nèi)微機(jī)控制技術(shù), 這項(xiàng)技術(shù)僅限于對(duì)溫度的單項(xiàng)環(huán)境因子的控制。 我國(guó)溫度測(cè)控設(shè)施的計(jì)算機(jī)應(yīng)用, 在總體上正從消化吸收、 簡(jiǎn)單應(yīng)用階段過(guò)渡和發(fā)展。在技術(shù)上, 以單片機(jī)控制的單參數(shù)單回路系統(tǒng)居多, 尚無(wú)真正意義上的多參數(shù)綜合控制系統(tǒng), 與發(fā)達(dá)國(guó)家相比, 存在較大差距。
2 設(shè)計(jì)的內(nèi)容及性能指標(biāo)
本設(shè)計(jì)主要是介紹了單片機(jī)控制下的溫度報(bào)警系統(tǒng), 詳細(xì)介紹了其硬件和軟件設(shè)計(jì),并對(duì)其各功能模塊做了詳細(xì)介紹, 其主要功能和指標(biāo)如下: 單片機(jī)實(shí)時(shí)檢測(cè)溫度傳感器DS18B20 的狀態(tài), 并將 DS18820 得到的數(shù)據(jù)進(jìn)行處理。 上電后數(shù)碼管顯示當(dāng)前的環(huán)境溫度,通過(guò)按鍵可設(shè)置高低溫報(bào)警值, 當(dāng)檢測(cè)到的溫度高于設(shè)置的報(bào)警值的時(shí)候, 蜂鳴器報(bào)警同時(shí)報(bào)警燈閃爍, 溫度檢測(cè)精確到 0. 1 度。并具有掉電保存功能, 數(shù)據(jù)保存在單片機(jī)內(nèi)部 EEPOM中, 進(jìn)入設(shè)置界面后如果沒(méi)有鍵按下系統(tǒng)會(huì)在 15 秒后自動(dòng)退出設(shè)置界面。
3 系統(tǒng)方案比較、 設(shè)計(jì)與論證該系統(tǒng)主要由溫度測(cè)量和溫度設(shè)置及系統(tǒng)狀態(tài)顯示三部分電路組成, 下面介紹實(shí)現(xiàn)此系統(tǒng)功能的方案。
3.1 主控制器模塊
采用 STC89C52 單片機(jī)作為整個(gè)系統(tǒng)的核心, 用其控制行進(jìn)中的小車, 以實(shí)現(xiàn)其既定的性能指標(biāo)。 充分分析我們的系統(tǒng), 其關(guān)鍵在于實(shí)現(xiàn)小車的自動(dòng)控制, 而在這一點(diǎn)上, 單片機(jī)就顯現(xiàn)出來(lái)它的優(yōu)勢(shì)——控制簡(jiǎn)單、 方便、 快捷。 這樣一來(lái), 單片機(jī)就可以充分發(fā)揮其資源豐富、 有較為強(qiáng)大的控制功能及可位尋址操作功能、 價(jià)格低廉等優(yōu)點(diǎn)。 STC89C52 單片機(jī)具有功能強(qiáng)大的位操作指令, I/O 口均可按位尋址, 程序空間多達(dá) 8K, 對(duì)于本設(shè)計(jì)也綽綽有余, 更可貴的是 STC89C52 單片機(jī)價(jià)格非常低廉。
3.2 溫度測(cè)量
采用數(shù)字溫度芯片 DS18B20 測(cè)量實(shí)際溫度, 輸出信號(hào)全數(shù)字化。 便于單片機(jī)處理及控制, 省去傳統(tǒng)的測(cè)溫方法的很多外圍電路。 且該芯片的物理化學(xué)性很穩(wěn)定, 它能用做工業(yè)測(cè)溫元件, 此元件線形較好。 在0—100 攝氏度時(shí), 最大線形偏差小于1攝氏度。 DS18B20的最大特點(diǎn)之一采用了單總線的數(shù)據(jù)傳輸, 由數(shù)字溫度計(jì) DS18B20和微控制器 STC89C52構(gòu)成的溫度測(cè)量裝置, 它直接輸出溫度的數(shù)字信號(hào), 可直接與計(jì)算機(jī)連接。 這樣, 測(cè)溫系統(tǒng)的結(jié)構(gòu)就比較簡(jiǎn)單, 體積也不大。 采用51單片機(jī)控制, 軟件編程的自由度大, 可通過(guò)編程實(shí)現(xiàn)各種各樣的算術(shù)算法和邏輯控制, 而且體積小, 硬件實(shí)現(xiàn)簡(jiǎn)單, 安裝方便。 既可以單獨(dú)對(duì)多 DS18B20控制工作, 還可以與 PC 機(jī)通信上傳數(shù)據(jù), 另外 AT89C51在工業(yè)控制上也有著廣泛的應(yīng)用, 編程技術(shù)及外圍功能電路的配合使用都很成熟。
3.3 設(shè)置溫度
采用鍵盤(pán)輸入設(shè)置溫度, 鍵盤(pán)則可以用4個(gè)按鍵, 一個(gè)復(fù)位鍵, 一個(gè)功能設(shè)定鍵, 一個(gè)加減一個(gè)減鍵。 四個(gè)鍵比較常用, 而且用到的接口得到了極好的利用, 僅需要4個(gè)接口。
3.4 顯示模塊
用 LED 數(shù)碼管實(shí)現(xiàn)數(shù)值的顯示, LED 數(shù)碼管顯示相對(duì)來(lái)說(shuō)比較直觀、 明亮, 可以用動(dòng)態(tài)顯示和靜態(tài)顯示兩種方法編程實(shí)現(xiàn), 數(shù)碼管由于顯示速度快, 使用簡(jiǎn)單, 顯示效果簡(jiǎn)潔明了而得到了廣泛應(yīng)用。 LCD 雖然其顯示清晰, 顯示內(nèi)容豐富、 清晰, 顯示信息量大,使用方便, 顯示快速。 但對(duì)于此系統(tǒng)我們不需要顯示豐富的內(nèi)容, 而且 LCD 液晶價(jià)格貴,因此我們選擇用數(shù)碼管顯示。
3.5 電源選取
采用干電池供電。 干電池價(jià)格低廉、 攜帶方便、 運(yùn)用靈活, 經(jīng)過(guò)實(shí)驗(yàn)驗(yàn)證系統(tǒng)工作時(shí), 單片機(jī)、 傳感器的工作電壓穩(wěn)定能夠滿足系統(tǒng)的要求, 而且電池更換方便。
3.6 報(bào)警設(shè)備的論證與選擇
采用聲、 光同時(shí)報(bào)警, 既可以利用不同顏色的等對(duì)應(yīng)不同的狀態(tài)判別出此時(shí)的溫度處于的狀況, 又可以使工作人員在一定距離范圍內(nèi)監(jiān)測(cè)到溫度異常進(jìn)行及時(shí)處理。
4 系統(tǒng)器件選擇
. 溫度傳感器的選擇
由于傳統(tǒng)的熱敏電阻等測(cè)溫元件測(cè)出的一般都是電壓, 再轉(zhuǎn)換成對(duì)應(yīng)的溫度, 需要比較多的外部元件支持, 且硬件電路復(fù)雜, 制作成本相對(duì)較高。 這里采用 DALLAS 公司的數(shù)字溫度傳感器 DS18B20 作為測(cè)溫元件。
5 硬件實(shí)現(xiàn)及單元電路設(shè)計(jì)
5.1 主控制模塊
主控制最系統(tǒng)電路如圖 4 所示。
圖 4 單片主控電路
5.2 顯示模塊電路
顯示采用四位數(shù)碼管顯示, 當(dāng)位選打開(kāi)時(shí), 送入相應(yīng)的段碼, 則相應(yīng)的數(shù)碼管打開(kāi),關(guān)掉位選, 打開(kāi)另一個(gè)位選, 送入相應(yīng)的段碼, 則數(shù)碼管打開(kāi), 而每次打開(kāi)關(guān)掉相應(yīng)的位選時(shí), 時(shí)間間隔低于20ms, 從人類視覺(jué)的角度上看, 就仿佛是全部數(shù)碼管同時(shí)顯示的一樣。顯示電路如圖5
5.3 數(shù)碼管顯示驅(qū)動(dòng)電路
三極管 8550 來(lái)驅(qū)動(dòng) 4 位數(shù)碼管, 不僅簡(jiǎn)單, 而且價(jià)格便宜。
5.4 溫度傳感器(DS18B20)電路
5. 4. 1 DS18B20 基本介紹
DS18B20 是美國(guó) DALLAS 半導(dǎo)體公司推出的第一片支持“一線總線” 接口的溫度傳感器, 它具有微型化、 低功耗、 高性能、 抗干擾能力強(qiáng)、 易配微處理器等優(yōu)點(diǎn), 可直接將溫度轉(zhuǎn)化成串行數(shù)字信號(hào)處理器處理。 DS18B20 進(jìn)行精確的溫度轉(zhuǎn)換, I/O 線必須保證在溫度轉(zhuǎn)換期間提供足夠的能量, 由于每個(gè) DS18B20 在溫度轉(zhuǎn)換期間工作電流達(dá)到 1mA, 當(dāng)幾個(gè)溫度傳感器掛在同一根 I/O 線上進(jìn)行多點(diǎn)測(cè)溫時(shí), 只靠 4. 7K 上拉電阻就無(wú)法提供足夠的能量, 會(huì)造成無(wú)法轉(zhuǎn)換溫度或溫度誤差極大。因此, 下圖電路只適應(yīng)于單一溫度傳感器測(cè)溫情況下使用, 不適宜采用電池供電系統(tǒng)中。 并且工作電源 VCC 必須保證在 5V, 當(dāng)電源電壓下降時(shí), 寄生電源能夠汲取的能量也降低, 會(huì)使溫度誤差變大。
5. 4. 2 DS18B20 控制方法DS18B20 有六條控制命令:
溫度轉(zhuǎn)換 44H 啟動(dòng) DS18B20 進(jìn)行溫度轉(zhuǎn)換
讀暫存器 BEH 讀暫存器 9 個(gè)字節(jié)內(nèi)容
寫(xiě)暫存器 4EH 將數(shù)據(jù)寫(xiě)入暫存器的 TH、 TL 字節(jié)
復(fù)制暫存器 48H 把暫存器的 TH、 TL 字節(jié)寫(xiě)到 E2RAM 中
重新調(diào) E2RAM B8H 把 E2RAM 中的 TH、 TL 字節(jié)寫(xiě)到暫存器 TH、 TL 字節(jié)
讀電源供電方式 B4H 啟動(dòng) DS18B20 發(fā)送電源供電方式的信號(hào)給主 CPU
5. 4. 3 DS18B20 供電方式
DS18B20可以采用兩種方式供電, 一種是采用電源供電方式, 此時(shí) DS18B20的1腳接地,2腳作為信號(hào)線, 3腳接電源。 另一種是寄生電源供電方式, 如圖3. 1所示單片機(jī)端口接單線總線, 為保證在有效的 DS18B20時(shí)鐘周期內(nèi)提供足夠的電流, 可用一個(gè)三極管來(lái)完成對(duì)總線的上拉。 本設(shè)計(jì)采用電源供電方式, P2. 2口接單線總線為保證在有效的 DS18B20時(shí)鐘周期內(nèi)提供足夠的電流, 可用一個(gè)上拉電阻和 STC89C52的 P2. 2來(lái)完成對(duì)總線的上拉。 當(dāng)DS18B20處于寫(xiě)存儲(chǔ)器操作和溫度 A/D 變換操作時(shí), 總線上必須有強(qiáng)的上拉, 上拉開(kāi)啟時(shí)間最大為10 μ s。 采用寄生電源供電方式是 VDD 和 GND 端均接地。 由于單線制只有一根線,因此發(fā)送接收口必須是三狀態(tài)的。 主機(jī)控制 DS18B20完成溫度轉(zhuǎn)換必須經(jīng)過(guò)3個(gè)步驟:
l 初始化。
l ROM 操作指令。
l 存儲(chǔ)器操作指令。
5. 6 蜂鳴器、 發(fā)光二極管報(bào)警電路
電路如圖8主要是用來(lái)設(shè)定溫度報(bào)警溫度的、 有高溫和低溫報(bào)警。
6 系統(tǒng)軟件設(shè)計(jì)
6. 1 程序結(jié)構(gòu)分析
主程序調(diào)用了 3 個(gè)子程序, 分別是數(shù)碼管顯示程序、 溫度信號(hào)處理程序、 按鍵設(shè)定報(bào)
警溫度程序。 溫度信號(hào)處理程序: 對(duì)溫度芯片送過(guò)來(lái)的數(shù)據(jù)進(jìn)行處理, 進(jìn)行判斷和顯示。 數(shù)碼管顯示程序: 向數(shù)碼管的顯示送數(shù), 控制系統(tǒng)的顯示部分。 按鍵設(shè)定程序: 可以設(shè)定低溫和高溫報(bào)警可精確到 0. 1 度。
6. 2 系統(tǒng)程序流圖
主程序的主要功能是負(fù)責(zé)溫度的實(shí)時(shí)顯示、 讀出并處理 DS18B20 的測(cè)量的當(dāng)前溫度值,溫度測(cè)量每 1s 進(jìn)行一次。 這樣可以在一秒之內(nèi)測(cè)量一次被測(cè)溫度, 主程序的主要功能是負(fù)責(zé)溫度的實(shí)時(shí)顯示, 讀出并處理 DS18B20 的當(dāng)前溫度值, 與設(shè)定的報(bào)警溫度比較, 其程序流程見(jiàn)圖 9 所示。通過(guò)調(diào)用讀溫度子程序把存入內(nèi)存儲(chǔ)中的整數(shù)部分與小數(shù)部分開(kāi)分存放在不的的兩個(gè)單元中, 然后通過(guò)調(diào)用顯示子程序顯示出來(lái)。
6. 2. 1 DS18B20初始化程序流程圖在 DS18B20 工作之前需要進(jìn)行初始化, 流程圖如下:
6. 2. 2 讀溫度子程序流程圖
讀溫度子程序的主要功能是從DS18B20中讀出溫度數(shù)據(jù), 移入溫度暫存器保存。 其程序流程圖如下:
7 系統(tǒng)的安裝與調(diào)試
7. 1 安裝步驟
1. 檢查元件的好壞
按電路圖買好元件后首先檢查買回元件的好壞, 按各元件的檢測(cè)方法分別進(jìn)行檢測(cè),一定要仔細(xì)認(rèn)真。 而且要認(rèn)真核對(duì)原理圖是否一致, 在檢查好后才可上件、 焊件, 防止出現(xiàn)錯(cuò)誤焊件后不便改正。
2. 放置、 焊接各元件
按原理圖的位置放置各元件, 在放置過(guò)程中要先放置、 焊接較低的元件, 后焊較高的和要求較高的元件。 特別是容易損壞的元件要后焊, 在焊集成芯片時(shí)連續(xù)焊接時(shí)間不要超過(guò) 10s, 注意芯片的安裝方向。
7. 2 電路的調(diào)試
首先燒入顯示程序, 看顯示正不正常。 在調(diào)試程序時(shí), 發(fā)現(xiàn)有的指令用的不正確, 導(dǎo)
致電路功能不能完全實(shí)現(xiàn), 另外軟件程序中的延時(shí)有的過(guò)長(zhǎng)、 有的過(guò)短。 類似的現(xiàn)象還有
很多就不一一列舉了。
7. 3 本章小結(jié)
本章的主要內(nèi)容是電路的測(cè)試和調(diào)試注意事項(xiàng)
結(jié) 論
本溫度報(bào)警器, 通過(guò)單片機(jī)實(shí)時(shí)檢測(cè)溫度傳感器 DS18B20的狀態(tài), 并將 DS18820得到的數(shù)據(jù)進(jìn)行處理。 上電后數(shù)碼管顯示當(dāng)前的環(huán)境溫度, 通過(guò)按鍵可設(shè)置高低溫報(bào)警值, 當(dāng)檢測(cè)到的溫度高于設(shè)置的報(bào)警值的時(shí)候, 蜂鳴器報(bào)警同時(shí)報(bào)警燈閃爍, 溫度檢測(cè)精確到0. 1度。 并具有掉電保存功能, 數(shù)據(jù)保存在單片機(jī)內(nèi)部 EEPOM 中, 進(jìn)入設(shè)置界面后如果沒(méi)有鍵按下系統(tǒng)會(huì)在15秒后自動(dòng)退出設(shè)置界面。 由于采用了4節(jié)干電池供電使系統(tǒng)的抗干擾性得到加強(qiáng)。 在軟件上, 充分利用了 STC89C52的系統(tǒng)資源, 系統(tǒng)運(yùn)行流暢。本設(shè)計(jì)結(jié)構(gòu)簡(jiǎn)單, 調(diào)試方便, 系統(tǒng)反映快速靈活, 經(jīng)實(shí)驗(yàn)測(cè)試, 該溫度報(bào)警系統(tǒng)設(shè)計(jì)方案正確、 可行, 各項(xiàng)指標(biāo)穩(wěn)定、 可靠。
附錄 1 整體電路原理圖
附錄 2 部分源程序:
#include <reg52.h>
#include "eepom52.h"
#define uchar unsigned char
#define uint unsigned int
//數(shù)碼管段選定義 0 1 2 3 4 5 6 7 8 9
uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //斷碼
//數(shù)碼管位選定義
uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
uchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
uchar smg_i = 3; //顯示數(shù)碼管的個(gè)位數(shù)
sbit dq = P2^4; //18b20 IO 口的定義
sbit beep = P2^5; //蜂鳴器 IO 口定義
uchar a_a;
uint temperature ; //
bit flag_300ms ;
uchar key_can;
//按鍵值的變量
uchar menu_1; //菜單設(shè)計(jì)的變量
uint t_high = 300,t_low = 100;
bit flag_lj_en;
//按鍵連加使能
bit flag_lj_3_en; //按鍵連 3 次連加后使能 加的數(shù)就越大了
uchar key_time,flag_value; //用做連加的中間變量
bit key_500ms ;
uchar flag_clock;
uchar zd_break_en,zd_break_value; //自動(dòng)退出設(shè)置界面
/***********************1ms 延時(shí)函數(shù)*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/***********************小延時(shí)函數(shù)*****************************/
void delay_uint(uint q)
{
while(q--);
}
/***********************數(shù)碼顯示函數(shù)*****************************/
void display()
{
uchar i;
for(i=0;i<smg_i;i++)
{
P3 = smg_we[i];
//位選
P1 = dis_smg[i];
//段選
delay_1ms(1);
P3 = 0xff;
//位選
P1 = 0xff;
//消隱
}
}
/******************把數(shù)據(jù)保存到單片機(jī)內(nèi)部 eepom 中******************/
void write_eepom()
{
SectorErase(0x2000);
byte_write(0x2000, t_high % 256);
byte_write(0x2001, t_high / 256);
byte_write(0x2002, t_low % 256);
byte_write(0x2003, t_low / 256);
byte_write(0x2055, a_a);
}
/******************把數(shù)據(jù)從單片機(jī)內(nèi)部 eepom 中讀出來(lái)*****************/
void read_eepom()
{
t_high = byte_read(0x2001);
t_high <<= 8;
t_high |= byte_read(0x2000);
t_low = byte_read(0x2003);
t_low <<= 8;
t_low |= byte_read(0x2002);
a_a = byte_read(0x2055);
}
/***********************18b20 初始化函數(shù)*****************************/
void init_18b20()
{
bit q;
dq = 1;
//把總線拿高
delay_uint(1); //15us
dq = 0;
//給復(fù)位脈沖
delay_uint(80);
//750us
dq = 1;
//把總線拿高 等待
delay_uint(10);
//110us
q = dq;
//讀取 18b20 初始化信號(hào)
delay_uint(20);
//200us
dq = 1;
//把總線拿高 釋放總線
}
/*************寫(xiě) 18b20 內(nèi)的數(shù)據(jù)***************/
void write_18b20(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
//寫(xiě)數(shù)據(jù)是低位開(kāi)始
dq = 0;
//把總線拿低寫(xiě)時(shí)間隙開(kāi)始
dq = dat & 0x01; //向 18b20 總線寫(xiě)數(shù)據(jù)了
delay_uint(5); // 60us
dq = 1;
//釋放總線
dat >>= 1;
}
}
/*************讀取 18b20 內(nèi)的數(shù)據(jù)***************/
uchar read_18b20()
{
uchar i,value;
for(i=0;i<8;i++)
{
dq = 0;
//把總線拿低讀時(shí)間隙開(kāi)始
value >>= 1; //讀數(shù)據(jù)是低位開(kāi)始
dq = 1;
//釋放總線
if(dq == 1)
//開(kāi)始讀寫(xiě)數(shù)據(jù)
value |= 0x80;
delay_uint(5); //60us 讀一個(gè)時(shí)間隙最少要保持 60us 的時(shí)間
}
return value;
//返回?cái)?shù)據(jù)
}
/*************讀取溫度的值 讀出來(lái)的是小數(shù)***************/
uint read_temp()
{
uint value;
uchar low;
//在讀取溫度的時(shí)候如果中斷的太頻繁了, 就應(yīng)該把中斷給關(guān)了, 否則
會(huì)影響到 18b20 的時(shí)序
init_18b20(); //初始化 18b20
write_18b20(0xcc); //跳過(guò) 64 位 ROM
write_18b20(0x44); //啟動(dòng)一次溫度轉(zhuǎn)換命令
delay_uint(50);
//500us
init_18b20(); //初始化 18b20
write_18b20(0xcc); //跳過(guò) 64 位 ROM
write_18b20(0xbe); //發(fā)出讀取暫存器命令
EA = 0;
low = read_18b20(); //讀溫度低字節(jié)
value = read_18b20(); //讀溫度高字節(jié)
EA = 1;
value <<= 8;
//把溫度的高位左移 8 位
value |= low; //把讀出的溫度低位放到 value 的低八位中
value *= 0.625; //轉(zhuǎn)換到溫度值 小數(shù)
return value;
//返回讀出的溫度 帶小數(shù)
}
/*************定時(shí)器 0 初始化程序***************/
void time_init()
{
EA = 1; //開(kāi)總中斷
TMOD = 0X01; //定時(shí)器 0、 定時(shí)器 1 工作方式 1
ET0 = 1;
//開(kāi)定時(shí)器 0 中斷
TR0 = 1;
//允許定時(shí)器 0 定時(shí)
}
/****************獨(dú)立按鍵處理函數(shù)************************/
void key()
{
static uchar key_new = 0,key_old = 0,key_value = 0;
if(key_new == 0)
{
//按鍵松開(kāi)的時(shí)候做松手檢測(cè)
if((P2 & 0x0f) == 0x0f)
key_value ++;
else
key_value = 0;
if(key_value >= 10)
{
write_eepom();
key_value = 0;
key_new = 1;
flag_lj_en = 0; //關(guān)閉連加使能
flag_lj_3_en = 0; //關(guān)閉 3 秒后使能
flag_value = 0;
//清零
}
}
else
{
if((P2 & 0x0f) != 0x0f)
key_value ++; //按鍵按下的時(shí)候
else
key_value = 0;
if(key_value >= 7)
{
key_value = 0;
key_new = 0;
flag_lj_en = 1; //連加使能
zd_break_en = 1; //自動(dòng)退出設(shè)置界使能
zd_break_value = 0; //自動(dòng)退出設(shè)置界變量清零
}
}
key_can = 20;
if(key_500ms == 1)
{
key_500ms = 0;
zd_break_en = 1; //自動(dòng)退出設(shè)置界使能
zd_break_value = 0; //自動(dòng)退出設(shè)置界變量清零
key_new = 0;
key_old = 1;
}
if((key_new == 0) && (key_old == 1))
{
switch(P2 & 0x0f)
{
case 0x0e: key_can = 4; break; //得到 k1 鍵值
case 0x0d: key_can = 3; break; //得到 k2 鍵值
case 0x0b: key_can = 2; break; //得到 k3 鍵值
case 0x07: key_can = 1; break; //得到 k4 鍵值
}
}
key_old = key_new;
}
/****************按鍵處理數(shù)碼管顯示函數(shù)***************/
void key_with()
{
if(key_can == 4)
{
menu_1 ++;
if(menu_1 >= 3)
{
menu_1 = 0;
}
if(menu_1 == 0)
{
dis_smg[0] = smg_du[temperature % 10]; //取溫度的小數(shù)顯示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取溫度的個(gè)位顯示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取溫度的十位顯示
smg_i = 3;
}
if(menu_1 == 1)
{
dis_smg[0] = smg_du[t_high % 10]; //取小數(shù)顯示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取 low 十位顯示
dis_smg[3] = 0x89;
smg_i = 4;
}
if(menu_1 == 2)
{
dis_smg[0] = smg_du[t_low % 10]; //取 low 小數(shù)顯示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位顯示
dis_smg[3] = 0xc7;
smg_i = 4;
}
}
if(menu_1 == 1)
//設(shè)置高溫報(bào)警
{
if(key_can == 3)
{
if(flag_lj_3_en == 0)
t_high ++ ;
//按鍵按下未松開(kāi)自動(dòng)加三次
else
t_high += 10; //按鍵按下未松開(kāi)自動(dòng)加三次之后每次自動(dòng)加 10
if(t_high > 990)
t_high = 990;
dis_smg[0] = smg_du[t_high % 10]; //取小數(shù)顯示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取十位顯示
dis_smg[3] = 0x89; //H
}
if(key_can == 1)
{
if(flag_lj_3_en == 0)
t_high -- ; //按鍵按下未松開(kāi)自動(dòng)加三次
else
t_high -= 10; //按鍵按下未松開(kāi)自動(dòng)減三次之后每次自動(dòng)減 10
if(t_high <= t_low)
t_high = t_low + 1;
dis_smg[0] = smg_du[t_high % 10]; //取小數(shù)顯示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取十位顯示
dis_smg[3] = 0x89; //H
}
// write_eepom();
}
if(menu_1 == 2)
//設(shè)置低溫報(bào)警
{
if(key_can == 3)
{
if(flag_lj_3_en == 0)
t_low ++ ;
else
t_low += 10;
if(t_low >= t_high)
t_low = t_high - 1;
dis_smg[0] = smg_du[t_low % 10]; //取小數(shù)顯示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位顯示
dis_smg[3] = 0xc7; //L
}
if(key_can == 1)
{
if(flag_lj_3_en == 0)
t_low -- ;
else
t_low -= 10;
if(t_low <= 10)
t_low = 10;
dis_smg[0] = smg_du[t_low % 10]; //取小數(shù)顯示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取個(gè)位顯示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位顯示
dis_smg[3] = 0xc7; //L
}
// write_eepom();
}
}
/****************報(bào)警函數(shù)***************/
void clock_h_l()
{
if((temperature <= t_low) || (temperature >= t_high))
{
flag_clock = 1;
}
else
{
flag_clock = 0;
beep = 1;
}
}
void main()
{
temperature = read_temp();
//先讀出溫度的值
time_init(); //初始化定時(shí)器
read_eepom();
if(a_a == 0xff)
//新的單片機(jī)初始單片機(jī)內(nèi)問(wèn) EEPOM
{
t_high = 300;
t_low = 100;
a_a = 1;
write_eepom();
}
delay_1ms(650);
temperature = read_temp();
//先讀出溫度的值
dis_smg[0] = smg_du[temperature % 10]; //取溫度的小數(shù)顯示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取溫度的個(gè)位顯示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取溫度的十位顯示
while(1)
{
display();
//顯示函數(shù)
key();
//按鍵程序
if(key_can < 10)
{
key_with();
//設(shè)置報(bào)警溫度
}
temperature = read_temp(); //先讀出溫度的值
if(flag_300ms == 1) //300ms 處理一次溫度程序
{
clock_h_l(); //報(bào)警函數(shù)
if(flag_clock == 1)
beep = ~beep;
flag_300ms = 0;
if(menu_1 == 0)
{
smg_i = 3;
dis_smg[0] = smg_du[temperature % 10]; //取溫度的小數(shù)顯示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取溫度的個(gè)位顯示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取溫度的十位顯示
}
if(zd_break_en == 1) //自動(dòng)退出設(shè)置界面程序
{
zd_break_value ++; //每 300ms 加一次
if(zd_break_value > 50) //15 秒后自動(dòng)退出設(shè)置界面
{
menu_1 = 0;
zd_break_en = 0;
zd_break_value = 0;
}
}
}
}
}
/*************定時(shí)器 0 中斷服務(wù)程序***************/
void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms
value ++;
if(value % 6 == 0)
{
flag_300ms = 1; //300ms
value = 0;
}
if(flag_lj_en == 1) //按下按鍵使能
{
key_time ++;
if(key_time >= 10) //500ms
{
key_time = 0;
key_500ms = 1; //500ms
flag_value ++;
if(flag_value > 3)
{
flag_value = 10;
flag_lj_3_en = 1; //3 次后 1.5 秒連加大些
}
}
}
}
同類文章排行
- LED數(shù)碼管的檢測(cè)
- LED數(shù)碼管故障檢測(cè)檢修
- LED數(shù)顯溫度控制器設(shè)計(jì)論述
- LED大屏幕數(shù)顯裝置在隨流孕育裝置上的應(yīng)用
- LED數(shù)碼管正裝與倒裝結(jié)構(gòu)區(qū)別
- led數(shù)碼管靜態(tài)顯示方式和動(dòng)態(tài)顯示方式
- LED七段數(shù)碼管數(shù)字鐘
- led數(shù)碼管顯示種類簡(jiǎn)介
- LED數(shù)碼管顯示器介紹
- LED數(shù)碼管動(dòng)態(tài)掃描顯示控制器設(shè)計(jì)