久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7636|回復: 3
收起左側

單片機+TLC2543濕敏HS1101 NTC熱敏 溫濕度計仿真程序設計

  [復制鏈接]
ID:367029 發表于 2019-9-20 17:23 | 顯示全部樓層 |閱讀模式
上個月剛做的智能儀器儀表設計。
首先感謝51黑,這次設計用到的很多程序都參考了51黑大神們的分享。
溫濕度計本身也有很多大佬有發,我的設計也沒有什么高明之處,還望見諒。
溫度傳感器為NTC熱敏電阻,濕度傳感器為HS1101濕敏電容,用的12位ADC。溫濕度測量分辨率0.01,精度0.5%。
仿真圖如下
0.png
51hei.gif

本文的主要目標是設計一款具有較高精度的低成本溫度、濕度監測儀表。該溫濕度監測儀表的主要功能及性能指標如下:

溫度測量范圍:0~99 ℃

濕度測量范圍:0%~100% RH

溫度分辨率:0.2 ℃

濕度分辨率:1% RH

溫度值精度:±2 ℃

濕度值精度:±2% RH

為了降低成本,同時提高精度,本溫濕度監測儀表大量采用模擬電路以代替價格高昂的集成芯片,產品預期效果圖如圖1-1所示。

圖1-1 溫濕度檢測儀表預期成果圖


二、整體設計方案
2.1 設計任務

本文的主要目標是設計一款具有較高精度的低成本溫度、濕度監測儀表。設計動態性能更好的模擬電路以替代集成芯片。

該溫濕度監測儀表需要滿足以下性能指標:

溫度測量范圍:0~99 ℃

濕度測量范圍:0%~100% RH

溫度分辨率:0.2 ℃

濕度分辨率:1% RH

溫度值精度:±2 ℃

濕度值精度:±2% RH

2.2 設計原則

要求嵌入式系統應具有高可靠性、易維護、高性價比等特點。設計原則有以下幾個:

(1)可靠性高

可靠性是單片機系統應用的前提,在系統設計的每一個環節,都應該將可靠性作為首要的設計準則。提高系統的可靠性通常從以下幾個方面考慮:使用可靠性高的元器件;設計電路板時布線和接地要合理;對供電電源采用抗干擾措施;進行軟硬件濾波等。

(2)易維護

在系統的軟硬件設計時,應從操作者的角度考慮操作和維護方便,盡量減少對操作人員專業知識的要求,以利于系統的推廣。因此在設計時,要盡可能減少人機交互接口,多采用操作內置或簡化的方法。

(3)性價比高

微處理器除體積小、功耗低等特點外,最大的優勢在于高性能價格比。一個嵌入式系統能否被廣泛應用,性價比是其中一個關鍵因素。因此,在設計時,除了保持高性能外,盡可能降低成本,在系統性能和速度允許的情況下盡可能用軟件功能取代硬件功能等。

2.3 元件選型
2.3.1 嵌入式芯片

本文所設計的溫濕度監測計要求在實現長時間穩定工作的基礎上,進一步提高性能,降低成本。因此,核心運算部分選用久經市場考驗的STC89C52RC芯片。它內部集成了通用8位中央處理器和8 kb Flash存儲單元,功能上滿足溫濕度計的設計需要。同時,STC89C52芯片可以在0~75℃的環境下正常工作,具有較強的穩定性和抗干擾能力。

圖2-1 STC89C52實物圖

2.3.2 顯示模塊

液晶顯示的原理是利用液晶的物理特性,通過電壓對其顯示區域進行控制,有電就有顯示,這樣即可以顯示出圖形。1602具有輕薄短小、低壓微功耗、體積小、無輻射、平面直角顯示及影像穩定不閃爍等優點,且可視面積大、效果好、分辨率高、抗干擾能力強,適合用于顯示字母、數字、符號等信息,而且不需要擴展過多外圍電路,可由單片機直接進行控制輸出顯示。


2.3.3 熱敏元件

計量溫度的單位有攝氏度和華氏度兩種單位。攝氏度和華氏度。

攝氏度是目前世界上使用較為廣泛的一種溫標——攝氏溫標的溫度計量單位,用符號“℃”表示。指在1標準大氣壓下,純凈的冰水混合物的溫度為0度,水的沸點為100度,其間平均分為100份,每一等份為1度,記作1℃。它最初是由瑞典天文學家安德斯·攝爾修斯(Anders Celsius,1701~1744)于1742年提出的,其后歷經改進。攝氏溫度現已納入國際單位制(SI)。T(K)=t(℃)+273.15,T為絕對溫度。

華氏度也是溫度的一種度量單位,以其發明者德國人華倫海特(Gabriel D. Fahrenheit,1681—1736)命名的。由于種種歷史局限性,華氏溫標正逐漸退出歷史舞臺,因此,本系統默認顯示攝氏溫標。

測量溫度的傳感器有很多種,其中熱敏電阻器是最早應用也是應用最廣泛的一類測溫元件。熱敏電阻屬于敏感元件,按照溫度系數不同分為正溫度系數熱敏電阻器(PTC)和負溫度系數熱敏電阻器(NTC)。熱敏電阻的典型特點是對溫度敏感,不同的溫度下會表現出不同的電阻值。PTC電阻在溫度越高時電阻值越大,NTC電阻在溫度越高時電阻值越低,根據這個特性可以制作出各種形式的溫度傳感器。

本系統的溫度采集電路核心傳感元件采用玻封熱敏電阻NTC-MF58A104F3950FA,這款型號的熱敏電阻為軸向引線,由于采用隔熱玻璃封裝的形式,所以其不易受輕微的熱流擾動,大大提高了溫度測量的靈敏度和精確度。本文所選熱敏電阻的阻值為100千歐,B值為3950,阻值精度和B值精度均為1%。

熱敏電阻價格低廉,小巧堅固,穩定性好,熱感應快,被廣泛應用于多種行業的溫度檢測系統。除了查詢溫度/阻值對照表以外,NTC熱敏電阻還有其溫度/阻值計算公式,本文所選型號熱敏電阻在25℃下的B值為3950,因此其計算公式如下所示:

                 (1)

化簡公式,并加上0.5的誤差校正后,MF58熱敏電阻的溫度與所測阻值的關系式為:

                 (2)

通過上述溫度/阻值計算公式,可以得出更高分辨率的溫度值,在后面的溫度測量中采用的正是通過公式法計算所測溫度。

2.3.4 濕敏元件

空氣的濕度有絕對濕度和相對濕度之分。

空氣中水蒸氣的壓強 p 叫做空氣的絕對濕度,可以用空氣中所含水蒸汽的密度,即單位體積的空氣中所含水蒸汽的質量來表示。由于直接測量空氣中水蒸氣的密度比較困難,而水蒸氣的壓強隨水蒸氣密度的增大而增大,所以通常用空氣中水蒸氣的壓強來表示空氣的濕度。

絕對濕度被廣泛應用于天氣預測上,而與我們生產生活密切相關的是相對濕度,即空氣中實際水汽壓與當時氣溫下的飽和水汽壓之比的百分數。常見的濕度測量方法有伸縮式溫度計、干濕球溫度計、露點溫度計、濕敏電阻和濕敏電容等。其中伸縮式溫度計精度最高,但不能轉換成電信號,干濕球溫度計和露點溫度計體積較大,且難以長時間穩定工作。濕敏電阻是利用濕敏材料吸收空氣中的水分而導致本身電阻值發生變化這一原理而制成的,工業上流行的濕敏電阻主要有:氯化鋰濕敏電阻,有機高分子膜濕敏電阻,但濕敏電阻只能用于交流電工作環境,直流電會導致高分子材料中的帶電粒子偏向兩極,從而導致其無法正常工作。

因此,本文選擇法國Humirel公司設計生產的濕敏電容HS1101作為濕度監測敏感元件,它也可以稱為MHS1101。它對濕度的監測精度高達±2%RH,典型值為180pF@55%RH,即在工作頻率為10 KHz、環境溫度為25℃、相對濕度為55%RH時測得電容為180 pF。在上述條件下,HS1101的電容變化范圍大致為160pF~200pF, RF特性曲線如圖所示,可以明顯的看出它具有極好的線性輸出。此外,依靠其獨特的固態聚合物結構,HS1101還具有優異的長期穩定性及可靠性,漂移量僅0.5%RH/年。

圖2-2 HS1101濕度電容特性曲線

2.3.5 模數轉換芯片

信號調理電路將電阻和電容的變化量轉換為電壓的變化量,因此,數據采集電路需要使用模數轉換芯片采集兩路電壓信號,基于低成本的原則,本文選擇美國TI公司生產的一種12位多通道A/D轉換芯片TLC2543作為模數轉換芯片,圖2-3為TLC2543的內部電路圖。

圖2-3 TLC2543的內部電路圖

TLC2543是一種12位開關電容逐次逼近A/D 轉換器,芯片共有11個模擬輸入通道。芯片的三個控制端: 串行三態輸出數據端(DATA OUTPUT)、輸人數據端(DATA INPUT)、輸人/出時鐘(I/O CLOCK)能形成與微處理器之間數據傳輸較快和較為有效的串行外設接口——SPI。片內具有一個14 通道多路選擇器用于在11個模擬輸人通道和3 個內部自測試(SELF-TEST)電壓中任選一個,可通過對其8 位內部控制寄存器進行編程完成通道的選擇,并可對輸出結果的位數、MSB/I.SB 導前和極性進行選擇。


2.4 方案設計思路

溫濕度監測系統的設計以嵌入式微處理器STC89C52為核心,熱敏元件NTC-MF58和濕敏元件HS1101作為物理量敏感元件,通過硬件電路將敏感元件變化的物理量轉換成模數轉換芯片可以獲取識別的電壓模擬量,再由模數轉換芯片將電壓模擬量轉換為數字量,通過串行通信接口傳給微處理器。最后經過軟件算法的處理,得出精確的溫度、濕度數值,并將數據通過LCD液晶屏呈現給用戶。

因此,整個方案設計應包含四個部分,即:信號調理部分、模數轉換部分、嵌入式系統部分、人機交互部分。設計思路如圖2-4所示,信號調理部分包含了傳感器和多個不同類型的轉換電路。

圖2-4 整體設計方案思路


三、理論分析

儀器儀表最重要的性能指標之一為精度,在設計系統硬件和軟件之前,需要對設計方案做系統而完備的理論分析。以便于在軟、硬件設計時對不合理之處進行修改補償。

溫敏元件和濕敏元件的物理量分別為電阻和電容,通過信號調理電路將電阻轉換為電壓;將電容依次轉換為頻率、電壓。由于微處理采集的是8位分辨率的電壓信號,因此需要多個計算公式將電壓值轉換為頻率、電容、電阻,最后根據敏感元件的特性轉換為對應的溫度、濕度值。其中需要的算法及步驟如下所示:

整理可得:

其中VolOut分別為微處理器采集的兩路電壓數字量,R、C分別為溫敏元件的電阻和濕敏元件的電容。多次轉換會帶來信號上的失真,且微處理器難以高精度地執行數據處理算法。本課題組使用Matlab工具軟件,通過模擬微處理器的運算方式計算出系統的理論誤差。其中溫度測量的最大誤差為1.8℃,濕度測量的最大誤差為2.0%RH,因此,需要在軟件設計中通過合適的算法補償誤差,使顯示結果接近真值。

四、系統硬件設計

整體硬件由STC89C52RC嵌入式運算芯片、LCD1602液晶顯示器、濕敏電容HS1101、溫敏電阻MF58、模數轉換芯片TLC2543、555計時器和LM331構成。基于上述硬件模塊的外圍電路分別為單片機最小系統電路、LCD1602驅動電路、TLC2543驅動電路、電阻電壓轉換電路、電容頻率轉換電路、電壓頻率轉換電路等。

本節以硬件模塊為中心分別介紹各個硬件及其外圍電路。

4.1 STC89C52RC

本設計選擇STC89C52RC作為主控芯片,其最小系統由單片機芯片、時鐘電路及復位電路四部分組成。

(1)時鐘電路

本設計采用外部時鐘方式,時鐘電路圖如圖4-1所示。AT89C52中有高增益的反相放大器,它是構成內部振蕩器的主要單元,XTAL1和XTAL2兩個引腳分別是該放大器的輸出端和輸入端。晶振和放大器共同構成了自激振蕩器,兩個旁路電容與外接晶振接在具有反饋功能的放大器中,構成了并聯反饋振蕩電路。

圖4-1 時鐘電路

C1、C2 為旁路電容,對頻率有微調作用,電容值根據晶振要求來選擇,對振蕩器的穩定性、幅值有輕微的影響。但如果C1、C2 值相差太大,容易引發諧振不平衡,所以此處選擇電容大小為100pF,以確保振蕩器的穩定性。


(2)復位電路

無論是在單片機剛開始接上電源時,還是運行過程中發生故障都需要復位。故復位電路是單片機小系統中重要的一環,如圖4-2所示。

復位電路用于將單片機內部各電路的狀態恢復到一個確定的初始值,并從這個狀態開始工作。單片機的復位條件:必須使其RST引腳上持續出現兩個(或以上)機器周期的高電平。

圖4-2 復位電路

單片機有兩種復位形式:上電復位和按鍵復位。

上電復位電路中,利用電容充電來實現復位。在電源接通瞬間,RST引腳上的電位是高電平(VCC),電源接通后對電容進行快速充電,隨著充電的進行,RST引腳上的電位也會逐漸下降為低電平。只要保證RST引腳上高電平出現的時間大于兩個機器周期,便可以實現正常復位。

按鍵復位電路中,當按鍵沒有按下時,電路同上電復位電路。如在單片機運行過程中,按下S1鍵,已經充好電的電容會快速通過電阻的回路放電,從而使得RST引腳上的電位快速變為高電平,此高電平會維持到按鍵釋放,從而滿足單片機復位的條件實現按鍵復位。


4.2 溫度采集電路

溫敏元件為NTC熱敏電阻,隨著溫度的變化,其電阻阻值會發生相應的變化。因此,本溫度采集電路的功能是將電阻變化量轉化為電壓變化量,嵌入式微處理器會將采集到的電壓量通過算法轉換成溫度量。

圖4-3 電阻轉電壓電路

溫度采集電路如圖4-3所示,為一種基于歐姆定律的電阻轉電壓電路,也稱為電阻分壓電路。分壓電路輸出電壓的計算公式為

其中RT1為熱敏電阻。輸入電壓VCC和電阻R10固定不變時,如果熱敏電阻的阻值發生變化,輸出電壓會隨之發生變化。

當嵌入式微處理器采集到電壓數據時,可以通過分壓電路輸出電壓公式反向推導出對應的電阻值,具體計算公式如下所示


4.3 濕度采集電路

MHS1101的電容隨著濕度的變化而變化,因此,獲取準確的電容值即可通過電容-濕度表或換算公式得到濕度值。由于單片機無法直接采集電容物理量,因此需要通過設計測量電路將電容值轉換為單片機可采集的模擬量或數字量。

濕度采集電路分為兩部分,首先將MHS1101置于555振蕩電路(C/F)中,將電容值轉換成方波脈沖信號,由于轉換后的頻率范圍在6kHz~7kHz之間,屬于中高頻,核心芯片難以有效采集,因此,本文設計了頻率轉電壓(F/V)電路,將555振蕩電路輸出的頻率信號進一步線性轉換成電壓信號,便于處理器的高效采集與處理。

1. C/F電路

C/F電路如圖4-4所示。555芯片外接電阻R1,R2與MHS1101,構成對MHS1101的充電回路。7端通過芯片內部的晶體管對地短路實現對MHS1101的放電回路,并將引腳2,6端相連引入到片內比較器,構成一個多諧波振蕩器,其中,R1相對于R2必須非常的小,但決不能低于一個最小值。R4是防止短路的保護電阻。

圖4-4 電容轉頻率電路

MHS1101作為一個變化的電容器,連接2和6引腳。引腳作為R1的短路引腳。MHS1101的等效電容通過R1和R2充電達到上限電壓(近似于0.67VCC,時間記為T1),這時555的引腳3由高電平變為低電平,然后通過R2開始放電,由于R1被7引腳內部短路接地,所以只放電到觸發界線(近似于0.33VCC,時間記為T2),這時555芯片的引腳3變為高電平。通過不同的兩個電阻R1,R2進行傳感器的不停充放電,產生方波輸出。

充電、放電時間分別為:

輸出波形的頻率和占空比的計算公式如下:

由此可以看出,空氣相對濕度與555定時器輸出頻率存在一定線性關系。表1給出了典型頻率濕度關系(參考點:25℃,相對濕度:55%,輸出頻率:6.208kHz)。在對精度要求不高的場合,可以通過微處理器采集555定時器輸出的頻率,然后查表即可得出相對濕度值。

表1 部分典型頻率/濕度對照表

RH(%)

0

10

20

30

40

50

60

70

80

Frequency

6852

6734

6618

6503

6388

6271

6152

6029

5901


2. F/V電路

頻率/電壓轉換電路就是把輸入的脈沖信號轉換為電壓信號輸出的一種電路。輸出的電壓與輸入的脈沖頻率成線性關系,并可通過測量其輸出端的電壓值來間接測量輸入的脈沖頻率。目前市面上已有成熟的基于ΣΔ技術的頻率/電壓轉換芯片,但是芯片的成本較高,構成的電路結構比較復雜,功耗較大。本文選擇了基于LM331頻率轉換芯片設計的頻率/電壓轉換電路,其由專用的頻率/電壓轉換芯片LM331及少量的電阻電容組成。

圖4-5 頻率轉電壓電路

LM331外接電路簡單,只需接入幾個外部元件就可方便構成V/F或F/V等變換電路,并且轉換精度較高。LM331構成的頻率/電壓轉換電路如圖4-5所示,經C/F電路輸出的頻率FreOut經過R3、C1組成的微分電路加到LM331的6腳。當FreOut的下降沿到來時經過微分電路將在6腳產生負向尖峰脈沖,當負向尖峰脈沖大于VCC/3時LM331的內部觸發器將置位,其內部的電流源對電容C3充電,同時電源VCC通過R7對電容C2充電。當C3上的電壓大于2VCC/3時, LM331內部的觸發器復位,C3通過R8放電,同時定時電容C2迅速放電,完成一次充放電過程。此后,每經過一次充放電過程電路重復上面的工作過程,這樣就實現了頻率/電壓的轉換。LM331輸出的電壓Vol2Out與輸入信號頻率FreOut的關系可表示為:

              此關系式具有較好的線性度,且轉換速度快,便于微處理器進行采集處理。

4.4 模數轉換電路

TLC2543具有20個引腳,TLC2543與單片機的接口應為5條數據線,分別是CS、CLK、SDO、SDI和EOC。

圖4-6 模數轉換電路

              模數轉換電路的驅動電路如圖4-6所示,其中AIN0、AIN1端口分別連接溫度采集電路和濕度采集電路的電壓輸出端,CS、CLK、SDO、SDI和EOC則與微處理器通用I/O口相連接。

4.5 液晶屏驅動電路

              LCD1602液晶屏采用標準的16腳接口,驅動電路如圖4-7所示。其中1號引腳和2號引腳分別為地電源和正電源。3號引腳為顯示器對比度調整端,電壓越高,對比度越低,接地時對比度最高。LCD驅動電路中使用可調電阻,方便使用者調整對比度。

4號引腳RS端為寄存器選擇端,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器。RW為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。EN端為使能端,高電平時讀取信息,負跳變時執行指令。D0~D7為8位雙向數據端。第15引腳為背光正極,第16引腳背光負極,加入隔離電容C9可以防止顯示器燒壞。

圖4-7 LCD1602驅動電路


五、系統軟件設計
5.1 軟件設計思路

              本課題設計的溫濕度檢測儀表具有較多的功能,且各個功能模塊對實時性的要求較高,因此本系統引入了多任務實時操作系統,所有功能子程序均運行在實時系統之上。整體設計思路如圖5-1所示

圖5-1 系統軟件設計思路

              job 0執行各個模塊的初始化程序,初始化完畢后,會創建job 1、job 2、job 3三個功能任務,最后刪除job 0的任務,因此,job 0任務在微處理器運行過程中只執行一次。

              job 1、job 2、job 3三個功能任務為同級輪轉任務,每個任務分得的時間均為10 ms,各自的運行時間結束后,會按順序跳轉執行下一個任務。在一個標準時間內,每個軟件功能模塊都會得到運行,不會出現由于大規模的數據處理導致其他功能停滯的現象。


5.2 實時系統的設計(程序暫未實現)

RTX-51 TINY是一個由美國Keil公司設計開發的用于8051系列處理器多任務實時操作系統。RTX-51采用時間片輪轉任務切換和使用信號進行任務切換,所有的任務平等運行,占用資源極低。

RTX-51 TINY的程序用標準的C語言構造,在傳統的C語言程序入口都是從main函數作為入口,而基于RTX-51 TINY構建的嵌入式程序卻沒有main函數,而是從任務0(job 0)開始執行的。在job 0中執行各個模塊的初始化程序,程序執行后,關閉job 0,開始輪流執行其他job函數。RTX-51 TINY使用無優先級時間片輪詢法,每個任務使用相同大小的時間片,時間片可以在相關參數配置中進行修改設置。

RTX51 Tiny的配置參數中有INT_CLOCK和TIMESHARING兩個參數。這兩個參數決定了每個任務使用時間片的大小:INT_CLOCK是時鐘中斷使用的周期數,也就是基本時間片;TIMESHARING是每個任務一次使用的時間片數目。兩者決定了一個任務一次使用的最大時間片。本系統設置INT_CLOCK為10000,即TIMESHARING=1,一個任務使用的最大時間片是10ms。

實時系統相關代碼如下圖5-2所示:

圖5-2 實時系統部分代碼(暫未實現 調試中)


5.3 功能子程序的設計
1.模擬量采集模塊

TLC2543與單片機的接口應為5條數據線,分別是CS、CLK、SDO、SDI和EOC。模擬量采集模塊開始工作后,片選CS必須從高到低,才能開始一次工作周期,此時EOC為高,輸入數據寄存器被置為0,輸出數據寄存器的內容是隨機的。

開始采集時,CS片選為高,I/O CLOCK、DATA INPUT被禁止,DATA OUT 呈高阻狀,EOC為高。接下來使CS變低,I/OCLOCK、DATAINPUT使能,DATAOUT脫離高阻狀態。12個時鐘信號從I/OCLOCK端依次加入,隨著時鐘信號的加入,控制字從DATAINPUT一位一位地在時鐘信號的上升沿時被送入TLC2543(高位先送入),同時上一周期轉換的A/D數據,即輸出數據寄存器中的數據從DATAOUT一位一位地移出(下降沿),在CS=0時輸出第一位,其他的在下降沿輸出。部分代碼如圖所示5-3所示,為TLC2543讀取低8位轉換結果。

圖5-3 讀取低8位轉換結果


2. LCD顯示模塊

              LCD1602的驅動程序一共有3個功能子程序,分別為初始化函數、寫命令函數和寫數據函數。具體函數如圖5-4所示。

圖5-4 LCD1602驅動程序


5.4 數據處理算法

              在理論分析中已經說明,嵌入式微處理并不能負擔大規模的實時數據處理運算。但是可以通過化簡、等價代換等方法將多個公式組合成線性表達式,如下所示:

              代入各個電阻、電容的數值,化簡可得:


              由于理論計算與實際典型值有偏差,因此需要對計算公式進行補償,其中補償后溫度處理算法如圖5-5所示,補償后的濕度處理算法如圖5-6所示,對不同大小的計算電容值做出對應的補償,可以有效的使最終結果逼近真值。

圖5-5 溫度處理算法

圖5-6 濕度處理算法


六、系統調試和實驗結果分析
6.1 仿真測試

在完成硬件設計和軟件編程后,啟動Proteus軟件進行仿真,仿真測試結果如圖6-1所示。啟動仿真后,LCD屏幕首先會顯示開機界面,如圖6-1所示。

圖6-1 開機界面

啟動后1秒鐘以內,LCD屏幕即能夠顯示當前時刻的溫度值、濕度值和敏感元件的物理量,且串口也會同步發送對應數據。

圖6-2 Proteus仿真示意圖

如圖6-2所示,在NCT熱敏電阻設定的虛擬溫度值為28. 0℃時,本溫濕度檢測儀表顯示溫度值為27.85℃。HS1101濕敏電容設定電容值為180pF,儀表顯示測得的濕敏電容的電容為179.74pF。根據HS1101特性曲線可知,180pF電容值下對應的環境濕度為49.15%RH,本溫濕度檢測儀表顯示濕度值為48.35%RH。

              本課題組針對此溫濕度檢測儀表進行了多組測試,測試結果如下表所示。

表1 對比測試表


1

2

3

4

5

實際溫度

5.3

25.3

45.3

65.3

85.3

測量溫度

5.33

25.16

45.08

64.99

84.94

實際濕度

10

30

50

70

90

測量濕度

9.97

29.82

49.56

69.85

89.60

              可以看出,本文所設計的溫濕度檢測儀表具有較好的快速性和準確性,溫度測量精度高達0.5%,濕度測量精度高達1%。滿足性能指標。


6.2 PCB效果圖

              本文所設計的溫濕度檢測儀表的控制系統如圖6-3所示,3D效果圖如圖6-4所示。

圖6-3 PCB設計圖


圖6-4 PCB 3D效果圖

單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <lcd1602.h>
  4. #include <math.h>
  5. #include "stdio.h"
  6. #include "2543.h"
  7. //#include "rtx51tny.h"


  8. /************************************************
  9.       變量/常量聲明
  10. ***************************************************/
  11. unsigned char Num[6]={0x00,0x00,0x00,0x00,0x00,0x00}; //數值顯示緩沖區
  12. unsigned int date0=0,date1=0; //AD值(0-255)
  13. unsigned int MID;        //中間變量(勿刪)
  14. double Temp,Hemi;        //溫度值,濕度值。
  15. double RES,CAP;        //溫度值,濕度值。
  16. unsigned char pencil;
  17. unsigned char rubber;

  18. /************************************************
  19.       子函數聲明
  20. ***************************************************/
  21. void convert(unsigned char a,unsigned char b);        //ADC寄存器轉數組
  22. void display(void);        //顯示電壓數值
  23. void process(void);        //數據處理(電壓轉溫度,濕度)
  24. void ShowNum(void);        //顯示數據(顯示溫度值,濕度)
  25. void ShowPhy(void);


  26. //////
  27. //串口函數
  28. uchar flag = 0;
  29. uchar index = 0;
  30. //uchar data c[2];
  31. void Delay_ms(uint n)
  32. {
  33.                 uchar i;
  34.                 while(n--)
  35.                                 for(i = 0;i < 120;i++);
  36. }
  37. /*********************************************
  38. * 函數名         :UsartInit()
  39. * 函數功能                 :設置串口并初始化*/
  40. void UsartInit()
  41. {
  42.                 SCON=0x50;        //串口模式1,允許接收
  43.                 TMOD=0x20;        //T1工作模式2
  44.                 TH1=0xFD;        //波特率9600
  45.                 TL1=TH1;
  46.                 PCON=0x00;        //波特率倍增
  47.                 EA = 1;                //開總中斷
  48.                 ES = 1;                //開串口中斷
  49.                 TR1=1;                //開定時器1中斷
  50. }
  51. /**********************************************
  52. * 函數名         :Send_string(uchar *c)
  53. * 函數功能                 :通過串口發送數據*/
  54. void Send_string(uchar c)
  55. {
  56. //                while(*c != '!')
  57. //                {        
  58. //                                SBUF=*c;
  59. //                                c++;
  60. //                                while(TI==0);
  61. //                                                TI=0;
  62. //                }
  63.                 SBUF=c;
  64.                 while(TI==0);
  65.                 TI=0;
  66. }


  67. /*******************************************************************************

  68. * 主函數         

  69. *******************************************************************************/
  70. void main()
  71. {
  72.                 UsartInit();        //串口初始化
  73.                 init_lcd1602();//液晶1602顯示初始化
  74.                 Welcome();
  75.                 pencil=0;
  76.                 Delay_ms(200);
  77.                 Delay_ms(200);

  78.                 write_cmd(0x01);  //清屏
  79.                 while(1)
  80.                 {
  81.                                 date0=A_D(0);
  82.                                 date1=A_D(1);
  83.                                 
  84.                                 process();
  85.                                 if(pencil == 0) pencil=1;
  86.                                 else
  87.                                 {
  88.                                                 ShowPhy();        //顯示電阻、電容
  89.                                                 ShowNum();        //顯示溫度、濕度
  90.                                 }
  91.                 }
  92. }

  93. /***********************************************
  94. 數據處理程序
  95. 功能:將電壓值(0-5V)轉換成溫度值(-40.0-250.0)和濕度值(0.0-100.0)
  96. ***********************************************/
  97. void process(void)
  98. {            
  99.                 RES = 409500.0/date0-100;
  100.         
  101.                 CAP = 635071.5/date1;                                                                //775.4230771397/V   =   635071.50017744/D
  102.                 rubber = ((uchar)CAP%100)/10;
  103.                 if(rubber==6) CAP=0.994*CAP;
  104.                 else if(rubber==7) CAP=0.993*CAP;
  105.                 else if(rubber==8) CAP=0.992*CAP;
  106.                 else if(rubber==9) CAP=0.991*CAP;
  107.                 else ;
  108.                 Hemi= (CAP-163.3)/0.34;

  109.                 Temp= 1.0/((log(RES/100)/3950)+0.003354)-273.15;        //1/(273.15+25)=0.0033540164
  110.                

  111. }





  112. /*****************************************
  113. 顯示傳感數值函數
  114. *****************************************/
  115. void ShowPhy(void)
  116. {
  117.                 unsigned char i;        //顯示器指針用

  118.                 MID = (unsigned int)(RES * 100);
  119.                 Num[0]=MID/10000;
  120.                 Num[1]=(MID%10000)/1000;
  121.                 Num[2]=(MID%1000)/100;
  122.                 Num[4]=(MID%100)/10;
  123.                 Num[5]=MID%10;
  124.                 write_cmd(0x80);        //指針設置到第二行
  125.                 for(i=0;i<6;i++)
  126.                 {
  127.                                 if(i==3)
  128.                                 {
  129.                                                 write_date(0x2e);
  130.                                                 Send_string('.');
  131.                                 }
  132.                                 else
  133.                                 {
  134.                                                 write_date(0x30+Num[i]);        //0x30是48。
  135.                                                 Send_string(0x30+Num[i]);
  136.                                 }
  137.                                 delay(5);
  138.                 }
  139.                 write_date('K');
  140.                 Send_string('K');
  141.                 Send_string(0x20);

  142.                 //設置第二個數值
  143.                 MID = (unsigned int)(CAP * 100);
  144.                 Num[0]=MID/10000;
  145.                 Num[1]=(MID%10000)/1000;
  146.                 Num[2]=(MID%1000)/100;
  147.                 Num[4]=(MID%100)/10;
  148.                 Num[5]=MID%10;
  149.                 write_cmd(0x80+8);        //指針設置到第二行中間
  150.                 for(i=0;i<6;i++)
  151.                 {
  152.                                 if(i==3)
  153.                                 {
  154.                                                 write_date(0x2e);
  155.                                                 Send_string('.');
  156.                                 }
  157.                                 else
  158.                                 {
  159.                                                 write_date(0x30+Num[i]);        //0x30是48。
  160.                                                 Send_string(0x30+Num[i]);
  161.                                 }
  162.                                 delay(5);
  163.                 }
  164.                 write_date('p');
  165.                 write_date('F');
  166.                 Send_string('p');
  167.                 Send_string('F');
  168.                 Send_string(0x20);
  169. }

  170. /*****************************************
  171. 顯示處理數值函數
  172. *****************************************/
  173. void ShowNum(void)
  174. {
  175.                 unsigned char i;        //顯示器指針用
  176.                
  177.                 MID = (unsigned int)(Temp * 100);
  178.                 Num[0]=MID/10000;
  179.                 Num[1]=(MID%10000)/1000;
  180.                 Num[2]=(MID%1000)/100;
  181.                 Num[4]=(MID%100)/10;
  182.                 Num[5]=MID%10;
  183.                 write_cmd(0x80+0x40);        //指針設置到第二行
  184.                 for(i=0;i<6;i++)
  185.                 {
  186.                                 if(i==3)
  187.                                 {
  188.                                                 write_date(0x2e);
  189.                                                 Send_string('.');
  190.                                 }
  191.                                 else
  192.                                 {
  193.                                                 write_date(0x30+Num[i]);        //0x30是48。
  194.                                                 Send_string(0x30+Num[i]);
  195.                                 }
  196.                                 delay(5);
  197.                 }
  198.                 write_date('C');  //最后一位后顯示字符'C'
  199.                 Send_string('C');
  200.                 Send_string(0x20);
  201.                
  202.                 //設置第二個數值
  203.                 MID = (unsigned int)(Hemi * 100);
  204.                 Num[0]=MID/10000;
  205.                 Num[1]=(MID%10000)/1000;
  206.                 Num[2]=(MID%1000)/100;
  207.                 Num[4]=(MID%100)/10;
  208.                 Num[5]=MID%10;
  209.                 write_cmd(0x80+0x40+8);        //指針設置到第二行中間
  210.                 for(i=0;i<6;i++)
  211.                 {
  212.                                 if(i==3)
  213.                                 {
  214.                                                 write_date(0x2e);
  215.                                                 Send_string('.');
  216.                                 }
  217.                                 else
  218.                                 {
  219.                                                 write_date(0x30+Num[i]);        //0x30是48。
  220.                                                 Send_string(0x30+Num[i]);
  221.                                 }
  222.                                 delay(5);
  223.                 }
  224.                 write_date('R');  //最后一位后顯示字符'Rh'
  225.                 write_date('h');  //
  226.                 Send_string('R');
  227.                 Send_string('h');
  228.                 Send_string(0x20);
  229.                 Send_string(0x20);
  230. }


  231. //串口接收中斷函數
  232. //void Serial_INT() interrupt 4
  233. //{
  234. // if(RI==0) return;
  235. // ES=0;        //關閉串口中斷
  236. // RI=0;        //清接收中斷標志
  237. // c[index++]=SBUF;
  238. //    if(SBUF == '!')
  239. //   flag = 1;
  240. // ES=1;
  241. //}


  242. ///************************************************
  243. //      job0函數
  244. //***************************************************/
  245. //void job0(void) _task_ 0
  246. //{
  247. //                UsartInit();        //串口初始化
  248. //                init_lcd1602();//液晶1602顯示初始化
  249. //                os_create_task(1);
  250. //                os_create_task(2);
  251. //                os_create_task(3);
  252. //                os_delete_task(0);
  253. //}
  254. //void job1(void) _task_ 1
  255. //{
  256. //                while(1)
  257. //                {
  258. //                                date0=A_D(0);
  259. //                                date1=A_D(1);
  260. //                }
  261. //}
  262. //void job2(void) _task_ 2
  263. //{
  264. //                while(1)
  265. //                {
  266. //                                process();
  267. //                }
  268. //        
  269. //}

  270. ///************************************************
  271. //      job3函數  Show
  272. //***************************************************/
  273. //void job3(void) _task_ 3
  274. //{
  275. ////                while(1)
  276. ////                {
  277. //                                ShowNum();        //顯示溫度、濕度
  278. //                                ShowPhy();        //顯示電阻、電容
  279. ////                }
  280. //        
  281. //}

  282. ……………………

  283. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

0.png

仿真原理圖和Keil程序下載:
溫濕度計.zip (1.62 MB, 下載次數: 162)

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:42615 發表于 2022-2-17 10:40 | 顯示全部樓層
好文章,
回復

使用道具 舉報

ID:793344 發表于 2022-2-28 10:18 | 顯示全部樓層
誰能用RTX51 OS重寫一下代碼嗎?,樓主的代碼是常規的順序執行
回復

使用道具 舉報

ID:730009 發表于 2022-3-26 18:11 | 顯示全部樓層
他把rtx51tny.h注釋掉了
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费观看色 | 欧产日产国产精品国产 | 欧美99 | 九九热热九九 | aa级毛片毛片免费观看久 | 亚州精品成人 | 皇色视频在线 | 有码一区 | 精品成人69xx.xyz | 日韩欧美国产精品一区二区三区 | 伊人99| 午夜精品久久久久久久久久久久 | 日本视频在线播放 | 久久久av| 91久色| 日韩精品视频一区二区三区 | 青草久久免费视频 | zzzwww在线看片免费 | 伊人网伊人网 | caoporon| 欧美国产日韩在线观看 | a免费视频| 中文字幕国产精品视频 | 国产999精品久久久影片官网 | 中文字幕精品一区久久久久 | 欧美久久久久久久久 | 91精品国产91久久久久久吃药 | 亚洲精品一二三区 | 国产精品久久 | 欧美精品一区二区三区在线 | 午夜电影在线播放 | 中文日韩在线视频 | 日日操日日舔 | www.99热这里只有精品 | 亚洲成人网在线 | 亚洲美女天堂网 | 一本在线 | 在线视频国产一区 | 欧美一区2区三区3区公司 | 国产特级毛片 | 狠狠躁18三区二区一区 |