欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: 基于51單片機(jī)的DS18B20溫控系統(tǒng)設(shè)計(jì)資料(源碼+論文+仿真) [打印本頁]

作者: ljxx    時(shí)間: 2018-4-17 20:36
標(biāo)題: 基于51單片機(jī)的DS18B20溫控系統(tǒng)設(shè)計(jì)資料(源碼+論文+仿真)
基于51單片機(jī)的溫度控制系統(tǒng)資料包:


摘要
在日常生活中溫度在我們身邊無時(shí)不在,溫度的控制和應(yīng)用在各個(gè)領(lǐng)域都有重要的作用。很多行業(yè)中都有大量的用電加熱設(shè)備,和溫度控制設(shè)備,如用于報(bào)警的溫度自動(dòng)報(bào)警系統(tǒng),熱處理的加熱爐,用于融化金屬的坩鍋電阻爐及各種不同用途的溫度箱等,這些都采用單片機(jī)技術(shù),利用單片機(jī)語言程序?qū)λ鼈冞M(jìn)行控制。而單片機(jī)技術(shù)具有控制和操作使用方便、結(jié)構(gòu)簡單便于修改和維護(hù)、靈活性大且具有一定的智能性等特點(diǎn),可以精確的控
制技術(shù)標(biāo)準(zhǔn),提高了溫控指標(biāo),也大大的提高了產(chǎn)品的質(zhì)量和性能。

由于單片機(jī)技術(shù)的優(yōu)點(diǎn)突出,智能化溫度控制技術(shù)正被廣泛地采用。本文介紹了基于單片機(jī)STC89C52 的溫度控制系統(tǒng)的設(shè)計(jì)方案與軟硬件實(shí)現(xiàn)。采用溫度傳感器DS18B20 采集溫度數(shù)據(jù),7段數(shù)碼管顯示溫度數(shù)據(jù),按鍵設(shè)置溫度上下限,當(dāng)設(shè)置為低于下降報(bào)警時(shí),當(dāng)溫度低于設(shè)定的下限時(shí),點(diǎn)亮發(fā)光二極管同時(shí)繼電器工作,啟動(dòng)加熱設(shè)備,當(dāng)溫度上升到上限時(shí),斷開繼電器,停止加熱設(shè)備工作,如此循環(huán)。當(dāng)設(shè)置為高于上限報(bào)警時(shí),當(dāng)溫度高于設(shè)定的上限時(shí),點(diǎn)亮發(fā)光二極管同時(shí)繼電器工作,啟動(dòng)制冷設(shè)備,當(dāng)溫度下降到下限時(shí),熄滅LED,同時(shí)斷開繼電器,使制冷設(shè)備停止工作,使溫度控制在上下限范圍內(nèi)。上限報(bào)警或者是下限報(bào)警可以設(shè)置,上限和下限溫度也可以設(shè)置,同時(shí)設(shè)置的數(shù)據(jù)掉電后可以存儲(chǔ)。給出了系統(tǒng)總體框架、程序流程圖和Protel 原理圖,并在硬件平臺(tái)上實(shí)現(xiàn)了所設(shè)計(jì)功能。
目錄
摘要
ABSTRACT
第一章 前言
1.1 溫度控制系統(tǒng)設(shè)計(jì)發(fā)展歷史及意義            
1.2 溫度控制系統(tǒng)的目的            
1.3 溫度控制系統(tǒng)完成的功能            
第二章 總體設(shè)計(jì)方案            
2.1 方案一            
2.2 方案二            
3.1 DS18B20簡介            
3.1.1DS18B20封裝與引腳            
3.1.2 DS18B20的簡單性能            
3.2 DS18B20的工作原理            
3.3 DS18B20的測溫原理            
3.3.1 測溫原理:            
3.3.2 DS18B20的溫度采集過程            
3.4  AT24CXX系列掉電存儲(chǔ)器的介紹
第四章 單片機(jī)接口設(shè)計(jì)            
4.1 設(shè)計(jì)原則            
4.2 單片機(jī)引腳連接            
4.2.1 單片機(jī)引腳圖            
4.2.2 串口引腳            
第五章 硬件電路設(shè)計(jì)            
5.1 主要硬件電路設(shè)計(jì)            
5.2 軟件系統(tǒng)設(shè)計(jì)            
5.2.1 軟件系統(tǒng)設(shè)計(jì)            
5.2.2 程序組成            
結(jié)束語            
致謝            
附錄            
參考文獻(xiàn)

1.1 溫度控制系統(tǒng)設(shè)計(jì)發(fā)展歷史及意義

溫度控制系統(tǒng)廣泛應(yīng)用于社會(huì)生活的各個(gè)領(lǐng)域 ,如家電、汽車、材料、電力電子等 ,常用的控制電路根據(jù)應(yīng)用場合和所要求的性能指標(biāo)有所不同 , 在工業(yè)企業(yè)中,如何提高溫度控制對象的運(yùn)行性能一直以來都是控制人員和現(xiàn)場技術(shù)人員努力解決的問題。這類控制對象慣性大,滯后現(xiàn)象嚴(yán)重,存在很多不確定的因素,難以建立精確的數(shù)學(xué)模型,從而導(dǎo)致控制系統(tǒng)性能不佳,甚至出現(xiàn)控制不穩(wěn)定、失控現(xiàn)象。傳統(tǒng)的繼電器調(diào)溫電路簡單實(shí)用 ,但由于繼電器動(dòng)作頻繁 ,可能會(huì)因觸點(diǎn)不良而影響正常工作。控制領(lǐng)域還大量采用傳統(tǒng)的PID控制方式,但PID控制對象的模型難以建立,并且當(dāng)擾動(dòng)因素不明確時(shí),參數(shù)調(diào)整不便仍是普遍存在的問題。而采用數(shù)字溫度傳感器DS18B20,因其內(nèi)部集成了A/D轉(zhuǎn)換器,使得電路結(jié)構(gòu)更加簡單,而且減少了溫度測量轉(zhuǎn)換時(shí)的精度損失,使得測量溫度更加精確。數(shù)字溫度傳感器DS18B20只用一個(gè)引腳即可與單片機(jī)進(jìn)行通信,大大減少了接線的麻煩,使得單片機(jī)更加具有擴(kuò)展性。由于DS18B20芯片的小型化,更加可以通過單跳數(shù)據(jù)線就可以和主電路連接,故可以把數(shù)字溫度傳感器DS18B20做成探頭,探入到狹小的地方,增加了實(shí)用性。更能串接多個(gè)數(shù)字溫度傳感器DS18B20進(jìn)行范圍的溫度檢測。

1.2 溫度控制系統(tǒng)的目的

溫度控制在日常生活及工業(yè)領(lǐng)域應(yīng)用相當(dāng)廣泛,比如溫室、水池、發(fā)酵缸、電源等場所的溫度控制。而以往溫度控制是由人工完成的而且不夠重視,其實(shí)在很多場所溫度都需要監(jiān)控以防止發(fā)生意外。針對此問題,本系統(tǒng)設(shè)計(jì)的目的是實(shí)現(xiàn)一種可連續(xù)高精度調(diào)溫的溫度監(jiān)測和控制系統(tǒng),實(shí)現(xiàn)對溫度的實(shí)時(shí)檢測,具有提醒和控制的功能,本設(shè)計(jì)的內(nèi)容是溫度測試控制系統(tǒng),控制對象是溫度。它的特點(diǎn)在于應(yīng)用廣泛,功能強(qiáng)大,小巧美觀,便于攜帶,是一款既實(shí)用又廉價(jià)的控制系統(tǒng)。

1.3 溫度控制系統(tǒng)完成的功能

本設(shè)計(jì)是對溫度進(jìn)行實(shí)時(shí)監(jiān)測與控制,設(shè)計(jì)的溫度控制系統(tǒng)實(shí)現(xiàn)了基本的溫度控制功能:此設(shè)計(jì)中溫度恒定值設(shè)置為60℃,上下跳轉(zhuǎn)溫度為1℃,設(shè)計(jì)精度值為0.1。當(dāng)溫度低于設(shè)定下限溫度即59℃時(shí),綠燈亮,報(bào)警提醒需要外界的加熱措施。當(dāng)溫度上升到上限溫度時(shí),停止加溫,紅燈亮保持溫度。當(dāng)溫度高于設(shè)定上限溫度即61℃時(shí),紅燈亮,需要外界采取降溫措施(本設(shè)計(jì)中沒有附加外界的加熱和降溫措施)。當(dāng)溫度下降到恒溫度時(shí),停止降溫。溫度在上下限溫度之間時(shí),執(zhí)行機(jī)構(gòu)不執(zhí)行。

第二章 總體設(shè)計(jì)方案2.1 方案一

利用溫度傳感器將溫度測出,通過某種電信號傳給外部電路產(chǎn)生一種變化,然后由外部電路控制裝置的開啟。測溫電路的設(shè)計(jì),可以使用熱敏電阻之類的傳感器件利用其感溫效應(yīng),(如電阻隨溫度的變化有一個(gè)變化的曲線,即利用它的變化特性曲線)溫度的變化使得電阻發(fā)生了變化根據(jù)歐姆定律,電阻的變化會(huì)帶來電流或這電壓的變化。再將隨被測溫度變化的電壓或電流采集過來,然后進(jìn)行模擬信號換成數(shù)字信號(A/D)轉(zhuǎn)換,將數(shù)字信號送入單片機(jī),用單片機(jī)進(jìn)行數(shù)據(jù)的處理,將溫度顯示在電路上,這樣就可以將被測溫度顯示出來。最后還有外圍的控制電路,采取一定的措施來控制產(chǎn)生溫度的電路,如加溫、降溫、保持不動(dòng)、或者報(bào)警。這種設(shè)計(jì)需要用到A/D轉(zhuǎn)換電路,感溫電路比較麻煩。

設(shè)計(jì)流程圖如圖2.1

圖2.1 設(shè)計(jì)流程圖

2.2 方案二

利用溫度傳感器芯片直接將溫度數(shù)據(jù)測出,之后通過單片機(jī)程序控制溫度的上、下限值,用外部電路產(chǎn)生顯示和控制加熱和降,來達(dá)到設(shè)計(jì)的要求。

考慮使用溫度傳感器,結(jié)合單片機(jī)電路設(shè)計(jì),采用一只DS18B20溫度傳感器,直接讀取被測溫度值,之后進(jìn)行轉(zhuǎn)換,依次完成設(shè)計(jì)要求。

比較以上兩種方案,很容易看出,采用方案二,電路比較簡單,軟件設(shè)計(jì)容易實(shí)現(xiàn),故實(shí)際設(shè)計(jì)中擬采用方案二。

在設(shè)計(jì)中的控制流程如圖2.2所示。

圖2.2 溫度控制整體流程

在本系統(tǒng)的總體電路設(shè)計(jì)方框圖如圖2.3所示,它由五部分組成:單片機(jī)STC89C52控制部分; DS18B20溫度傳感器采集部分;AT24C16數(shù)據(jù)掉電存儲(chǔ)部分;3位LED數(shù)碼管顯示部分;按鍵調(diào)節(jié)部分;二極管報(bào)警部分;繼電器驅(qū)動(dòng)部分。

圖2.3  溫度計(jì)電路總體設(shè)計(jì)方案


整個(gè)設(shè)計(jì)總體分為以下幾個(gè)部分:控制部分、顯示部分、溫度采集部分、按鍵控制部分,輸出部分。

1、控制部分

由單片機(jī)STC89C52芯片在程序控制和外圍簡單組合電路作用下運(yùn)行,和控制溫度的上、下限,和 LED的溫度顯示?刂瓢l(fā)光二級管的亮滅和繼電器動(dòng)作或復(fù)位,起到提醒報(bào)警功能。

2、顯示部分

顯示電路采用3位7斷共陽LED數(shù)碼管,從P3口送數(shù),P0口掃描。有兩部分顯示電路,第一是顯示DS18B20溫度傳感器所檢測的當(dāng)前溫度,第二是設(shè)定恒定的溫度值。

3、溫度采集部分

由DS18B20智能溫度傳感器直接采集被測溫度。

4、按鍵控制部分

由三個(gè)按鍵控制調(diào)節(jié),用來調(diào)節(jié)溫度的恒定限值,起到預(yù)設(shè)調(diào)節(jié)作用。

第三章 溫度傳感器DS18B20

3.1 DS18B20簡介3.1.1 DS18B20封裝與引腳

   DS18B20封裝與引腳如圖3.1

圖3.1  DS18B20的封裝與引腳

3.1.2 DS18B20的簡單性能

1、 獨(dú)特的單線接口方式,DS18B20在與微處理器連接時(shí)僅需要一條口線即可實(shí)現(xiàn)微處理器與DS18B20的雙向通訊。
  2、 測溫范圍 -55℃~+125℃,固有測溫分辨率0.5℃。
  3、 支持多點(diǎn)組網(wǎng)功能,多個(gè)DS18B20可以并聯(lián)在唯一的三線上,實(shí)現(xiàn)多點(diǎn)測溫。
  4、 工作電源: 3~5V/DC。
  5、 在使用中不需要任何外圍元件。
  6、 測量結(jié)果以9~12位數(shù)字量方式串行傳送。
  7、 不銹鋼保護(hù)管直徑 Φ6 。
  8、 適用于DN15~25, DN40~DN250各種介質(zhì)工業(yè)管道和狹小空間設(shè)備測溫。
  9、 標(biāo)準(zhǔn)安裝螺紋 M10X1, M12X1.5, G1/2”任選。
  10、 PVC電纜直接出線或德式球型接線盒出線,便于與其它電器設(shè)備連接。

3.2 DS18B20的工作原理

DS18B20內(nèi)部的低溫度系數(shù)振蕩器是一個(gè)振蕩頻率隨溫度變化很小的振蕩器,為計(jì)數(shù)器1提供一頻率穩(wěn)定的計(jì)數(shù)脈沖。

高溫度系數(shù)振蕩器是一個(gè)振蕩頻率對溫度很敏感的振蕩器,為計(jì)數(shù)器2提供一個(gè)頻率隨溫度變化的計(jì)數(shù)脈沖。

初始時(shí),溫度寄存器被預(yù)置成-55℃,每當(dāng)計(jì)數(shù)器1從預(yù)置數(shù)開始減計(jì)數(shù)到0時(shí),溫度寄存器中寄存的溫度值就增加1℃,這個(gè)過程重復(fù)進(jìn)行,直到計(jì)數(shù)器2計(jì)數(shù)到0時(shí)便停止。

初始時(shí),計(jì)數(shù)器1預(yù)置的是與-55℃相對應(yīng)的一個(gè)預(yù)置值。以后計(jì)數(shù)器1每一個(gè)循環(huán)的預(yù)置數(shù)都由斜率累加器提供。為了補(bǔ)償振蕩器溫度特性的非線性性,斜率累加器提供的預(yù)置數(shù)也隨溫度相應(yīng)變化。計(jì)數(shù)器1的預(yù)置數(shù)也就是在給定溫度處使溫度寄存器寄存值增加1℃計(jì)數(shù)器所需要的計(jì)數(shù)個(gè)數(shù)。

DS18B20內(nèi)部的比較器以四舍五入的量化方式確定溫度寄存器的最低有效位。在計(jì)數(shù)器2停止計(jì)數(shù)后,比較器將計(jì)數(shù)器1中的計(jì)數(shù)剩余值轉(zhuǎn)換為溫度值后與0.25℃進(jìn)行比較,若低于0.25℃,溫度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃時(shí),溫度寄存器的最低位就進(jìn)位然后置0。這樣,經(jīng)過比較后所得的溫度寄存器的值就是最終讀取的溫度值了,其最后位代表0.5℃,四舍五入最大量化誤差為±1/2LSB,即0.25℃。

溫度寄存器中的溫度值以9位數(shù)據(jù)格式表示,最高位為符號位,其余8位以二進(jìn)制補(bǔ)碼形式表示溫度值。測溫結(jié)束時(shí),這9位數(shù)據(jù)轉(zhuǎn)存到暫存存儲(chǔ)器的前兩個(gè)字節(jié)中,符號位占用第一字節(jié),8位溫度數(shù)據(jù)占據(jù)第二字節(jié)。

DS18B20測量溫度時(shí)使用特有的溫度測量技術(shù)。DS18B20內(nèi)部的低溫度系數(shù)振蕩器能產(chǎn)生穩(wěn)定的頻率信號;同樣的,高溫度系數(shù)振蕩器則將被測溫度轉(zhuǎn)換成頻率信號。當(dāng)計(jì)數(shù)門打開時(shí),DS18B20進(jìn)行計(jì)數(shù),計(jì)數(shù)門開通時(shí)間由高溫度系數(shù)振蕩器決定。芯片內(nèi)部還有斜率累加器,可對頻率的非線性度加以補(bǔ)償,測量結(jié)果存入溫度寄存器中。一般情況下的溫度值應(yīng)該為9位,但因符號位擴(kuò)展成高8位,所以最后以16位補(bǔ)碼形式讀出。

DS18B20工作過程一般遵循以下協(xié)議:初始化——ROM操作命令——存儲(chǔ)器操作命令——處理數(shù)據(jù)。

3.3 DS18B20的測溫原理3.3.1 測溫原理

每一片DSl8B20在其ROM中都存有其唯一的48位序列號,在出廠前已寫入片內(nèi)ROM 中。主機(jī)在進(jìn)入操作程序前必須用讀ROM(33H)命令將該DSl8B20的序列號讀出。ROM命令代碼見表3.1。

程序可以先跳過ROM,啟動(dòng)所有DSl8B20進(jìn)行溫度變換,之后通過匹配ROM,再逐一地讀回每個(gè)DSl8B20的溫度數(shù)據(jù)。

DS18B20的測溫原理,低溫度系數(shù)晶振的振蕩頻率受溫度的影響很小,用于產(chǎn)生固定頻率的脈沖信號送給減法計(jì)數(shù)器1,高溫度系數(shù)晶振隨溫度變化其震蕩頻率明顯改變,所產(chǎn)生的信號作為減法計(jì)數(shù)器2的脈沖輸入,還隱含著計(jì)數(shù)門,當(dāng)計(jì)數(shù)門打開時(shí),DS18B20就對低溫度系數(shù)振蕩器產(chǎn)生的時(shí)鐘脈沖后進(jìn)行計(jì)數(shù),進(jìn)而完成溫度測量。計(jì)數(shù)門的開啟時(shí)間由高溫度系數(shù)振蕩器來決定,每次測量前,首先將-55 ℃所對應(yīng)的基數(shù)分別置入減法計(jì)數(shù)器1和溫度寄存器中,減法計(jì)數(shù)器1和溫度寄存器被預(yù)置在-55 ℃所對應(yīng)的一個(gè)基數(shù)值。減法計(jì)數(shù)器1對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行減法計(jì)數(shù),當(dāng)減法計(jì)數(shù)器1的預(yù)置值減到0時(shí)溫度寄存器的值將加1,減法計(jì)數(shù)器1的預(yù)置將重新被裝入,減法計(jì)數(shù)器1重新開始對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行計(jì)數(shù),如此循環(huán)直到減法計(jì)數(shù)器2計(jì)數(shù)到0時(shí),停止溫度寄存器值的累加,此時(shí)溫度寄存器中的數(shù)值即為所測溫度。圖3.2中的斜率累加器用于補(bǔ)償和修正測溫過程中的非線性,其輸出用于修正減法計(jì)數(shù)器的預(yù)置值,只要計(jì)數(shù)門仍未關(guān)閉就重復(fù)上述過程,直至溫度寄存器值達(dá)到被測溫度值。

表3.1  ROM操作命令

指令
約定代碼
功                  能
讀ROM
33H
讀DS18B20 ROM中的編碼

符合ROM

55H
發(fā)出此命令之后,接著發(fā)出64位ROM編碼,訪問單線總線上與該編碼相對應(yīng)的DS18B20 使之作出響應(yīng),為下一步對該DS18B20的讀寫作準(zhǔn)備
搜索ROM
0F0H
用于確定掛接在同一總線上DS18B20的個(gè)數(shù)和識(shí)別64位ROM地址,為操作各器件作好準(zhǔn)備
跳過ROM
0CCH
忽略64位ROM地址,直接向DS18B20發(fā)溫度變換命令,適用于單片工作。
告警搜索
命   令
0ECH
執(zhí)行后,只有溫度超過設(shè)定值上限或者下限的片子才做出響應(yīng)
溫度變換
44H
啟動(dòng)DS18B20進(jìn)行溫度轉(zhuǎn)換,轉(zhuǎn)換時(shí)間最長為500MS,結(jié)果存入內(nèi)部9字節(jié)RAM中
讀暫存器
0BEH
讀內(nèi)部RAM中9字節(jié)的內(nèi)容
寫暫存器
4EH
發(fā)出向內(nèi)部RAM的第3,4字節(jié)寫上、下限溫度數(shù)據(jù)命令,緊跟讀命令之后,是傳送兩字節(jié)的數(shù)據(jù)
復(fù)制暫存器
48H
將E2PRAM中第3,4字節(jié)內(nèi)容復(fù)制到E2PRAM中
重調(diào)E2PRAM
0BBH
將E2PRAM中內(nèi)容恢復(fù)到RAM中的第3,4字節(jié)
讀供電方式
0B4H
讀DS18B20的供電模式,寄生供電時(shí)DS18B20發(fā)送“0”,外接電源供電DS18B20發(fā)送“1”


   

圖3.2測溫原理內(nèi)部裝置

3.3.2 DS18B20溫度采集過程

由于DS18B20單線通信功能是分時(shí)完成的,他有嚴(yán)格的時(shí)隙概念,因此讀寫時(shí)序很重要,系統(tǒng)對DS18B20的各種操作必須按協(xié)議進(jìn)行。操作協(xié)議為:初始化DS18B20(發(fā)復(fù)位脈沖)→發(fā)ROM功能命令→發(fā)存儲(chǔ)器操作命令→處理數(shù)據(jù)。溫度的采集流程如圖3.3所示。



圖3.3 DS18B20測溫流程

為防止斷電后密碼丟失,特在此項(xiàng)目設(shè)計(jì)中加入了以AT24C16為核心的存儲(chǔ)模塊。其電路原理圖如下所示:

AT24c16,是IIc總線協(xié)議的通信方式。單片機(jī)本身不具有IIc通行的硬件設(shè)備,因此采用軟件模擬的方式完成與單片機(jī)的通信。

摘抄文獻(xiàn):

IIC總線工作原理
        I2C總線進(jìn)行數(shù)據(jù)傳送時(shí),時(shí)鐘信號為高電平期間,數(shù)據(jù)線上的數(shù)據(jù)必須保持穩(wěn)定,只有在時(shí)鐘線上的信號為低電平期間,數(shù)據(jù)線上的高電平或低電平狀態(tài)才允許變化。
               
起始和終止信號 :SCL線為高電平期間,SDA線由高電平向低電平的變化表示起始信號;SCL線為高電平期間,SDA線由低電平向高電平的變化表示終止信號。
數(shù)據(jù)傳送格式(1)字節(jié)傳送與應(yīng)答
每一個(gè)字節(jié)必須保證是8位長度。數(shù)據(jù)傳送時(shí),先傳送最高位(MSB),每一個(gè)被傳送的字節(jié)后面都必須跟隨一位應(yīng)答位(即一幀共有9位)。如果一段時(shí)間內(nèi)沒有收到從機(jī)的應(yīng)答信號,則自動(dòng)認(rèn)為從機(jī)已正確接收到數(shù)據(jù)。
     AT24C16的芯片地址如下圖,1010為固定,A0,A1,A2正好與芯片的1,2,3引角對應(yīng),為當(dāng)前電路中的地址選擇線,三根線可選擇8個(gè)芯片同時(shí)連接在電路中,當(dāng)要與哪個(gè)芯片通信時(shí)傳送相應(yīng)的地址即可與該芯片建立連接,TX-1B實(shí)驗(yàn)板上三根地址線都為0。最后一位R/W為告訴從機(jī)下一字節(jié)數(shù)據(jù)是要讀還是寫,0為寫入,1為讀出。


      AT24C016芯片地址(0xa0為寫,0xa1為讀)
任一地址寫入數(shù)據(jù)格式


操作時(shí)序圖如下:

下面是本項(xiàng)目的源程序:


//*************************************************

//功能:發(fā)送非應(yīng)答信號

void nack_24c16()

{

sda_24c16=1;   

delay_3us();

delay_3us();

scl_24c16=1;

delay_3us();

delay_3us();

scl_24c16=0;

sda_24c16=0;

}

//*************************************************

//功能:發(fā)送IIC停止信號

void stop_24c16()

{

   sda_24c16=0;

   scl_24c16=1;                              

   delay_3us();

   delay_3us();                       

   sda_24c16=1;

   delay_3us();

   delay_3us();                                

   scl_24c16=0;

}

//*************************************************

//功能:發(fā)送啟動(dòng)通訊的信號

void star_24c16()

{

  sda_24c16=1;

  scl_24c16=1;

  delay_3us();

  delay_3us();

  sda_24c16=0;

  delay_3us();

  delay_3us();

  scl_24c16=0;

}

//****************************************************

//功能:判斷應(yīng)答或非應(yīng)答

//說明:通訊出錯(cuò)時(shí)標(biāo)志為1,否則為0

void cack_24c16()

{

   scl_24c16=0;

   sda_24c16=1;

   delay_3us();        

   scl_24c16=1;            

   flag12=0;//清除錯(cuò)誤標(biāo)志  

   if(sda_24c16)flag12=1;

   scl_24c16=0;

}     

//****************************************************

//功能:發(fā)送應(yīng)答信號

void mack_24c16()

{

  sda_24c16=0;

  scl_24c16=1;

  delay_3us();

  delay_3us();

  scl_24c16=0;

  sda_24c16=1;

}

//*************************************************

//功能:向24C16寫入一字節(jié)的數(shù)據(jù)

void w1byte_24c16(uchar byte1)

{

  uchar i=8;

  while(i--)   

  {            

    delay_3us();

    delay_3us();

    delay_3us();

    if(byte1 & 0x80)

    {sda_24c16=1;}

    else

    {sda_24c16=0;}

    delay_3us();

    delay_3us();

    delay_3us();

    scl_24c16=1;

    delay_3us();

    delay_3us();

    delay_3us();

    scl_24c16=0;

    byte1<<=1;

  }

}

//****************************************************

//功能:從24C16中讀出一字節(jié)的數(shù)據(jù)

uchar rd1byte_24c16(void)//;讀1字節(jié)子程序(通用)讀出的數(shù)據(jù)存放在30H中

{

  uchar i;

  uchar ddata=0;

  sda_24c16=1;//置IO口為1,準(zhǔn)備讀入數(shù)據(jù)                     

  for(i=0;i<8;i++)           

  {

     ddata<<=1;

     delay_3us();

     delay_3us();

     delay_3us();

     scl_24c16=1;

     if(sda_24c16) ddata++;

     delay_3us();

     delay_3us();

     delay_3us();   

     scl_24c16=0;

  }

  return ddata;

}

1





第四章 單片機(jī)接口設(shè)計(jì)4.1 設(shè)計(jì)原則

DS18B20有2種供電方式,一種是直流電源,還有一種是寄生蟲方式供電。采用電源供電方式,此時(shí)DS18B20的1腳接地,2腳作為信號線,3腳接電源。電源是利用直流穩(wěn)壓電源。當(dāng)DS18B20處于寫存儲(chǔ)器操作和溫度A/D變換操作時(shí),總線上必須有強(qiáng)的上拉,上拉開啟時(shí)間最大為10 μs。采用寄生電源供電方式是VDD和GND端均接地。由于單線制只有一根線,因此發(fā)送接收口必須是三狀態(tài)的。主機(jī)控制DS18B20完成溫度轉(zhuǎn)換必須經(jīng)過3個(gè)步驟:

4.2 單片機(jī)引腳連接4.2.1 單片機(jī)引腳圖

單片機(jī)引腳如圖4.1所示。



圖4.1單片機(jī)引腳


4.2.2 串口引腳

串口引腳的連接圖如附錄1。


第五章 硬件電路設(shè)計(jì)5.1 主要硬件電路設(shè)計(jì)

硬件電路主要包括:顯示電路,DS18B20溫度傳感器檢測電路,按鍵電路,晶振電路,二極管顯示報(bào)警電路,電源電路。

(1) 顯示電路

顯示電路采用了7段共陰數(shù)碼管掃描電路,通過單片機(jī)的P0.0到P0.7八個(gè)端口接數(shù)碼管的八個(gè)引腳,數(shù)碼管的9號引腳接地。用來顯示當(dāng)前檢測的溫度值,精確度為0.1。如圖5.1所示。節(jié)約了單片機(jī)的輸出端口,便于程序的編寫。

本設(shè)計(jì)中還有一組數(shù)碼管由P2.0到P2.7連接,除接口不同外其他一樣,如圖5.2。



圖5.2顯示電路

(2) DS18B20溫度傳感器檢測電路

溫度采集通過數(shù)字化的溫度傳感器DS18B20,通過QD接向單片機(jī)的P3.0口。

DS18B20溫度傳感器電路如圖5.3所示。


圖5.3 溫度傳感器電路引腳圖

(3) 按鍵電路

按鍵電路如圖5.4所示。由K2、K3、K4三個(gè)按鍵控制上、下限溫度值。P3.1接口接K4按鍵。P3.2接口接入K3按鍵。P3.3接口接K2按鍵。

1.K2溫度上下限減少鍵:減少溫度上下限的值。
2.K3溫度上下限增加鍵:增加溫度上下限的值。
3.K4溫控開關(guān)鍵:進(jìn)入溫控的切換鍵。


圖5.4 按鍵電路圖

(4) 晶振控制電路

晶振采用的是12MHZ的標(biāo)準(zhǔn)晶振。接入單片機(jī)的XTAL1、XTAL2。

晶振控制電路如圖5.5所示。


圖5.5 晶振控制電路圖


  (5) 復(fù)位電路

復(fù)位電路采用了人工復(fù)位的方式,按下按鍵K1使單片機(jī)復(fù)位。直接接到單片機(jī)的RESET引腳。

  復(fù)位電路如圖5.6所示


圖5.6 復(fù)位電路圖

(6)二極管顯示報(bào)警電路

二極管顯示報(bào)警電路如圖5.7所示。通過單片機(jī)的P3.4和P3.5兩個(gè)端口送出,采用的是高電平驅(qū)動(dòng),使其發(fā)光發(fā)出警告。


圖5.7 二極管顯示電路

      (8)電源部分

電源部分才用的是直流穩(wěn)壓電源,產(chǎn)生5V的穩(wěn)定直流電壓。電源設(shè)計(jì)部分如圖5.8所示。


圖5.8 電源部分電路

5.2 軟件系統(tǒng)設(shè)計(jì)5.2.1 軟件系統(tǒng)設(shè)計(jì)

一個(gè)應(yīng)用系統(tǒng)要完成各項(xiàng)功能,首先必須有較完善的硬件作保證。同時(shí)還必須得到相應(yīng)設(shè)計(jì)合理的軟件的支持,尤其是微機(jī)應(yīng)用高速發(fā)展的今天,許多由硬件完成的工作,都可通過軟件編程而代替。甚至有些必須采用很復(fù)雜的硬件電路才能完成的工作,用軟件編程有時(shí)會(huì)變得很簡單,如數(shù)字濾波,信號處理等。因此充分利用其內(nèi)部豐富的硬件資源和軟件資源,采用與C51系列單片機(jī)相對應(yīng)的51匯編語言和結(jié)構(gòu)化程序設(shè)計(jì)方法進(jìn)行軟件編程。

程序設(shè)計(jì)語言有三種:機(jī)器語言、匯編語言和高級語言。機(jī)器語言是機(jī)器唯一能“懂”的語言,用匯編語言或高級語言編寫的程序(稱為源程序)最終都必須翻譯成機(jī)器語言的程序(成為目標(biāo)程序),計(jì)算機(jī)才能“看懂”,然后逐一執(zhí)行。

高級語言是面向問題和計(jì)算過程的語言,它可通過于各種不同的計(jì)算機(jī),用戶編程時(shí)不必仔細(xì)了解所用的計(jì)算機(jī)的具體性能與指令系統(tǒng),而且語句的功能強(qiáng),常常一個(gè)語句已相當(dāng)于很多條計(jì)算機(jī)指令,于是用高級語言編制程序的速度比較快,也便于學(xué)習(xí)和交流,但是本系統(tǒng)卻選用了匯編語言。原因在于,本系統(tǒng)是編制程序工作量不大、規(guī)模較小的單片機(jī)微控制系統(tǒng),使用匯編語言可以不用像高級語言那樣占用較多的存儲(chǔ)空間,適合于存儲(chǔ)容量較小的系統(tǒng)。同時(shí),本系統(tǒng)對位處理要求很高,需要解決大量的邏輯控制問題。

51指令系統(tǒng)的指令長度較短,它在存儲(chǔ)空間和執(zhí)行時(shí)間方面具有較高的效率,編成的程序占用內(nèi)存單元少,執(zhí)行也非常的快捷,與本系統(tǒng)的應(yīng)用要求很適合。而且AT89C—51指令系統(tǒng)有豐富的位操作(或稱位處理)指令,可以形成一個(gè)相當(dāng)完整的位操作指令子集,這是AT89C—51指令系統(tǒng)主要的優(yōu)點(diǎn)之一。對于要求反應(yīng)靈敏與控制及時(shí)的工控、檢測等實(shí)時(shí)控制系統(tǒng)以及要求體積小、系統(tǒng)小的許多“電腦化”產(chǎn)品,可以充分體現(xiàn)出匯編語言簡明、整齊、執(zhí)行時(shí)間短和易于使用的特點(diǎn)。

本裝置的軟件包括主程序、讀出溫度子程序、復(fù)位應(yīng)答子程序、寫入子程序、以及有關(guān)DS18B20的程序(初始化子程序、寫程序和讀程序)。

5.2.2 程序組成

系統(tǒng)程序主要包括主程序,讀出溫度子程序,寫入子程序,門限調(diào)節(jié)子程序等。

1)主程序

主程序的主要功能是負(fù)責(zé)溫度的實(shí)時(shí)顯示、讀出并處理DS18B20的測量的當(dāng)前溫度值,溫度測量每1s進(jìn)行一次。這樣可以在一秒之內(nèi)測量一次被測溫度,其程序流程見圖5.9所示。

通過調(diào)用讀溫度子程序把存入內(nèi)存儲(chǔ)中的整數(shù)部分與小數(shù)部分分開存放在不同的兩個(gè)單元中,然后通過調(diào)用顯示子程序顯示出來。


圖5.9 主程序流程圖

2)讀出溫度子程序

讀出溫度子程序的主要功能是讀出RAM中的9字節(jié),在讀出時(shí)需進(jìn)行CRC校驗(yàn),校驗(yàn)有錯(cuò)時(shí)不進(jìn)行溫度數(shù)據(jù)的改寫,程序流程圖如圖5.10所示。

DS18B20的各個(gè)命令對時(shí)序的要求特別嚴(yán)格,所以必須按照所要求的時(shí)序才能達(dá)到預(yù)期的目的,同時(shí),要注意讀進(jìn)來的是高位在后低位在前,共有12位數(shù),小數(shù)4位,整數(shù)7位,還有一位符號位。


結(jié)束語
本文詳細(xì)講述了系統(tǒng)設(shè)計(jì)方案,并給出了相關(guān)程序流程。本設(shè)計(jì)應(yīng)用性比較強(qiáng),可以應(yīng)用在倉庫溫度、大棚溫度、機(jī)房溫度、水池等的監(jiān)控。另外,如果把本設(shè)計(jì)方案擴(kuò)展為多點(diǎn)溫度控制,加上上位機(jī),則可以實(shí)現(xiàn)遠(yuǎn)程溫度監(jiān)控系統(tǒng),將具有更大的應(yīng)用價(jià)值。
    本文的創(chuàng)新點(diǎn)在于詳細(xì)設(shè)計(jì)了基于單片機(jī)AT89C51 的溫度監(jiān)控系統(tǒng),設(shè)計(jì)程序已經(jīng).此系統(tǒng)可廣泛用于溫度在DS18B20 測溫范圍之內(nèi)的場合,有良好的應(yīng)用前景。由于單片機(jī)的各種優(yōu)越的特性,使得它的經(jīng)濟(jì)效益顯的更加突出,有很好的實(shí)用性。



附錄

附錄1

原理電路總設(shè)計(jì)圖


單片機(jī)源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. sbit    jidianqi=P2^0;//繼電器控制口
  6. sbit    dis_bit1=P2^6;//定義數(shù)碼管控制口
  7. sbit    dis_bit2=P2^5;//定義數(shù)碼管控制口
  8. sbit    dis_bit3=P2^4;//定義數(shù)碼管控制口
  9. sbit    dis_bit4=P2^7;//定義數(shù)碼管控制口

  10. sbit    s1_bit=P1^0;  //定義按鍵S1控制口
  11. sbit    s2_bit=P1^1;  //定義按鍵S2控制口
  12. sbit    s3_bit=P1^2;  //定義按鍵S3控制口

  13. sbit  sda_24c16=P3^4;//定義24C16串行數(shù)據(jù)線 第5腳
  14. sbit  scl_24c16=P3^5;//定義24C16串行時(shí)鐘線 第6腳

  15. sbit    dq_ds18b20=P1^3;//定義控制DS18B20

  16. #define smg_data    P0//定義數(shù)碼管數(shù)據(jù)口

  17. void    delay_3us();//3US的延時(shí)程序
  18. void    nack_24c16();//24C16非應(yīng)答信號  
  19. void    stop_24c16();//停止通訊信號
  20. void    star_24c16();//啟動(dòng)信號
  21. void    cack_24c16();//檢測應(yīng)答信號
  22. void    mack_24c16();//發(fā)送應(yīng)答信號
  23. void    w1byte_24c16(uchar byte1);//向24C16寫入一字節(jié)的數(shù)據(jù)
  24. uchar   rd1byte_24c16(void);
  25. void    read_24c16();//讀數(shù)據(jù)操作
  26. void    write_24c16();//寫入16字節(jié)的數(shù)據(jù)操作


  27. void  init_t0();//定時(shí)器0初始化函數(shù)
  28. void  judge_s1();//S1按鍵處理函數(shù)
  29. void  judge_s2();//S2按鍵處理函數(shù)
  30. void  judge_s3();//S3按鍵處理函數(shù)
  31. void  dis(uchar s1,uchar s2,uchar s3,uchar s4);//顯示子程序
  32. void  dis_san(uchar s1,uchar s2,uchar s3,uchar s4,uchar san);//閃爍顯示子程序
  33. void  judge_dis();//顯示處理函數(shù)


  34. void  judge_dongzuo();//判斷繼電器是否動(dòng)作
  35. //***********************************************************************
  36. //DS18B20測溫函數(shù)定義
  37. void w_1byte_ds18b20(uchar value);//向DS18B20寫一個(gè)字節(jié)
  38. uchar r_1byte_ds18b20(void);//從DS18B20讀取一個(gè)字節(jié)的數(shù)據(jù)
  39. void rest_ds18b20(void);//DS18B20復(fù)位程序
  40. void readtemp_ds18b20(void);//讀取溫度
  41. void  countavetemp(void);//計(jì)算平均溫度
  42. void dis_temp();//溫度顯示函數(shù)

  43. void  delay_3us();//3US的延時(shí)程序
  44. void  delay_8us(uint t);//8US延時(shí)基準(zhǔn)程序
  45. void  delay_50us(uint t);//延時(shí)50*T微妙函數(shù)的聲明
  46. void  display1(uchar dis_data);//數(shù)碼管1顯示子程序
  47. void  display2(uchar dis_data);//數(shù)碼管2顯示子程序
  48. void  display3(uchar dis_data);//數(shù)碼管3顯示子程序
  49. void  display4(uchar dis_data);//數(shù)碼管4顯示子程序
  50. void  display3_dian(uchar dis_data);//數(shù)碼管3顯示子程序


  51. //共陽數(shù)碼管斷碼表
  52. const uchar tabl1[18]={0xA0,0xBE,0x62,0x2A,0x3c,0x29,
  53.                      // 0     1    2    3    4    5
  54.                        0x21,0xBa,0x20,0x38,0x61,0x65,0xFF,
  55.                       //6   7     8    9   10 E 11T   12滅
  56.                        0xe1,0x5f,0x65,0xE5,0X34};
  57.                  //    13C  14-   15t     L    H
  58. //共陽數(shù)碼管斷碼表(帶小數(shù)點(diǎn))
  59. const uchar  tabl2[10]={0x80,0x9e,0x42,0x0A,0x1c,0x09,0x01,
  60. //                        0    1    2     3   4    5    6
  61.                       0x9a,0x00,0x18};
  62.                     //  7   8    9
  63. const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};



  64. uchar flag1,zancun1,zancun2,zancun3;
  65. uchar t0_crycle,msecond_count;
  66. uchar set_h,set_l,dongzuo_flag;//存儲(chǔ)設(shè)置溫度的上限和下限
  67. uchar setlow_f,sethigh_f;//存儲(chǔ)設(shè)置問的上下限的符號
  68. uchar low_high;//存儲(chǔ)低下動(dòng)作還是高上動(dòng)作
  69. //unsigned long  temp32_1,temp32_2,temp_ave;
  70. uchar templ,temph,temp_flag;
  71. uchar temp32,flag12;
  72. uchar  t_b,t_s,t_g,t_x,temp_flag2;//從左到右分別存儲(chǔ)溫度百位,十位,個(gè)位,小數(shù)位
  73. //主程序
  74. void main()
  75. {
  76.     uchar i;
  77.     P3=0x00;
  78.     dongzuo_flag=0;//繼電器動(dòng)作標(biāo)志位,0復(fù)位,1動(dòng)作
  79.     jidianqi=0;//繼電器復(fù)位

  80.     flag1=0;   
  81.     read_24c16();//單片機(jī)上電的時(shí)候先讀取4組密碼
  82.     init_t0();
  83.      while(1)
  84.     {
  85.       if(flag1==0)
  86.       {
  87.          countavetemp();//求取平均溫度
  88.          judge_dongzuo();
  89.       }
  90.       for(i=0;i<250;i++)
  91.       {
  92.         judge_dis();//顯示處理
  93.         judge_s1();
  94.         judge_s2();
  95.         judge_s3();

  96.       }
  97.     }
  98. }

  99. //***************************************************
  100. //讀數(shù)據(jù)操作
  101. void read_24c16()
  102. {
  103.   uchar  i,j;
  104. read1:
  105.        nack_24c16();
  106.         star_24c16();//發(fā)送啟動(dòng)脈沖
  107.         w1byte_24c16(0xa0);//24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  108.         cack_24c16();
  109.         if(flag12)goto read1;
  110.         w1byte_24c16(j*6+i+1);//寫入24C16的內(nèi)部地址,選擇第二頁
  111.         cack_24c16();
  112.         if(flag12)goto read1;
  113.         nack_24c16();
  114.         stop_24c16();//重新開始  
  115.         star_24c16();//
  116.         w1byte_24c16(0xa1);// 24C16的芯片地址,高四位固定為1010,選擇第一區(qū),讀操作
  117.         cack_24c16();
  118.         if(flag12)goto read1;
  119.         low_high=rd1byte_24c16();
  120.         mack_24c16();
  121.         setlow_f=rd1byte_24c16();
  122.         mack_24c16();
  123.         set_l=rd1byte_24c16();
  124.         mack_24c16();
  125.         sethigh_f=rd1byte_24c16();
  126.         mack_24c16();
  127.         set_h=rd1byte_24c16();

  128.   mack_24c16();
  129.   nack_24c16();
  130.   stop_24c16();
  131.      if(low_high>=2)low_high=1;
  132.      if(setlow_f>=2)setlow_f=1;
  133.      if(set_l>=100)set_l=20;
  134.      if(sethigh_f>=2)sethigh_f=1;
  135.      if(set_h>=100)set_h=38;
  136. }
  137. //****************************************************
  138. //寫入數(shù)據(jù)操作
  139. void write_24c16()
  140. {
  141. write1:
  142.    star_24c16();//發(fā)送啟動(dòng)脈沖
  143.    w1byte_24c16(0xa0);//寫24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  144.    cack_24c16();// 讀取應(yīng)答或非應(yīng)答信號
  145.    if(flag12)goto write1;//判斷
  146.    w1byte_24c16(01);//寫入24C16的內(nèi)部地址
  147.    cack_24c16();
  148.    if(flag12)goto write1;
  149.    w1byte_24c16(low_high);
  150.    cack_24c16();
  151.    if(flag12)goto write1;
  152.    w1byte_24c16(setlow_f);
  153.    cack_24c16();
  154.    if(flag12)goto write1;
  155.    w1byte_24c16(set_l);
  156.    cack_24c16();
  157.    if(flag12)goto write1;
  158.    w1byte_24c16(sethigh_f);
  159.    cack_24c16();
  160.    if(flag12)goto write1;
  161.    w1byte_24c16(set_h);
  162.    cack_24c16();
  163.    if(flag12)goto write1;
  164.    stop_24c16();//寫數(shù)據(jù)完畢,發(fā)送停止脈沖      

  165. }
  166. //set1 進(jìn)入設(shè)置低于下限動(dòng)作或者高于上下動(dòng)作
  167. //set2 進(jìn)入設(shè)置上限溫度
  168. //set3 進(jìn)入設(shè)置下限溫度

  169. //**************************************************
  170. //顯示處理函數(shù)
  171. void  judge_dis()
  172. {   
  173.     if(flag1==0)
  174.     {
  175.         dis_temp();//溫度顯示函數(shù)
  176.     }
  177.     if(flag1!=0)
  178.     {
  179.        switch(flag1)
  180.        {
  181.            case 1:
  182.                dis(5,10,11,1);//顯示SET1

  183.                 break;
  184.            case 2:
  185.                 dis(5,10,11,2);//顯示SET2
  186.                 break;
  187.            case 3:
  188.                 dis(5,10,11,3);//顯示SET3
  189.                 break;
  190.            case 6://設(shè)置高于上限或者低于下限報(bào)警
  191.                 dis_san(16+low_high,12,12,12,1);
  192.                 break;
  193.            case 10://進(jìn)入修改上限溫度的正負(fù)
  194.            case 15://修改下限溫度的正負(fù)
  195.                 dis_san(14+zancun1,zancun2/100,zancun2/10%10,zancun2%10,1);
  196.                 break;
  197.            case 11://進(jìn)入修改上限的百位數(shù)據(jù)
  198.            case 16:
  199.                 dis_san(14+zancun1,zancun2/100,zancun2/10%10,zancun2%10,2);
  200.                 break;
  201.            case 12://進(jìn)入修改鬧鐘,鬧鐘小時(shí)十位閃爍
  202.            case 17:
  203.                 dis_san(14+zancun1,zancun2/100,zancun2/10%10,zancun2%10,3);
  204.                 break;
  205.            case 13://進(jìn)入修改鬧鐘,鬧鐘小時(shí)個(gè)位閃爍
  206.            case 18:
  207.                 dis_san(14+zancun1,zancun2/100,zancun2/10%10,zancun2%10,4);
  208.                 break;
  209.             default:
  210.                 break;
  211.         }
  212.     }
  213. }
  214. //**************************************************
  215. //S1按鍵處理函數(shù)
  216. void  judge_s1()
  217. {
  218.     s1_bit=1;//置IO為1,準(zhǔn)備讀入數(shù)據(jù)
  219.     if(s1_bit==0)//判斷是否有按鍵按下
  220.     {
  221.         delay_50us(1);// 延時(shí),去除機(jī)械抖動(dòng)
  222.         if(s1_bit==0)
  223.         {
  224.            switch(flag1)
  225.            {
  226.                case 0:
  227.                case 1:
  228.                case 2:
  229.                case 10:
  230.                case 11:
  231.                case 12:
  232.                case 15:
  233.                case 16:
  234.                case 17:
  235.                     flag1++;
  236.                     dongzuo_flag=0;
  237.                     jidianqi=0;
  238.                     TR0=1;//
  239.                     break;
  240.                case 3:
  241.                     flag1=1;
  242.                     break;
  243.                case 13:
  244.                     flag1=10;
  245.                     break;
  246.                case 18:
  247.                     flag1=15;
  248.                     break;
  249.                default:
  250.                     break;
  251.            }         
  252.            while(s1_bit==0)
  253.            {
  254.               judge_dis();
  255.            }//等待按鍵釋放
  256.         }
  257.     }
  258. }
  259. //**************************************************
  260. //S2按鍵處理函數(shù)
  261. void  judge_s2()
  262. {
  263.     s2_bit=1;//置IO為1,準(zhǔn)備讀入收據(jù)
  264.     if(s2_bit==0)//判斷是否有按鍵按下
  265.     {
  266.         delay_50us(1);// 延時(shí),去除機(jī)械抖動(dòng)
  267.         if(s2_bit==0)
  268.         {
  269.            switch (flag1)
  270.            {
  271.               case 1: //在顯示SET1狀態(tài)下按S2件,進(jìn)入修改時(shí)間
  272.                  flag1=6;
  273.                  break;
  274.               case 2://在顯示SET2狀態(tài)下按S2,進(jìn)入設(shè)置鬧鐘
  275.                  zancun1=sethigh_f;
  276.                  zancun2=set_h;
  277.                  flag1=10;
  278.                  break;
  279.               case 6://確定修改低于下限動(dòng)作或者高于上限動(dòng)作
  280.                  flag1=0;
  281.                  TR0=0;//
  282.                  write_24c16();
  283.                  break;
  284.               case 10://修改上限溫度正負(fù)性時(shí)按下確定鍵S2
  285.               case 11://修改上限溫度百位數(shù)據(jù)時(shí)按下確定鍵S2
  286.               case 12://修改上限溫度十位數(shù)據(jù)時(shí)按下確定鍵S2
  287.               case 13://修改上限溫度個(gè)位數(shù)據(jù)時(shí)按下確定鍵S2
  288.                  sethigh_f=zancun1;
  289.                  set_h=zancun2;
  290.                  flag1=0;
  291.                  TR0=0;//
  292.                  write_24c16();
  293.                  break;
  294.               case 3:
  295.                  flag1=15;
  296.                  zancun1=setlow_f;
  297.                  zancun2=set_l;
  298.                  break;
  299.               case 15:
  300.               case 16:
  301.               case 17:
  302.               case 18:
  303.                  setlow_f=zancun1;
  304.                  set_l=zancun2;
  305.                  flag1=0;
  306.                  TR0=0;//
  307.                  write_24c16();
  308.                  break;
  309.       /*        case 22:
  310.                  flag1=21;
  311.                  break;
  312.               case 21:
  313.                  flag1=22;
  314.                  break;
  315.               case 4:
  316.                  flag1=23;//秒表暫停
  317.                  msecond_minute=0;
  318.                  msecond_second=0;
  319.                  msecond_msecond=0;
  320.                  break;
  321.               case 23:
  322.                  flag1=24;
  323.                  break;
  324.               case 24:
  325.                  flag1=23;
  326.                  break;
  327.               case 5:
  328.                  flag1=25;//進(jìn)入計(jì)數(shù)器模式
  329.                  zancun1=0;
  330.                  zancun2=0;
  331. //                 zancun3=0;
  332.                  break;
  333.               default:
  334.                  break;*/
  335.                
  336.            }  
  337.            while(s2_bit==0)
  338.            {
  339.               judge_dis();
  340.            }//等待按鍵釋放
  341.         }
  342.     }
  343. }
  344. //**************************************************
  345. //S3按鍵處理函數(shù)
  346. void  judge_s3()
  347. {
  348.     s3_bit=1;//置IO為1,準(zhǔn)備讀入收據(jù)
  349.     if(s3_bit==0)//判斷是否有按鍵按下
  350.     {
  351.         delay_50us(1);// 延時(shí),去除機(jī)械抖動(dòng)
  352.         if(s3_bit==0)
  353.         {
  354.            switch (flag1)
  355.            {

  356.               case 6://修改低于下限動(dòng)作還是高于上限動(dòng)作
  357.                  if(low_high==0)
  358.                  {
  359.                      low_high=1;
  360.                  }
  361.                  else
  362.                  {
  363.                      low_high=0;
  364.                  }
  365.                  break;
  366.               case 7://修改時(shí)間小時(shí)的個(gè)位數(shù)
  367.                  zancun1=zancun1/10*10+(zancun1%10+1)%10;
  368.                  if(zancun1>=24)zancun1=20;
  369.                  break;
  370.               case 8://修改時(shí)間分鐘的十位數(shù)
  371.                  zancun2+=10;
  372.                  if(zancun2>=60)zancun2-=60;
  373.                  break;
  374.               case 9://修改時(shí)間分鐘的個(gè)位數(shù)
  375.                  zancun2=zancun2/10*10+(zancun2%10+1)%10;
  376.                  break;
  377.               case 10://修改上限溫度的正負(fù)性
  378.                  if(zancun1==0)
  379.                  {zancun1=1;}
  380.                  else
  381.                  {zancun1=0;}
  382.                  break;
  383.               case 11://修改上限溫度的百位數(shù)據(jù)
  384.                  zancun2+=100;
  385.                  if(zancun2>=200)zancun2-=200;
  386.                  break;
  387.               case 12://修改上限溫度的十位
  388.                  zancun3=zancun2/10%10+1;
  389.                  if(zancun3>=10)zancun3=0;
  390.                  zancun2=zancun2/100*100+zancun3*10+zancun2%10;
  391.                  break;
  392.               case 13://修改上限溫度的個(gè)位數(shù)據(jù)
  393.                  zancun3=zancun2%10+1;
  394.                  if(zancun3>=10)zancun3=0;
  395.                  zancun2=zancun2/10*10+zancun3;
  396.                  break;
  397.               case 15://修改下限的正負(fù)性
  398.                  if(zancun1==0)
  399.                  {zancun1=1;}
  400.                  else
  401.                  {zancun1=0;}
  402.                  break;
  403.               case 16: //修改下限的百位
  404.                  zancun2+=100;
  405.                  if(zancun2>=200)zancun2-=200;
  406.                  break;
  407.                case 17://修改倒計(jì)時(shí)分鐘的十位數(shù)
  408.                  zancun3=zancun2/10%10+1;
  409.                  if(zancun3>=10)zancun3=0;
  410.                  zancun2=zancun2/100*100+zancun3*10+zancun2%10;
  411.                  break;
  412.              case 18: //修改倒計(jì)時(shí)分鐘的個(gè)位數(shù)
  413.                  zancun3=zancun2%10+1;
  414.                  if(zancun3>=10)zancun3=0;
  415.                  zancun2=zancun2/10*10+zancun3;
  416.                  break;
  417.               default:
  418.                  break;

  419.            }  
  420.            while(s3_bit==0)
  421.            {
  422.               judge_dis();
  423.            }//等待按鍵釋放
  424.         }
  425.     }
  426. }
  427. //****************************************
  428. ////閃爍顯示子程序
  429. void  dis_san(uchar s1,uchar s2,uchar s3,uchar s4,uchar san)
  430. {   
  431.      if(san==1)
  432.      {
  433.         if(msecond_count<5)
  434.         {
  435.            display1(s1);
  436.         }
  437.      }
  438.      else
  439.      {
  440.          display1(s1);
  441.      }
  442.      if(san==2)
  443.      {
  444.         if(msecond_count<5)
  445.         {
  446.            display2(s2);
  447.         }
  448.      }
  449.      else
  450.      {
  451.          display2(s2);
  452.      }
  453.      if(san==3)
  454.      {
  455.         if(msecond_count<5)
  456.         {
  457.            display3(s3);
  458.         }
  459.      }
  460.      else
  461.      {
  462.          display3(s3);
  463.      }
  464.      if(san==4)
  465.      {
  466.         if(msecond_count<5)
  467.         {
  468.            display4(s4);
  469.         }
  470.      }
  471.      else
  472.      {
  473.          display4(s4);
  474.      }     
  475. }
  476. //****************************************
  477. //時(shí)鐘顯示程序
  478. void  dis(uchar s1,uchar s2,uchar s3,uchar s4)
  479. {
  480.      display1(s1);
  481.      display2(s2);
  482.      display3(s3);
  483.      display4(s4);

  484. }



  485. //****************************************
  486. //判斷繼電器是否動(dòng)作處理函數(shù)
  487. void  judge_dongzuo()
  488. {
  489.    if(low_high==0)//低于下限時(shí)繼電器動(dòng)作或復(fù)位處理程序
  490.    {
  491.      if(dongzuo_flag==0 && temp_flag==0 && setlow_f==0 && temp32>=set_l)
  492.      {
  493.         jidianqi=1;//繼電器動(dòng)作  
  494.         dongzuo_flag=1;//繼電器動(dòng)作標(biāo)志為1
  495.      }
  496.      if(dongzuo_flag==0 && temp_flag==0 && setlow_f==1)
  497.      {
  498.         jidianqi=1;//繼電器動(dòng)作
  499.         dongzuo_flag=1;//繼電器動(dòng)作標(biāo)志為1
  500.      }
  501.      if(dongzuo_flag==0 && temp_flag==1 && setlow_f==1 && temp32<set_l)
  502.      {
  503.         jidianqi=1;
  504.         dongzuo_flag=1;
  505.      }
  506.      if(dongzuo_flag==1 && temp_flag==1 && sethigh_f==1&& temp32>=set_h)
  507.      {
  508.         dongzuo_flag=0;
  509.         jidianqi=0;
  510.      }
  511.      if(dongzuo_flag==1 && temp_flag==0 && sethigh_f==0 && temp32<=set_h)
  512.      {
  513.         dongzuo_flag=0;
  514.         jidianqi=0;
  515.      }
  516.      if(dongzuo_flag==1 && temp_flag==1 && sethigh_f==0 )
  517.      {
  518.         dongzuo_flag=0;
  519.         jidianqi=0;
  520.      }
  521.    }
  522.    if(low_high==1)//高于上限時(shí)繼電器動(dòng)作和復(fù)位處理程序
  523.    {
  524.      if(dongzuo_flag==0 && temp_flag==0 && sethigh_f==0 && temp32<set_h)
  525.      {
  526.         jidianqi=1;//繼電器動(dòng)作  
  527.         dongzuo_flag=1;//繼電器動(dòng)作標(biāo)志為1
  528.      }
  529.      if(dongzuo_flag==0 && temp_flag==1 && sethigh_f==0)
  530.      {
  531.         jidianqi=1;//繼電器動(dòng)作
  532.         dongzuo_flag=1;//繼電器動(dòng)作標(biāo)志為1
  533.      }
  534.      if(dongzuo_flag==0 && temp_flag==1 && sethigh_f==1 && temp32>=set_h)
  535.      {
  536.         jidianqi=1;
  537.         dongzuo_flag=1;
  538.      }
  539.      if(dongzuo_flag==1 && temp_flag==1 && setlow_f==1&& temp32<set_l)
  540.      {
  541.         dongzuo_flag=0;
  542.         jidianqi=0;
  543.      }
  544.      if(dongzuo_flag==1 && temp_flag==0 && setlow_f==0 && temp32>=set_l)
  545.      {
  546.         dongzuo_flag=0;
  547.         jidianqi=0;
  548.      }
  549.      if(dongzuo_flag==1 && temp_flag==0 && setlow_f==1 )
  550.      {
  551.         dongzuo_flag=0;
  552.         jidianqi=0;
  553.      }

  554.    }


  555. }
  556. void  countavetemp()//計(jì)算平均溫度
  557. {
  558.     /* readtemp_ds18b20();
  559.     // temp32=5;
  560.     // t_x=4;
  561.      temp32_1=temp32*100+t_x*10;
  562.      readtemp_ds18b20();
  563.      //temp32=28;
  564.     // t_x=5;
  565.      temp32_2=temp32*100+t_x*10;
  566.      temp_ave=temp32_2+temp32_1;
  567.      temp32_1=temp_ave/2;
  568.      t_x=temp32_1/10%10;
  569.      temp_ave=temp32_1/100;
  570.      t_b=temp_ave/100%10;//計(jì)算溫度的百位數(shù)據(jù)
  571.      t_s=temp_ave/10%10;//計(jì)算溫度的十位數(shù)據(jù)
  572.      t_g=temp_ave%10;//計(jì)算溫度的個(gè)位數(shù)據(jù)*/
  573.      readtemp_ds18b20();
  574.      t_b=temp32/100%10;//計(jì)算溫度的百位數(shù)據(jù)
  575.      t_s=temp32/10%10;//計(jì)算溫度的十位數(shù)據(jù)
  576.      t_g=temp32%10;//計(jì)算溫度的個(gè)位數(shù)據(jù)*/

  577. }
  578. //****************************************************
  579. //讀取溫度
  580. void readtemp_ds18b20(void)
  581. {

  582.       rest_ds18b20();
  583.       w_1byte_ds18b20(0xcc); //跳過讀序列號的操作
  584.       w_1byte_ds18b20(0x44); //啟動(dòng)溫度轉(zhuǎn)換
  585.       delay_8us(2);
  586.       rest_ds18b20();
  587.       w_1byte_ds18b20(0xcc); //跳過讀序列號的操作
  588.       w_1byte_ds18b20(0xbe); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
  589.       templ=r_1byte_ds18b20();
  590.       temph=r_1byte_ds18b20();
  591.    //  templ=0x98;
  592.    //  temph=0xFc;
  593.       if((temph&0xf0))//判斷溫度的正負(fù)性
  594.       {
  595.       temp_flag=0;//溫度為負(fù)數(shù)標(biāo)志
  596.       temph=~temph;
  597.       templ=~templ;
  598.       t_x=tabl3[templ & 0x0f];//計(jì)算溫度的小數(shù)
  599.       temp32=temph & 0x0f;
  600.       temp32<<=4;
  601.       templ>>=4;
  602.       temp32=temp32 | templ;

  603.     }
  604.     else//為正數(shù)
  605.     {
  606.       temp_flag=1;
  607.       t_x=tabl3[templ & 0x0f];//計(jì)算溫度的小數(shù)
  608.       temp32=temph & 0x0f;
  609.       temp32<<=4;
  610.       templ>>=4;
  611.       temp32=temp32 | templ;
  612.      }
  613. }

  614. void dis_temp()//溫度顯示函數(shù)
  615. {

  616.      if(temp_flag==1)//溫度為正數(shù)
  617.      {
  618.         if(t_b==0)//判斷溫度的百位數(shù)
  619.        {
  620.           display1(12);
  621.           display2(t_s);//顯示溫度的十位數(shù)據(jù)
  622.           display3_dian(t_g);//顯示溫度的個(gè)位數(shù)據(jù)
  623.           display4(t_x);//顯示溫度的小數(shù)位
  624.        }
  625.        else
  626.        {
  627.           display1(t_b);//顯示溫度的百位數(shù)據(jù)
  628.           display2(t_s);//顯示溫度的十位數(shù)據(jù)
  629.           display3_dian(t_g);//顯示溫度的個(gè)位數(shù)據(jù)
  630.           display4(t_x);//顯示溫度的小數(shù)位
  631.        }
  632.      }
  633.      else//下為負(fù)溫度的處理程序
  634.      {
  635.          display1(14);//顯示-號
  636.          display2(t_s);//顯示溫度的十位數(shù)據(jù)
  637.          display3_dian(t_g);//顯示溫度的個(gè)位數(shù)據(jù)
  638.          display4(t_x);//顯示溫度的小數(shù)位
  639.      }
  640. }

  641. //***************************************************************
  642. //功能:把數(shù)據(jù)1顯示在數(shù)碼管1上
  643. void display4(uchar dis_data)
  644. {
  645.    smg_data=tabl1[dis_data];//送顯示斷碼
  646.    dis_bit4=0;//鎖存數(shù)據(jù)
  647.    delay_50us(40);
  648.    dis_bit4=1;
  649. }//***************************************************************
  650. //功能:把數(shù)據(jù)1顯示在數(shù)碼管1上
  651. void display3(uchar dis_data)
  652. {
  653.    smg_data=tabl1[dis_data];//送顯示斷碼
  654.    dis_bit3=0;//鎖存數(shù)據(jù)
  655.    delay_50us(40);
  656.    dis_bit3=1;
  657. }
  658. //功能:帶小數(shù)點(diǎn),把數(shù)據(jù)顯示在數(shù)碼管3上
  659. void display3_dian(uchar dis_data)
  660. {
  661.    smg_data=tabl2[dis_data];//送顯示斷碼
  662.    dis_bit3=0;//鎖存數(shù)據(jù)
  663.    delay_50us(40);
  664.    dis_bit3=1;
  665. }
  666. //***************************************************************
  667. //功能:把數(shù)據(jù)1顯示在數(shù)碼管1上
  668. void display1(uchar dis_data)
  669. {
  670.    smg_data=tabl1[dis_data];//送顯示斷碼
  671.    dis_bit1=0;//鎖存數(shù)據(jù)
  672.    delay_50us(40);
  673.    dis_bit1=1;
  674. }
  675. //***************************************************************
  676. //功能:把數(shù)據(jù)1顯示在數(shù)碼管1上
  677. void display2(uchar dis_data)
  678. {
  679.    smg_data=tabl1[dis_data];//送顯示斷碼
  680.    dis_bit2=0;//鎖存數(shù)據(jù)
  681.    delay_50us(40);
  682.    dis_bit2=1;
  683. }
  684. //**************************************************************************************************
  685. //函數(shù)名稱:void delay_50US(unsigned int t)
  686. //功能: 延時(shí)50*t(us)
  687. void delay_50us(uint t)
  688. {
  689.   unsigned char j;
  690.   for(;t>0;t--)
  691.   {
  692.     for(j=19;j>0;j--);
  693.   }
  694. }
  695. //*******************************************************************************
  696. //8微秒延時(shí)基準(zhǔn)程序
  697. void delay_8us(uint t)
  698. {
  699. while(--t);
  700. }
  701. //*******************************************************************************
  702. //3微秒延時(shí)程序
  703. void delay_3us()
  704. {
  705.   ;
  706.   ;
  707. }
  708. //*******************************************************************************
  709. //子程序功能:向DS18B20寫一字節(jié)的數(shù)據(jù)
  710. void w_1byte_ds18b20(uchar value)
  711. {
  712.    uchar i=0;
  713.    for(i=0;i<8;i++)
  714.    {
  715.     dq_ds18b20=0;
  716.     delay_3us();
  717.     if (value & 0x01) dq_ds18b20=1; //DQ = 1
  718.     delay_50us(1); //延時(shí)50us 以上
  719.    value>>=1;
  720.      dq_ds18b20=1; //DQ = 1
  721.    }
  722.     delay_50us(1);
  723. }
  724. //讀一個(gè)字節(jié)
  725. uchar r_1byte_ds18b20(void)
  726. {
  727.   uchar i=0;
  728.   uchar value = 0;
  729.   for (i=0;i<8;i++)
  730.   {
  731.    value>>=1;
  732.    dq_ds18b20=0;// DQ_L;
  733.    delay_3us();
  734.    dq_ds18b20=1;
  735.    delay_3us();
  736.   delay_3us();
  737.    if(dq_ds18b20==1) value|=0x80;
  738.    delay_50us(1); //延時(shí)40us
  739.   }
  740.   return value;
  741. }
  742. //;**************************************************
  743. //ds18b20復(fù)位子程序
  744. void rest_ds18b20(void)
  745. {
  746. rest:delay_3us(); //稍做延時(shí)
  747.      delay_3us();
  748.      dq_ds18b20=1;
  749.      delay_3us();
  750.      dq_ds18b20=0;// DQ_L;
  751.      delay_8us(75);//480us<T<960us
  752.      dq_ds18b20=1;//拉高總線
  753.      delay_8us(8);
  754.      if(dq_ds18b20==1)
  755.      {
  756.        return;
  757.      }
  758.      delay_8us(11); //延時(shí)90us
  759.      if(dq_ds18b20==1)
  760.      {
  761.        return;
  762.       }
  763.       else
  764.       {
  765.        goto rest;
  766.       }
  767. }
  768. void timer0() interrupt 1
  769. {
  770.               TH0=(65536-50000)/256;
  771.               TL0=(65536-50000)%256;
  772.               t0_crycle++;
  773.               if(t0_crycle==2)// 0.1秒
  774.               {
  775.                 t0_crycle=0;
  776.                 msecond_count++;
  777.       if(msecond_count==10)//1秒
  778.       {
  779.         msecond_count=0;
  780.       }   
  781.               }
  782. }
  783. //********************************************************************************************
  784. void init_t0()
  785. {
  786.                  TMOD=0x01;//設(shè)定定時(shí)器工作方式1,定時(shí)器定時(shí)50毫秒
  787.               TH0=(65536-50000)/256;
  788.               TL0=(65536-50000)%256;
  789.               EA=1;//開總中斷
  790.               ET0=1;//允許定時(shí)器0中斷
  791.               t0_crycle=0;//定時(shí)器中斷次數(shù)計(jì)數(shù)單元
  792. }
  793. //*************************************************
  794. //功能:發(fā)送非應(yīng)答信號
  795. void nack_24c16()
  796. {
  797. sda_24c16=1;   
  798. delay_3us();
  799. delay_3us();
  800. scl_24c16=1;
  801. delay_3us();
  802. delay_3us();
  803. scl_24c16=0;
  804. sda_24c16=0;
  805. }
  806. ……………………

  807. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)



所有資料51hei提供下載:
溫控.zip (516.96 KB, 下載次數(shù): 230)



作者: 我回來了鯊魚    時(shí)間: 2018-4-19 11:17
什么東西,原理圖與論文不符,原理圖垃圾的還是錯(cuò)的
作者: 小傻白甜    時(shí)間: 2019-2-20 09:49
下載的東西亂七八糟的。
作者: BestZed    時(shí)間: 2019-3-14 13:36
感謝分享                    
作者: 85464684321    時(shí)間: 2019-3-14 14:18
學(xué)習(xí)一下,謝謝分享
作者: 月杯星    時(shí)間: 2019-11-10 15:14
學(xué)習(xí)一下,感謝分享!
作者: 塞12    時(shí)間: 2019-11-29 19:35
很好的一篇




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1