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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 24551|回復: 8
打印 上一主題 下一主題
收起左側

基于單片機空氣質量檢測儀畢業設計論文下載 含源碼 原理圖等

  [復制鏈接]
跳轉到指定樓層
樓主
完整的論文及源碼下載(word格式可編輯):
基于單片機空氣質量檢測儀設計.doc (3.94 MB, 下載次數: 382)


下面是論文的部分內容預覽:


圖4-1 硬件實物圖


基于單片機空氣質量檢測儀設計

摘  要

隨著我國經濟的發展,人民生活水平的提高,人們對環境問題及健康問題日益重視,室內空氣品質(IAQ)狀況受到越來越多的關注。人的一生中有三分之二的時間是在居室內度過的。本文研究的室內便攜式智能空氣品質監測儀是以室內空氣中有毒有害氣體的監測監控為背景,是以STC工公司的一款8位超低功耗單片機STC90C51為控制核心,能夠實現對室內溫度,濕度,VOC氣體的實時采集處理、顯示、報警等功能。儀器采用鋰電池供電,具有良好的便攜性和通用性,并且使用LCD1602點陣式液晶屏顯示菜單,有良好的人機對話界面。同時設計了聲光報警系統,實現在參數超標時及時的報警。室內智能空氣品質監測儀體積小,功耗低,操作簡單,適合應用于家庭和社區的醫療健康保健,能夠實時知道室內空氣的質量。


目  錄

前  言
第1章              本課題的主要研究內容、方法及總體設計
§1.1 課題設計的內容
§1.2課題設計的方法
第2章 空氣質量檢測儀的硬件設計
§2.1 空氣質量檢測儀系統簡介
§2.1.1 系統硬件結構及原理
§2.2 STC90C51單片機簡介
§2.2.1STC90C51主要性能參數:
§2.2.2時鐘電路模塊
§2.2.3復位電路模塊
§2.3傳感器的選用
§2.3.1氣體傳感器
§2.3.2溫濕度傳感器
§2.4模數轉換電路設計
§2.5聲光報警電路設計
§2.6液晶顯示電路設計
§2.6.1LCD1602的基本參數及引腳功能
§2.6.2LCD1602的指令說明及時序
§2.6.31602LCD的RAM地址映射及標準字庫表
§2.6.4LCD1602的一般初始化過程
§2.7按鍵電路設計
§2.8電路電源設計
§2.9本章小結
第3章 空氣質量檢測儀的軟件設計
§3.1 系統軟件設計思路
§3.1.1 編程語言的選擇
§3.1.2 軟件功能需求
§3.2軟件模塊設計
§3.2.1主程序模塊
§3.2.2AD轉換模塊
§3.2.3液晶顯示模塊
§3.2.4聲光報警模塊
§3.2.5按鍵模塊
§3.3本章小結
第4章 仿真調試
§4.1系統硬件調試
§4.1.1 常見的硬件故障
§4.1.2硬件調試方法
§4.2 系統軟件調試
§4.3本章小結
結  論            
§1主要結論
§2展望
參考文獻
致 謝
附 錄
附錄一
附錄二




河南科技大學畢業設計(論文)
前  言

一、課題研究的目的及意義
空氣質量的好壞反映了空氣污染程度,它是依據空氣中污染物濃度的高低來判斷的。來自固定和流動污染源的人為污染物排放大小是影響空氣質量的最主要因素之一。空氣質量檢測種類包括裝修污染、辦公室內空氣檢測、作業場所有害物質檢測、食堂油煙檢測、鍋爐大氣及工業窯爐檢測及工廠排放工業廢氣檢測。
當今,人類正面臨“煤煙污染”、“光化學煙霧污染”之后,又出現了“室內空氣污染”為主的第三次環境污染。美國專家檢測發現,在室內空氣中存在500多種揮發性有機物,其中致癌物質就有20多種,致病病毒200多種。危害較大的主要有:氡、甲醛、苯、氨以及酯、三氯乙烯等。大量觸目驚心的事實證實,室內空氣污染已成為危害人類健康的“隱形殺手”,也成為全世界各國共同關注的問題。據統計,全球近一半的人處于室內空氣污染中,室內環境污染已經引起35.7%的呼吸道疾病,22%的慢性肺病和15%的氣管炎、支氣管炎和肺癌。
本課題主要研究設計基于量化檢測的“空氣質量檢測儀”系統,此系統旨在實現室內空氣溫度、濕度、有害氣體的預警監測,有利于進行全方位的評價室內空氣質量,為人類營造一個健康的室內生存空間。空氣質量檢測儀體積小,功耗低,操作簡單,適合應用于家庭和社區的醫療健康保健,能夠實時知道室內空氣的質量。
二、國內外的研究狀況
氣體傳感器測定甲醛成為近年來甲醛檢測研究的新熱點。早在1983年,壓電類甲醛傳感器就已問世。這種傳感器可以不需要對樣品進行任何處理就可以測定,但易受水分子的影響而使晶體震動頻率發生漂移,故基本無實用性。為適應室內空氣甲醛現場快速檢測的要求,目前已開發出不少甲醛快速測定儀,這些儀器可直接在現場測定甲醛濃度,操作方便,適用于室內和公共場所空氣中甲醛濃度的現場測定,也適用于環境測試艙法測定木質板材中的甲醛釋放量。但這些儀器的工作原理、響應性能、適應范圍等都不同。
在測試甲醛、苯等害氣體方面,國外比較出名的有:美國ESC公司生產的Z一300甲醛檢測儀、英國PPM公司生產的PPM-400甲醛檢測儀;國內的有:江蘇安普電子工程有限公司生產的400型甲醛分析儀、北京賓達綠創科技有限公司生產的甲醛測定儀抑一308等。
這些儀器可實現對有害氣體的檢測功能,適用于專業檢測機構或實驗研究機構。準確測定甲醛、苯、氨等有害氣體的設備昂貴(如英國PPM公司生產的PPM400甲醛儀約兩萬多元),測定時間較長,每隔一段時間就需進行重新標定,需要專業人員進行操作,很難連續測定;目前國內外產品的設計差異主要集中在監測傳感器和控制單片機芯片的選用,操作方面國外的產品操作界面方便,功能加完備。



  •          本課題的主要研究內容、方法及總體設計


§1.1 課題設計的內容

以單片機為核心,選擇合適的傳感器,實現對空氣質量的檢測。

§1.2課題設計的方法

查閱相關資料,應用電腦軟件進行仿真、調試,制作硬件設備,在實際環境中測試并進行修改、調試,直至達到課題要求。

§1.3總體方案設計
本設計集VOC氣體及溫濕度監測,顯示與報警于一體,利用MCU進行數據采集保證了前臺數據的及時、準確,有利于進行全方位的評價。儀器采用鋰電池供電,具有良好的便攜性和通用性,并且使用LCD點陣式液晶屏顯示菜單,有良好的人機對話界面。
§1.3.1系統框圖


圖1-1 系統總框圖
§1.3.2功能設定
  • 顯示部分采用LCD1602顯示屏,循環顯示各項測量的上下限及實際濃度、實際溫度、濕度。并在按鍵選擇情況下連續顯示一個測量值的變化。
  • 當有害氣體濃度超出安全范圍時進行聲光報警。
  • 按鍵操作可進行測量范圍的調整,及手動和自動測量的轉換。


第2章 空氣質量檢測儀的硬件設計


§2.1 空氣質量檢測儀系統簡介

基于STC90C51的室內便攜式智能空氣質量監測儀是以室內空氣中有毒有害氣體的監測監控為背景,能夠實現對室內溫度,濕度,VOC氣體的實時采集處理、顯示、報警等功能。儀器采用鋰電池供電,具有良好的便攜性和通用性,并且使用LCD點陣式液晶屏顯示菜單,有良好的人機對話界面。同時設計了聲光報警系統,實現在參數超標時及時的報警。室內智能空氣品質監測儀體積小,功耗低,操作簡單,適合應用于家庭和社區的醫療健康保健,能夠實時知道室內空氣的質量。
§2.1.1 系統硬件結構及原理
本文研究的室內便攜式智能空氣品質監測儀是以STC工公司的一款8位超低功耗單片機STC90C51為控制核心。室內空氣中有害氣體通過傳感器輸出一個與氣體濃度相對應的電壓信號,該信號經過A/D轉換電路按一定得采樣頻率將模擬信號轉換為數字信號送入單片機進行數據采集以便進行顯示處理,溫濕傳感器直接與單片機相連。單片機對采樣值進行數字處理后驅動液晶顯示器分別顯示出被測室內空氣中的VOC氣體濃度值及溫濕度。若被測室內空氣中VOC氣體的濃度有超過國家標準或設定的危險值或溫濕度超出設定范圍時報警電路對應的發出聲光報警信號。

§2.2 STC90C51單片機簡介

隨著計算機技術的發展,單片機因具有集成度高、體積小、速度快、價格低等特點而在許多領域如過程控制、數據采集、機電一體化、智能化儀表、家用電器以及網絡技術等方面得到廣泛應用,從而使這些領域的技術水平、自動化程度大大提高。根據上述幾方面及本課題的實際情況,單片機型號的選擇主要從以下兩點考慮:
一是要有較強的抗干擾能力。由于一般室內電子電器產品比較多,這對單片機的干擾較大,所以應采用抗干擾性能較好的單片機機型。
二是要有較高的性價比。由于高度的通用性和出色的穩定性,本系統采用宏晶公司產的低功耗,高性能CMOS 8位單片機的STC90C51作為控制器。片內含4k bytes的可系統編程的Flash只讀程序存儲器,器件采用ATMEL公司的高密度、非易失性存儲技術生產,兼容標準8051指令系統及引腳。它集Flash程序存儲器既可在線編程(ISP)也可用傳統方法進行編程及通用8位微處理器于單片芯片中,可提供許多高性價比的應用場合,可靈活應用于各種控制領域。
§2.2.1STC90C51主要性能參數:







    • MCS.51產品指令系統完全兼容
    • 4k字節在系統編程(ISP)Flash閃速存儲器
    • 1000次擦寫周期
    • 4.0-5.5V的工作電壓范圍
    • 全境態工作模式:0Hz-33MHz
    • 三級程序加密鎖
    • 128×8字節內部RAM
    • 32個可編程IO口線
    • 216位定時器計數器
10、6個中斷源
11、全雙工串行UART通道
12、低功耗空閑和掉電模式
13、中斷可從空閑模喚醒系統
14、看門狗(wDT)及雙數據指針
15、掉電標識和快速編程特性
16、靈活的在線系統編程
STC90C51芯片管腳如圖2-1。
   
圖2-1 STC90C51引腳布置
§2.2.2時鐘電路模塊
時鐘電路由一個晶體振蕩器12MHZ和兩個30pF的瓷片電容組成。時鐘電路用于產生單片機工作所需要的時鐘信號,而時序所研究的是指令執行中各信號之間的相互關系。單片機本身就如一個復雜的同步時序電路,為了保證同步工作方式的實現,電路應在唯一的時鐘信號控制下嚴格地工作。其電路如圖2-2所示:
圖2-2 時鐘電路模塊
§2.2.3復位電路模塊
復位電路是使單片機的CPU或系統中的其他部件處于某一確定的初始狀態,并從這狀態開始工作,除了進入系統的正常初始化之外,當由于程序運行出錯或操作錯誤使系統處于死鎖狀態時,為擺脫困境,也需按復位電路以重新啟動。本設計采用的是按鍵復位電路。其電路如圖2-3所示:
圖2-3 復位電路模塊

§2.3傳感器的選用

§2.3.1氣體傳感器
1.氣體傳感器基礎知識
按照氣敏特性來分,氣體傳感器主要分為:半導體型、電化學型、固體電解質型、接觸燃燒型、光化學型等氣體傳感器,又以前兩種最為普遍。
    (1)半導體型氣體傳感器的優缺點
半導體氣體傳感器具有成本低廉、制造簡單、靈敏度高、響應速度快、壽命長、對濕度敏感低和電路簡單等優點。不足之處是必須在高溫下工作、對氣體或氣味的選擇性差、元件參數分散、穩定性不理想、功率高等方面。
(2)半導體傳感器需要加熱的原因
半導體傳感器是利用一種金屬氧化物薄膜制成的阻抗器件,其電阻隨著氣體含量不同而變化。氣體分子在薄膜表面進行還原反應以引起傳感器電導率的變化。為了消除氣體分子達到初始狀態就必須發生一次氧化反應。傳感器內的加熱器可以加速氧化過程,這也是為什么有些低端傳感器總是不穩定,其原因就是沒有加熱或加熱電壓過低導致溫度太低反應不充分。
(3)電化學氣體傳感器的工作原理
電化學氣體傳感器是通過監測電流來監測氣體的濃度,分為不需供電的原電池式以及需要供電的可控電位電解式,目前可以監測許多有毒氣體和氧氣,后者還能監測血液中的氧濃度。電化學傳感器的主要優點是氣體的高靈敏度以及良好的選擇性。不足之處是有壽命的限制一般為兩年。
(4)半導體傳感器和電化學傳感器的區別
半導體傳感器因其簡單低價已經得到廣泛應用,但是又因為它的選擇性差和穩定性不理想目前還只是在民用級別使用。而電化學傳感器因其良好的選擇性和高靈敏度被廣泛應用在幾乎所有工業場合。
(5)固態電解質氣體傳感器
顧名思義,固態電解質就是以固體離子導電為電解質的化學電池。它介于半導體和電化學之間。選擇性,靈敏度高于半導體而壽命又長于電化學,所以也得到了很多的應用,不足之處就是響應時間過長。
(6)接觸燃燒式氣體傳感器
接觸燃燒式氣體傳感器只能測量可燃氣體。又分為直接接觸燃燒式和催化接觸燃燒式,原理是氣敏材料在通電狀態下,可燃氣體在表面或者在催化劑作用下燃燒,由于燃燒使氣敏材料溫度升高從而電阻發生變化。后者因為催化劑的關系具有廣普特性應用更廣。
(7)光學式氣體傳感器
光學式氣體傳感器主要包括紅外吸收型、光譜吸收型、熒光型等等,主要以紅外吸收型為主。由于不同氣體對紅外波吸收程度不同,通過測量紅外吸收波長來監測氣體。目前因為它的結構關系一般造價頗高。基于本文的實時要求和性價比等方面的原因,本系統選用電化學傳感器中的定電位電解式氣體傳感器。
本設計針對VOC氣體選用能夠偵測0.1ppm以上的氣體的空氣質量VOC氣體濃度傳感器MS1100用于檢測空氣中的甲醛、苯、二甲苯等檢測空氣中的甲醛、苯、二甲苯等多種有機揮發成分,具有極高的靈敏度和穩定性,體積小巧。實物如圖2-4,使用時的連接電路如圖2-5。
      
   圖2-4 VOC傳感器實物圖      圖2-5 VOC傳感器接線圖
§2.3.2溫濕度傳感器
溫濕度傳感器是指能將溫度量和濕度量轉換成容易被測量處理的電信號的設備或裝置。溫濕度傳感器一般是測量溫度量和相對濕度量。
鑒于測量溫濕度的范圍不大,精度要求不高故采用數字溫濕度傳感器DHT11。實物如圖2-6。
圖2-6 DHT11實物圖
具有的特性:相對濕度和溫度測量、全部校準,數字輸出、卓越的長期穩定性、無需額外部件、超長的信號傳輸距離、超低能耗、4引腳安裝、完全互換。
DHT11產品概述
DHT11數字溫濕度傳感器是一款含有已校準數字信號輸出的溫濕度復合傳感器。它應用專用的數字模塊采集技術和溫濕度傳感技術,確保產品具有極高的可靠性與卓越的長期穩定性。傳感器包括一個電阻式感濕元件和一個NTC測溫元件,并與一個高性能8位單片機相連接。因此該產品具有品質卓越、超快響應、抗干擾能力強、性價比極高等優點。每個DHT11傳感器都在極為精確的濕度校驗室中進行校準。校準系數以程序的形式儲存在OTP內存中,傳感器內部在檢測信號的處理過程中要調用這些校準系數。單線制串行接口,使系統集成變得簡易快捷。超小的體積、極低的功耗,信號傳輸距離可達20米以上,使其成為各類應用甚至最為苛刻的應用場合的最佳選則。產品為4針單排引腳封裝。連接方便,特殊封裝形式可根據用戶需求而提供。
應用領域:
暖通空調、測試及檢測設備、汽車、數據記錄器、消費品、自動控制、氣象站、家電、濕度調節器、醫療、除濕器。
傳感器信息見表2-1。
表2-1 DHT11傳感器信息
型號
測量范圍
測濕精度
測溫精度
分辨力
封裝
DHT11
20-90%RH 0-50℃
±5%RH
±2℃
1
4針單排直插

  • 傳感器性能說明見表2-2
表2-2 傳感器性能說明
參數
條件
Min
Typ
Max
單位
濕度
分辨率


1
1
1
%RH


16


Bit
重復性




±1


%RH
精度
25℃


±4


%RH
0-50℃




±5
%RH
互換性
可完全互換
量程范圍
0℃
30


90
%RH
25℃
20


90
%RH
50℃
20


80
%RH
響應時間
1/e(63%)25℃,1m/s空氣
6
10
15
S
遲滯




±1


%RH
長期穩定性
典型值


±1


%RH/yr
溫度
分辨率



1
1
1
16
16
16
Bit
重復性




±1


精度


±1


±2
量程范圍


0


50
響應時間
1/e(63%)
6


30
S

2、 接口說明  
建議連接線長度短于20米時用5K上拉電阻,大于20米時根據實際情況使用合適的上拉電阻接線方式如圖2-7。
圖2-7 典型接線電路
3、電源引腳
DHT11的供電電壓為              3-5.5V。傳感器上電后,要等待 1s 以越過不穩定狀態在此期間無需發送任何指令。電源引腳(VDD,GND)之間可增加一個100nF 的電容,用以去耦濾波。
4、串行接口  (單線雙向)
DATA 用于微處理器與 DHT11之間的通訊和同步,采用單總線數據格式,一次通訊時間4ms左右,數據分小數部分和整數部分,具體格式在下面說明,當前小數部分用于以后擴展,現讀出為零.操作流程如下:
一次完整的數據傳輸為40bit,高位先出。
數據格式:8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據+8bit校驗和
數據傳送正確時校驗和數據等于“8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據”所得結果的末8位。
用戶MCU發送一次開始信號后,DHT11從低功耗模式轉換到高速模式,等待主機開始信號結束后,DHT11發送響應信號,送出40bit的數據,并觸發一次信號采集,用戶可選擇讀取部分數據。從模式下,DHT11接收到開始信號觸發一次溫濕度采集,如果沒有接收到主機發送開始信號,DHT11不會主動進行溫濕度采集,采集數據后轉換到低速模式。
(1).通訊過程如圖2-8所示
圖2-8 通訊過程
操作時序如圖2-9,總線空閑狀態為高電平,主機把總線拉低等待DHT11響應,主機把總線拉低必須大于18毫秒,保證DHT11能檢測到起始信號。DHT11接收到主機的開始信號后,等待主機開始信號結束,然后發送80us低電平響應信號。主機發送開始信號結束后,延時等待20-40us后,讀取DHT11的響應信號,主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可,總線由上拉電阻拉高。
圖2-9 操作時序
總線為低電平,說明DHT11發送響應信號,DHT11發送響應信號后,再把總線拉高80us,準備發送數據,每一bit數據都以50us低電平時隙開始,高電平的長短定了數據位是0還是1。格式見下面圖示,如果讀取響應信號為高電平,則DHT11沒有響應,請檢查線路是否連接正常。當最后一bit數據傳送完畢后,DHT11拉低總線50us,隨后總線由上拉電阻拉高進入空閑狀態。            
數字0信號表示方法如圖2-10所示
圖2-10 數字0信號表示方法
數字1信號表示方法如圖2-11所示
圖2-11 數字1信號表示方法
5、測量分辨率
測量分辨率分別為 8bit(溫度)、8bit(濕度)。
6、電氣特性如表2-3
表2-3 電氣特性
參數
條件
min
typ
max
單位
供電
DC
3
5
5.5
V

供電電流

測量
0.5


2.5
mA
平均
0.2


1
mA
待機
100


150
uA
采樣周期
1





注:采樣周期間隔不得低于1秒鐘。
7、應用信息
7.1工作與貯存條件
超出建議的工作范圍可能導致高達3%RH的臨時性漂移信號。返回正常工作條后,傳感器會緩慢地向校準狀態恢復。要加速恢復進程/可參閱7.3小節的“恢復處理”。在非正常工作條件下長時間使用會加速產品的老化過程。
7.2暴露在化學物質中
電阻式濕度傳感器的感應層會受到化學蒸汽的干擾,化學物質在感應層中的擴散可能導致測量值漂移和靈敏度下降。在一個純凈的環境中,污染物質會緩慢地釋放出去。下文所述的恢復處理將加速實現這一過程。高濃度的化學污染會導致傳感器感應層的徹底損壞。
7.3恢復處理
置于極限工作條件下或化學蒸汽中的傳感器,通過如下處理程序,可使其恢復到校準時的狀態。在50-60℃和< 10%RH的濕度條件下保持2小時(烘干);隨后在20-30℃和>70%RH的濕度條件下保持5小時以上。
7.4溫度影響
氣體的相對濕度,在很大程度上依賴于溫度。因此在測量濕度時,應盡可能保證濕度傳感器在同一溫度下工作。如果與釋放熱量的電子元件共用一個印刷線路板,在安裝時應盡可能將DHT11遠離電子元件,并安裝在熱源下方,同時保持外殼的良好通風。為降低熱傳導,DHT11與印刷電路板其它部分的銅鍍層應盡可能最小,并在兩者之間留出一道縫隙。
7.5光線
長時間暴露在太陽光下或強烈的紫外線輻射中,會使性能降低。
7.6配線注意事項
DATA信號線材質量會影響通訊距離和通訊質量,推薦使用高質量屏蔽線。
8、封裝信息如圖2-12,
圖2-12 DHT11封裝圖
  • DHT11引腳說明見表2-4


表2-4 引腳說明
Pin
名稱
注釋
1
VDD
供電 3-5.5VDC
2
DATA
串行數據,單總線
3
NC
空腳,請懸空
4
GND
接地,電源負極

本設計采用的為DHT11模塊,原理圖為圖2-13:
圖2-13 DHT11模塊接線圖

§2.4模數轉換電路設計

氣體傳感器出來的信號是模擬信號,而微處理器STC90C51只能處理數字信號,故需要對模擬信號信號進行轉換,將其轉換為處理器能識別的數字信號,由于測試電路出來的模擬電壓變化范圍在0~5V,故選擇性價比比較合適的ADC0809進行模數轉換。其管腳定義如圖2-14所示。
圖2-14 ADC0809管腳示意圖
ADC0809各腳功能如表2-5:
表2-5 ADC0809各腳功能
引腳
功能介紹
D7-D0
IN0-IN7
8位數字量輸出引腳
8位模擬量輸入引腳
VCC
+5V工作電壓
REF(+)
參考電壓正端
REF(-)
參考電壓負端
START
A/D轉換啟動信號輸入端
ALE
地址鎖存允許信號輸入端
EOC
轉換結束信號輸出引腳,開始轉換時為低電平,當轉換結束時為高電平
OE
輸出允許控制端,用以打開三態數據輸出鎖存器。
CLK
時鐘信號輸入端(一般為500KHz)。
A、B、C
地址輸入線
ADC0809對輸入模擬量要求:信號單極性,電壓范圍是0-5V,若信號太小,必須進行放大;輸入的模擬量在轉換過程中應該保持不變,如若模擬量變化太快,則需在輸入前增加采樣保持電路。ADC0809的時序接口為51系列單片機的標準總線接口,操作方便,如同對存儲器或I/O操作一樣,A/D轉換精度為8比特,滿足本課題要求。輸入的模擬電壓為0~5V,一次A/D轉換時間為100μS。
ADC0809與單片機及VOC傳感器的接線方式如圖2-15:
圖2-15 ADC0809接線原理圖

§2.5聲光報警電路設計

為了使本系統對室內空氣品質的監測更為直觀,采用了如圖2-16由2個發光二極管和一個蜂鳴器構成的聲光報警電路。其中VOC氣體含量超標時雙燈閃爍蜂鳴器報警,溫度超標時D1燈亮蜂鳴器報警,濕度超標時D2燈亮蜂鳴器報警。
圖2-16 聲光報警電路

§2.6液晶顯示電路設計

本課題所要顯示的數據一共有6個,分別是有毒氣體的濃度和室內的溫度、濕度的范圍和測量值,故選用2行16個字符的LCD1602作為顯示模塊,滿足顯示要求。液晶顯示模塊具有體積小、功耗低、顯示內容豐富等特點,現在字符型液晶顯示模塊已經是單片機應用設計中最常用的信息顯示器件了。
    字符型液晶顯示模塊是一種專門用于顯示字母、數字、符號等點陣式LCD,目前常用16*1,16*2,20*2和40*2行等的模塊。下面以長沙太陽人電子有限公司的1602字符型液晶顯示器為例,介紹其用法。一般1602字符型液晶顯示器實物如圖2-17:
圖2-17 1602字符型液晶顯示器實物圖
§2.6.1LCD1602的基本參數及引腳功能
1602LCD分為帶背光和不帶背光兩種,基控制器大部分為HD44780,帶背光的比不帶背光的厚,是否帶背光在應用中并無差別,兩者尺寸差別如下圖2-18所示:
圖2-18 1602LCD尺寸圖
1602LCD主要技術參數:
顯示容量:16x2個字符芯片
工作電壓:4.5V—5.5V
工作電流:2.0Ma(5V)
模塊兒最佳工作電壓:5.0V
字符尺寸:2.95×4.35(W×H)mm
引腳功能說明:
1602LCD采用標準的14腳(無背光)或16腳(有背光)接口,各引腳說明如表2-6所示:
表2-6  1602引腳說明
編號
符號
引腳說明
編號
符號
引腳說明
1
VSS
電源地
9
D2
數據
2
VDD
電源正極
10
D3
數據
3
VL
液晶顯示偏壓
11
D4
數據
4
RS
數據/命令選擇
12
D5
數據
5
R/W
讀/寫選擇
13
D6
數據
6
E
使能信號
14
D7
數據
7
D0
數據
15
BLA
背光源正極
8
D1
數據
16
BLK
背光源負極

第1腳:VSS為地電源。
第2腳:VDD接+5V正電源。
第3腳:VL為液晶顯示器對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。
第4腳:PS為寄存器選擇,高電平時選擇數據寄存器、低電平時選擇指令寄存器。
第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入數據。
第6腳:E端為使能端,當E端由高電平跳變成低電平時,夜景模塊執行命令。
第7~14腳:D0~D7為八位雙向數據線。
第15腳:背光源正極。
第16腳:背光源負極。
§2.6.2LCD1602的指令說明及時序
1602液晶模塊內部的控制器共有11條控制指令,如表2-7所示:


表2-7 控制命令表
序號
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清顯示
0
0
0
0
0
0
0
0
0
1
2
光標返回
0
0
0
0
0
0
0
0
1
*
3
置輸入模式
0
0
0
0
0
0
0
1
I/D
S
4
顯示開/關控制
0
0
0
0
0
0
1
D
C
B
5
光標或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符發生存貯器地址
0
0
0
1
字符發生存貯器地址
8
置數據存貯器地址
0
0
1
顯示數據存貯器地址
9
讀忙標志或地址
0
1
BF
計數器地址
10
寫數到CGRAM或DDRAM
1
0
要寫的數據內容
11
從CGRAM或DDRAM讀數
1
1
讀出的數據內容

1602液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明:1為高電平、0為低電平)
指令1:清顯示,指令碼01H,光標復位到地址00H位置。
指令2:光標復位,光標返回到地址00H。
指令3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。
指令4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。
指令5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。
指令6:功能設置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。
指令7:字符發生器RAM地址設置。
指令8:DDRAM地址設置。
指令9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如果為低電平表示不忙。
指令10:寫數據。
指令11:讀數據。
與HD44780相兼容的芯片時序如表2-8:
表2-8 基本操作時序表
讀狀態
輸入
RS=L,R/W=H,E=H
輸出
D0—D7=狀態字
寫指令
輸入
RS=L,R/W=L,D0—D7=指令碼,E=高脈沖
輸出
讀數據
輸入
RS=H,R/W=H,E=H
輸出
D0—D7=數據
寫數據
輸入
RS=H,R/W=L,D0—D7=數據,E=高脈沖
輸出

讀寫操作時序如圖2-19和2-20所示:
圖2-19 讀操作時序
圖2-20 寫操作時序
§2.6.31602LCD的RAM地址映射及標準字庫表
液晶顯示模塊是一個慢顯示器件,所以在執行每條指令之前一定要確認模塊的忙標志為低電平,表示不忙,否則此指令失效。要顯示字符時要先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符,圖2-21是1602的內部顯示地址。
圖2-21 1602LCD內部顯示地址
第二行第一個字符的地址是40H,寫入顯示地址時要求最高位D7恒定為高電平1所以實際寫入的數據應該是:
01000000B(40H)+10000000B(80H)=11000000B(C0H)。
在對液晶模塊的初始化中要先設置其顯示模式,在液晶模塊顯示字符時光標是自動右移的,無需人工干預。每次輸入指令前都要判斷液晶模塊是否處于忙的狀態。
1602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼。
§2.6.4LCD1602的一般初始化過程
延時15mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
以后每次寫指令、讀/寫數據操作均需要檢測忙信號
寫指令38H:顯示模式設置
寫指令08H:顯示關閉
寫指令01H:顯示清屏
寫指令06H:顯示光標移動設置
寫指令0CH:顯示開及光標設置
LCD1602的具體接線路圖如圖2-22所示。
圖2-22 LCD1602接線電路圖


§2.7按鍵電路設計

考慮到整個測量系統中不同環境對氣體濃度及溫濕度范圍要求不同,故設置了按鍵功能,用于實現測量范圍的調整,參考單片機引腳使用情況,共設置五個獨立按鍵如圖2-23,實現功能為設定鍵可進行設定的進入與退出,同時可實現三種范圍的切換,另設左右移位鍵、上下調值鍵各兩個,與此同時考慮到用戶可能需要在一定時間內連續測量一種量,故設計了上調鍵的第二功能:當只有上調鍵按下時完成顯示的自動與手動的切換以實現良好的人機對話。
圖2-23 按鍵電路
§2.8電路電源設計

本設計采用集成穩壓器7805,C29、C30分別為輸入端和輸出端濾波電容,D1為續流二極管。當輸出電流較大時,7805應配上散熱板。電源電路如圖2-24所示:
圖2-24 電源電路

§2.9本章小結

本章首先介紹了便攜式室內空氣質量監測儀的硬件結構以及系統功能,該儀器以8位單片機STC90C51作為控制核心,設計并構建了系統的硬件平臺,完成了有毒氣體濃度信號的采集轉換電路、液晶顯示電路、聲光報警電路等的設計。該儀器能夠實現有毒氣體濃度信號和溫濕度信號采集與顯示及超標聲光報警等功能。本章重點介紹了信號采集模擬電路和以主控制器為中心的數字電路的設計與工作原理。首先討論了有毒氣體采集模塊中傳感器選擇問題,最后討論了系統的外圍接口電路模塊,包括液晶顯示,聲光報警等,實現了各外圍接口電路模塊與STC90C51的硬件接口設計。
這一章比較具體的說明了系統硬件設計的內容,通過模塊化的設計思想,把一個復雜的單片機系統按照功能劃分成一個個單獨的電路模型,分別進行設計,最后在集成到一起。這種方法對于設計復雜的單片機系統很有效。大大提高系統設計的效率與質量。(說明:系統硬件設計的電路原理圖附在論文的附錄里面。)


第3章 空氣質量檢測儀的軟件設計


§3.1 系統軟件設計思路

§3.1.1 編程語言的選擇
在系統硬件電路確定以后,其主要功能的實現將依賴于軟件來實現。對同一硬件電路,配以不同的軟件,它所實現的功能也就不同,其設計軟件基本要求:
1.可靠性。可靠性是軟件設計的重要指標,具有較強的抗干擾能力。
2.易理解性、易維護性。編制的軟件要求易閱讀,容易發現和糾正錯誤,容易修改和補充。
3.實時性。系統能夠及時響應外部事件的發生并能及時做出處理結果。
4.準確性。保證系統進行計算數據的精度。
目前存在有4種編程語言支持單片機,即匯編語言、PL/M51語言、C語言和BASI語言。其中匯編語言和C語言應用的較多,匯編語言的機器代碼生成效率高,控制性好,但就是移植性不高。結合本系統的特點,這里選用了功能強、效率高的C語言。C語言主要有以下特點:用C語言編制的程序效率高,占用存儲空間小,運行速度快。C語言能寫出最優化程序,且能反映出計算機的實際運行情況。C語言能直接與存儲器、接口電路打交道,也能申請中斷。具有良好的模塊化、容易閱讀、維護等優點,且編寫的模塊程序易于移植。基于C語言和匯編語言的優缺點,本系統采用C語言編寫方法。
§3.1.2 軟件功能需求
室內空氣質量檢測儀系統軟件主要由溫濕傳感器采集模塊、AD轉換模塊、人機接口模塊、聲光報警模塊、核心控制器模塊構成,各模塊功能概述如表3-1所示。


表3-1 各功能模塊功能描述
功能模塊
功能描述
溫濕傳感器采集模塊
對室內溫濕度測點進行實時監測
AD轉換模塊
1.完成信號采樣
2.完成與核心處理器間的數據傳輸
核心控制器模塊
1.系統時基分配
2.人機接口控制
3.各模塊協調工作
人機接口模塊
1.按鍵控制
2.動態信息顯示
根據軟件設計的基本要求,采取了如下的措施:
1.程序模塊化。軟件設計中包含有:主程序模塊、顯示模塊、DHT11傳感器檢測函數、A/D數據轉換子模塊、聲光報警模塊、數據轉換模塊、按鍵函數。
2.軟件設計采用C語言編程。
3.中斷響應外部事件,提高了系統的實時處理事件能力。
4.軟、硬件抗干擾。軟件抗干擾措施提高了系統的可靠性。
以下就對一些主要模塊進行詳細的闡述。

§3.2軟件模塊設計

§3.2.1主程序模塊
主程序運行流程圖如圖3-1所示。由主程序流程圖可以看出,軟件要實現的主要功能是實現對傳感器信號的數據采集,然后進行數據的計算、分析、送液晶進行顯示及報警功能。程序開始時,對系統進行初始化,包括單片機的各寄存器、RAM、定時器裝載初值、中斷設置及各模塊初始化等。完成初始化后,CPU等待傳感器傳入信號及AD轉換結束,從而完成當前監測參數的正確顯示。





圖3-1 主程序流程圖
§3.2.2AD轉換模塊
AD完成轉換需要一定的時間,AD應用中我們可以有兩種方法來:
1.中斷查詢法,AD完成模數轉換后會向中斷輸出端輸出一個中斷請求信號,告訴CPU轉換已經完成,CPU可以讀取數據。
2.延時等待法,設定一定的時間讓CPU處于等待狀態,此時間足夠AD完成轉換,過了等待時間CPU再去讀取數據。
綜合考慮各方面的因素,本研究采用第一種方法:延時等待法。所用的芯片為AD0809,根據所需的要求。
§3.2.3液晶顯示模塊
本設計所用的顯示器件為1602液晶面板,該液晶能顯示32個字符,滿足顯示要求。1602液晶與CPU是并口通信,由單片機的P2.5、P2.6、P2.7引腳來控制1602的讀寫數據命令功能,單片機P0口傳輸數據到1602進行顯示。
系統上電LCD初始化,液晶顯示首先需要要按照時序給定顯示地址,然后傳送數據。上電后液晶顯示開始循環顯示三個被測量的范圍和測量結果。
§3.2.4聲光報警模塊
聲音報警采用的是蜂鳴器,光報警是通過6個發光二極管來顯示,3個綠色和三個紅色的,當毒氣含量沒超標時顯示綠色,超標時顯示紅色并啟動蜂鳴器,報警子程序執行之前,設定的報警閾值存放在兩個變量中,傳感器輸入AD轉換值后,調用比較程序,小于閾值則執行顯示程序,若大于閾值進行聲光報警。。
§3.2.5按鍵模塊
本設計設定按鍵功能為調整測量數據的安全范圍并可進行手動和自動的切換考慮到實現按鍵功能所用按鍵數目不多及單片機引腳數量決定選用五個獨立式按鍵,其中設定鍵用于進入和退出上下限的調整,上下左右四個鍵在設定鍵被按下的情況下可以對數值進行調整;同時,當設定鍵未按下且上調鍵被按下時進入上調鍵的第二功能,實現用戶手動控制和自動控制的切換。已滿足用戶對環境條件檢測要求的不同,實現良好的人機交流。

§3.3本章小結

在這一章里對室內便攜式只能空氣品質監測儀的軟件設計進行了較詳細的介紹。軟件采用了模塊化設計的思路,以單片機高級語言C51編程。在本章開始給出了主程序結構流程圖,然后分別對各個子模塊的軟件流程進行介紹。(說明:程序見附錄二)

1


河南科技大學畢業設計(論文)


第4章 仿真調試


§4.1系統硬件調試

§4.1.1 常見的硬件故障
(1)邏輯錯誤:硬件的邏輯錯誤是由于設計錯誤和加工過程中的工藝性錯誤所造成的,主要包括:錯線、開路、短路等,其中短路最為常見,在印刷電路板布線密度高的情況下,極易因工藝原因造成短路。
(2)器件失效:元器件失效主要是因為器件本身已損壞或性能不符合要求,或者是由于組裝錯誤造成的元器件失效,如電解電容、二極管的極性錯誤,集成塊安裝方向錯誤等。
(3)可靠性差:系統不可靠可能受多種因素影響,如金屬化孔、接插件接觸不良會造成系統時好時壞;內部和外部的干擾、器件負載過大等造成邏輯電平不穩定;另外,走線和布局的不合理等也是系統可靠性差的重要因素之一。
(4)電源故障:若系統中存在電源故障,則加電后將造成器件損壞。
§4.1.2硬件調試方法
拿到印刷電路板后,用萬用表直接檢查線路板各處是否有明顯短路、斷路的地方,尤其是電源是否短路。接著,焊接各元器件及插座,在焊接過程中要對各元件做逐一檢查,比如二極管極性、電容容量及耐壓、電阻值大小等。在插座、元件焊接完畢后,仔細檢查元件面各元件之間裸露部分有無相互接觸現象,焊接面的各焊點間、焊點和近鄰線有無連接。最后,再給電路板空載上電(未插芯片),檢查線路板各管腳及插件上的電位是否正確,特別是單片機管腳上的各點電壓。若上述的一切都正常,則硬件調試的準備工作完成。
硬件實物如圖4-1。

§4.2 系統軟件調試

對系統軟件編寫完成之后,可以利用Keil C51仿真軟件進行仿真運行調試,其調試界面如圖4-2所示。
圖4-2 KeilC51軟件調試截面圖
在具體的調試過程中,采取以下方法進行調試:在Keil C51編譯環境中編寫、編譯軟件模塊,進行軟件仿真調試,對功能模塊的軟件仿真。通過Keil C51的調試窗口觀察各個寄存器、變量以及并行口輸出的結果,監測軟件模塊運行的狀態,在調試過程中不斷地調整修改系統的軟件程序,使系統實現預定功能。
調試過程中單步運行和斷點運行調試只能驗證程序正確與否,而不能確定定時精度、CPU的實時響應等問題,故在單步和斷點調試之后,又進行了連續調試。待全部完成后,應反復運行調試多次,對系統的穩定性和操作是否符合原始設計要求、安排的操作是否合理等都要進行詳細的觀察,必要時作適當的修正。
調試完成后將程序導入protues中進行仿真,觀察系統運行結果如圖4-3。通過調試,確定基本可行后,將程序燒寫單片機進行實物調整,通過不斷燒寫、試驗,最終完成整個軟件,準確實現要求的功能如圖4-4。


圖4-3 protues仿真調試


圖4-4 實物調試

§4.3本章小結

本章首先詳細描述用Keil C51對軟件進行調試的過程以及其方法,通過輸入不同的數據對系統進行調試,以確定本設計方案的正確性。本章工作內容使得硬件部分與軟件部分結合實現預定的功能。

結  論


§1主要結論

    1.本系統綜合利用傳感器技術,自動監測技術,和微控制器技術,開發了一套對室內的空氣質量進行監控的操作方便、簡潔實用的自動監測系統。
2.系統軟硬件設計合理,其中單片機軟件采用模塊化的程序設計方法,各模塊相互獨立,提高了系統的可靠性和可擴展性,整個系統具有較高的性能價格比。
3.系統C51語言編程,程序結構清晰,顯示板界面非常友好,使得操作者在使用該系統時就像是在操作一臺實際的控制儀器一樣。
4.系統功能獨立,配置合理。鍵盤設置為不同的用戶提供了一定的選擇空間。
5.經運行驗證,系統具有響應速度快,操作簡便,工作可靠等特點。

§2展望

1.本系統選用了集傳感器,轉換器于一體,能直接輸出標準模擬信號的傳感器,這無疑會增加系統的成本,今后可選用能達到要求的價格低廉的傳感器,而信號的放大和調理電路部分可自行設計。
2.由于室內各種環境因子相互影響,而本系統的控制輸出僅為簡單的百分比信號量,這顯然不能滿足高精度的控制要求,應引入模糊算法,專家系統等技術以進一步提高系統的智能決策水平。
3.系統可以開發成多機監控模式,這就能同時監測多個環境室內的空氣品質,通過串行通信傳到上位機進行綜合處理。
5.可通過網絡與其他家電相聯系,將把家庭中原來孤立、各不相關的設備統一起來。
6. 本設計可改為多路氣體檢測,未來可以實現更多的檢測功能。
7. 本設計的主要強調智能化和人性化,例如可以適用于特殊人群——病人,他們可以把舒適的環境的指標通過相應的按鍵來控制,按下按鍵后,通過本系統控制相應的設備調節來達到是以病人的環境。
8.可以用來開發新型空調,現代空調都是針對空氣溫濕進行調節,可以將本設計加入空調內部,使其既能控制溫濕度,還可以對空氣中的各種氣體進行檢測,并通過控制“新風系統”改善空氣各方面的質量。


參考文獻

[1] 余永權.單片機原理及應用[M].北京:電子工業出版社,1998.12
[2] 余錫存、曹國華.單片機原理及接口技術[M].第二版.西安:西安電子科技大學出版社,2007.12
[3] 諸邦田.電子電路實用抗干擾技術[M].北京:人民郵電出版社,1994.5
[4] 曲喜新.電子元件材料手冊[M].北京:電子工業出版社,1989.4
[5] 汪吉鵬、馬云峰.微機原理與接口技術[M].北京:高等教育出版社,2001.7
[6] 田崴.電工技術(電工學1)[M].北京:高等教育出版社,2010.12
[7] 孫立功.電子技術(電工學2)[M].北京:高等教育出版社,2010.12
[8] 馬玉春.串行通信協議的研究及應用[J].計算機應用研究.2004
[9] 胡漢才.單片機原理及其接口技術[M].清華大學出版社,1996.
[10] 樓然苗,李光飛.51系列單片機設計實例[M].北京航空航天大學出版社,2003.
[11] 趙亮,侯國銳.單片機C語言編程與實例[M].人民郵電出版社,2003.
[12] 張毅剛.單片機原理及應用[M].北京:高等教育出版社,2003.
[13] 何立民.單片機與嵌入式系統應用[M].北京航空航天出版社,2003.
[14]譚浩強.C程序設計(第三版)[M].清華大學出版社,2005.
[15]清源科技.Protel 99 SE電路原理圖與PCB設計及仿真[M].機械工業出版社,2007.


致 謝

為期兩個多月的畢業設計終于完成了,對我個人而言,凝聚了許多努力和汗水,也經受住了嚴峻的考驗。和普通的課程設計不同,由于畢業設計的綜合性,幾乎用到所學的全部知識,而且是我第一次接觸傳感器的使用,對我來說這是一個全新的任務。由于基礎過于薄弱,專業知識有限,浮躁的心理讓我一開始舉步維艱,滿腦子想的就是放棄。在心理最為脆弱的時候,黃老師耐心地開導我,給我鼓勵和信心,畢業設計才得以步入正軌。
    萬事開頭難,從研究課題,搜集材料,到正式投入設計,我花費了很多時間和精力。對于這次全新的設計,老師給了我很大的自由空間,可以充分發揮自己的創造思維。但是,對于很多新的嘗試,我還是有所拘束。可能是性格使然吧,每當遇到問題,設計處于混沌狀態時,煩躁焦慮接踵而來,讓我迷失了方向。又是黃老師在最繁忙的時候,給我做細致的分析指導,讓我茅塞頓開,使設計得以延續直至順利完成。所以,在這次畢業設計中,我最感謝的是黃曉東老師,他給我們提供一流的設計場所,還提供了許多實用的設計資料,為我們的設計提供了保障。
在我看來,黃老師不僅是一位態度嚴謹,學識淵博的優秀教師,也是一位心理調節師,他總是能在設計氛圍緊張的時候,給同學們帶來歡樂,緩解同學們的壓力。他那自信樂觀的生活態度,也值得我們學習。從黃老師那里,我不僅學到了許多專業知識和實踐經驗,而且懂得許多做人的道理和生活的真諦,這些都是一輩子受用的財富,讓我受益匪淺,終生難忘。
最后,再次對黃老師表示真誠的謝意和崇高的敬意。同時也對同組同學的幫助表示衷心的感謝。

附 錄

附錄一
硬件電氣原理圖


  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define Data  P0    //數據端口
  6. /*****1602管腳定義*****/
  7. sbit RS=P2^6;
  8. sbit RW=P2^5;
  9. sbit E=P2^7;
  10. /******AD管腳定義*****/
  11. sbit STA=P3^0;
  12. sbit OE=P3^1;
  13. sbit EOC=P3^2;
  14. sbit CLK=P3^3;
  15. /*****按鍵管腳定義******/
  16. sbit key_U=P2^0;
  17. sbit key_D=P2^1;
  18. sbit key_L=P2^2;
  19. sbit key_R=P2^3;
  20. sbit key_S=P2^4;
  21. /******報警用管腳******/
  22. sbit beep=P3^4;
  23. sbit led1=P3^5;
  24. sbit led2=P3^6;
  25. unsigned char num=0;//記錄設定鍵按下次數
  26. unsigned char k_flag=0;//記錄設置鍵按下次數(用于調用)
  27. unsigned char wei=0;//光標位置
  28. unsigned char c_num=0;//記錄切換鍵按下次數
  29. unsigned char c_flag=0;//記錄切換鍵按下次數(用于調用)
  30. unsigned char voc_ad;//AD讀取數據
  31. unsigned char flag;//DHT11函數用到
  32. /****************************/
  33. sbit DHT=P3^7;
  34. uchar  WEN1[]="wen:16.00-28.00";              //溫度第一行數據
  35. uchar  WEN2[]="      20.00    ";   //溫度第二行數據
  36. uchar  SHI1[]="shi:30.00-70.00";              //濕度第一行數據
  37. uchar  SHI2[]="      20.00    ";   //濕度第二行數據
  38. uchar  VOC1[]="voc:0.00-2.70  ";              //濕度第一行數據
  39. uchar  VOC2[]="      0.00    ";   //濕度第二行數據
  40. unsigned char shiZ,shiX,wenZ,wenX,check;
  41. unsigned char tr_shiZ,tr_shiX,tr_wenZ,tr_wenX;
  42. /*********延時*******************************/
  43. void delay_1ms(uint x)
  44.   {
  45.     uchar i;
  46.     while(x--)
  47.     for(i=0;i<120;i++);
  48.   }
  49. void delay_10us()
  50.   {
  51.                             unsigned char i;
  52.                             i--;
  53.                             i--;
  54.                             i--;
  55.                             i--;
  56.                             i--;
  57.                             i--;
  58.   }
  59. void DelayUs(unsigned char us)                            //--延時函數
  60.   {
  61.                             unsigned char uscnt;
  62.                             uscnt=us>>1;        /*12MHz頻率*/
  63.                             while(--uscnt);
  64.   }
  65. /*******1602顯示*******************************************/
  66. /**********寫命令**********/
  67. void lcd_write_com(uchar c)               
  68.   {
  69.     delay_1ms(5);//操作前短暫延時,保證信號穩定
  70.     E=0;
  71.     RS=0;
  72.     RW=0;
  73.     _nop_();
  74.     E=1;
  75.     Data=c;
  76.     E=0;
  77.   }
  78. /**********寫數據*************/
  79. void lcd_write_dat(uchar c)                           
  80.   {
  81.     delay_1ms(5);  //操作前短暫延時,保證信號穩定
  82.     E=0;
  83.     RS=1;
  84.     RW=0;
  85.     _nop_();
  86.     E=1;
  87.     Data=c;
  88.     E=0;
  89.     RS=0;
  90.   }
  91. /**********LCD初始化********/
  92. void lcd_init()               
  93.   {
  94.     delay_1ms(15);
  95.     lcd_write_com(0x38); //display mode
  96.     lcd_write_com(0x38); //display mode
  97.     lcd_write_com(0x38); //display mode
  98.     lcd_write_com(0x06); //顯示光標移動位置
  99.     lcd_write_com(0x0c); //顯示開及光標設置
  100.     lcd_write_com(0x01); //顯示清屏
  101.   }
  102. /*********顯示單個字符**********/
  103. void ShowChar(uchar pos,uchar c)
  104.   {
  105.     unsigned char p;
  106.      if (pos>=0x10)
  107.        p=pos+0xb0; //是第二行則命令代碼高4位為0xc
  108.      else
  109.        p=pos+0x80; //是第二行則命令代碼高4位為0x8
  110.     lcd_write_com(p);//寫命令
  111.     lcd_write_dat(c);   //寫數據
  112.   }
  113. /*********顯示字符串**********/
  114. void ShowString (uchar line,char *ptr)               
  115.   {
  116.     unsigned char l,*p;
  117.     p=ptr;
  118.     l=line<<4;
  119.      while((*p)!='\0')
  120.        {
  121.           ShowChar(l++,*(p));
  122.                                                               p++;
  123.         }
  124.   }
  125. /*********溫度顯示函數***********/
  126. void WENdisp(void)               
  127.   {
  128.                             ShowString(0,WEN1);
  129.                             _nop_();  
  130.                             ShowString(1,WEN2);
  131.   }
  132. /*********濕度顯示函數***********/
  133. void SHIdisp(void)               
  134.   {
  135.     ShowString(0,SHI1);
  136.     _nop_();
  137.     ShowString(1,SHI2);
  138.   }
  139. /*********VOC調用的顯示函數***********/
  140. void VOCdisp(void)               
  141.   {
  142.     ShowString(0,VOC1);
  143.     _nop_();
  144.     ShowString(1,VOC2);
  145.   }
  146. /***********報警用函數************/
  147. void Beep(unsigned char i,j)//i用于確定亮燈方式,j用于確定蜂鳴器是否報警
  148.   {
  149.     unsigned char m;
  150.     led1=led2=1;
  151.     for(m=0; m<250; m++)
  152.                                 {
  153.                                switch(i)
  154.                                               {
  155.                                                         case 0:break;
  156.                                                         case 1:led1=led2=0;break;//低電平點亮
  157.                                                         case 2:led1=0;break;
  158.                                                         case 3:led2=0;break;
  159.                        }
  160.         beep = j;
  161.         delay_1ms(2);
  162.                                           led1=led2=1;
  163.         beep = 0;
  164.         delay_1ms(2);
  165.                                 }
  166.   }
  167. void voc_warning()
  168.   {
  169.                               unsigned char voc_t;            
  170.                               unsigned char voc_h;
  171.       voc_t=('0'+VOC2[6])*10+('0'+VOC2[8]);
  172.       voc_h=('0'+VOC1[9])*10+('0'+VOC1[11]);
  173.                             if(voc_t>voc_h)
  174.                                           {
  175.                                             Beep(1,1);
  176.         }
  177.                   else Beep(0,0);
  178.   }
  179. void wen_warning()
  180.   {
  181.                 unsigned char wen_t;            
  182.                 unsigned char wen_h;
  183.                 unsigned char wen_l;
  184.       wen_t=('0'+WEN2[6])*10+('0'+WEN2[7]);
  185.       wen_l=('0'+WEN1[4])*10+('0'+WEN1[5]);
  186.       wen_h=('0'+WEN1[10])*10+('0'+WEN1[11]);
  187.                             if(wen_t>wen_h||wen_t<wen_l)
  188.                                           {
  189.                                               Beep(2,1);
  190.         }
  191.                             else Beep(0,0);
  192.   }
  193. void shi_warning()
  194.   {
  195.                               unsigned char shi_t;            
  196.                               unsigned char shi_h;
  197.                               unsigned char shi_l;
  198.       shi_t=('0'+SHI2[6])*10+('0'+SHI2[7]);
  199.       shi_l=('0'+SHI1[4])*10+('0'+SHI1[5]);
  200.       shi_h=('0'+SHI1[10])*10+('0'+SHI1[11]);
  201.                             if(shi_t>shi_h||shi_t<shi_l)
  202.                                           {
  203.                                              Beep(3,1);
  204.                                           }
  205.                   else Beep(0,0);
  206.   }
  207. /*******************按鍵***************************/
  208. /*************進入設定功能***************/
  209. unsigned char key_set(void)
  210.   {
  211.      if(key_S==0)
  212.        {
  213.                                                           delay_1ms(10);
  214.                                                           if(key_S==0)
  215.             {
  216.                                                  while(!key_S);
  217.               num++;
  218.                                                               k_flag=num%4;
  219.                                                   }
  220.                                                            else k_flag=num%4;
  221.         }
  222.       else k_flag=num%4;
  223.    return k_flag;            
  224.   }
  225. /********************調整數據******************/
  226. unsigned char key_adddec(unsigned char dat)
  227.   {
  228.    if(key_U==0)
  229.      {
  230.                                 delay_1ms(10);
  231.                                              if(key_U==0)
  232.           {
  233.                                                              while(!key_U);
  234.                                                                       if(dat<'9')
  235.                   dat++;
  236.                            else
  237.                               dat='9';
  238.                                                }
  239.       }
  240.     if(key_D==0)
  241.       {
  242.                                                         delay_1ms(10);
  243.                                               if(key_D==0)
  244.                          {
  245.                                                                            while(!key_D);
  246.                                                                if(dat>'0')
  247.                                                         dat--;
  248.                                          else
  249.                                             dat='0';
  250.                          }
  251.                                           }
  252.    return dat;            
  253.   }
  254. /***************左右移位*******************/
  255. unsigned char key_LR()
  256.   {
  257.                  if(key_L==0)
  258.       {
  259.                                           delay_1ms(10);
  260.                                           if(key_L==0)
  261.            {
  262.                                                             while(!key_L);
  263.                                                              if(wei==0)
  264.                                         wei=3;
  265.                                                             else wei--;
  266.             }
  267.        }
  268.     if(key_R==0)
  269.       {
  270.                                           delay_1ms(10);
  271.                                           if(key_R==0)
  272.           {
  273.             while(!key_R);
  274.                                               if(wei==3)
  275.                 wei=0;
  276.                                               else wei++;
  277.            }
  278.        }
  279.     return wei;
  280.   }
  281. /*********主函數調用的按鍵函數*********/
  282. void set_updn_dat(void)
  283.   {
  284.                             while(key_set())
  285.        {
  286.         unsigned j=key_LR();      
  287.             if(key_set()==1)
  288.               {
  289.                                                                          switch(j>0)
  290.                                                                                                      {
  291.                                                                                                                    case 1:j=2;break;
  292.                                                                                                                    case 0:j=0;break;
  293.                                                                                                   }
  294.                             VOCdisp();
  295.                                                                   VOC1[j+9]=key_adddec(VOC1[j+9]);
  296.                                                      lcd_write_com(0x80+j+9);
  297.                                                                   lcd_write_dat(VOC1[j+9]);        
  298.                           }
  299.                         else                       
  300.               if(key_set()==2)
  301.                 {
  302.                                                                                       switch(j)
  303.                                                                                                   {
  304.                                                                                                                    case 2:j=6;break;
  305.                                                                                                                    case 3:j=7;break;
  306.                                                                                                   }
  307.                                WENdisp();
  308.                                                      WEN1[j+4]=key_adddec(WEN1[j+4]);
  309.                                                      lcd_write_com(0x80+j+4);
  310.                                                                   lcd_write_dat(WEN1[j+4]);
  311.                                                  }
  312.             else                       
  313.               if(key_set()==3)
  314.                 {
  315.                                                                                       switch(j)
  316.                                                                                                   {
  317.                                                                                                                    case 2:j=6;break;
  318.                                                                                                                    case 3:j=7;break;
  319.                                                                                                   }
  320.                   SHIdisp();
  321.                                           SHI1[j+4]=key_adddec(SHI1[j+4]);
  322.                                                      lcd_write_com(0x80+j+4);
  323.                                                                   lcd_write_dat(SHI1[j+4]);
  324.                                                  }            
  325.                               }                           
  326.   }
  327. /*************手動自動切換功能**************/
  328. unsigned char key_change(void)
  329.   {
  330.      if(key_U==0)
  331.        {
  332.                                                             delay_1ms(10);
  333.                                                if(key_U==0)
  334.                                      {
  335.                                                                   while(!key_U);
  336.                                c_num++;
  337.                                                      c_flag=c_num%4;
  338.                                                   }
  339.                                                         else c_flag=c_num%4;
  340.         }
  341.      else c_flag=c_num%4;
  342.    return c_flag;            
  343.   }
  344. /*************************傳感器函數************************/
  345. /**************DHT測試**************/
  346. /******溫濕度讀取函數*******/
  347. char DHTread_data()
  348.   {
  349.                             unsigned char i,num,temp;
  350.                             num=0;
  351.                             for(i=0;i<8;i++)
  352.                                             {
  353.                                                         flag=2;
  354.                                                         while((!DHT)&&flag++);
  355.                                                         delay_10us();
  356.                                                         delay_10us();
  357.                                                         delay_10us();
  358.                                                         if(DHT==1)
  359.                                                                         {
  360.                                                                                     temp=1;
  361.                                                                                     flag=2;
  362.                                                                                     while(DHT&&flag++);                                                      
  363.                                                                         }
  364.                                                         else
  365.                                                                       temp=0;
  366.                                                                       num<<=1;
  367.                                                                       num|=temp;
  368.                                             }
  369.                             return(num);
  370.   }
  371. /********初始化及采集程序*********/
  372. void DHTread_init()
  373.   {
  374.     DHT=0;                              //主機使DHT11低電平并延時至少18ms
  375.     delay_1ms(21);
  376.     DHT=1;                              //主機置DHT11高電平20~40us,并等待從機相應
  377.     delay_10us();
  378.     delay_10us();
  379.     delay_10us();
  380.     DHT=1;
  381.     if(!DHT)  //從機發出相應信號
  382.       {
  383.                                                         flag=2;
  384.                                                         while((!DHT)&&flag++);
  385.                                                         flag=2;
  386.                                                         while(DHT&&flag++);              //開始采集數據
  387.                                                         tr_shiZ=DHTread_data();//采集濕度整數部分
  388.                                                         tr_shiX=DHTread_data();//采集濕度小數部分
  389.                                                         tr_wenZ=DHTread_data();//采集溫度整數部分
  390.                                                         tr_wenX=DHTread_data();//采集溫度小數部分
  391.                                                         check=DHTread_data();              //采集校驗位
  392.                                                         DHT=1;
  393.       }                                                         
  394.   }
  395. /*********顯示測試結果*********/
  396. void DHT11()
  397.   {
  398.                  unsigned char temp;
  399.                   {
  400.                                    DHTread_init();
  401.                                   temp=tr_shiZ+tr_shiX+tr_wenZ+tr_wenX;
  402.                                               if(check==temp)
  403.                                                  {
  404.                                                                  shiZ=tr_shiZ;
  405.                                          shiX=tr_shiX;
  406.                                          wenZ=tr_wenZ;
  407.                                          wenX=tr_wenX;
  408.                          }
  409.            WEN2[6]='0'+wenZ/10;
  410.            WEN2[7]='0'+wenZ%10;            
  411.            WEN2[9]='0'+wenX/10;
  412.            WEN2[10]='0'+wenX%10;
  413.            SHI2[6]='0'+shiZ/10;
  414.            SHI2[7]='0'+shiZ%10;
  415.            SHI2[9]='0'+shiX/10;
  416.            SHI2[10]='0'+shiX%10;
  417.                   }
  418.   }
  419. /****************氣體濃度檢測************/
  420. /*********系統初始化***********/
  421. void init()
  422.   {
  423.                             TMOD = 0x01; //設定定時器T0工作方式
  424.                             TH0=(65536-2)%256;
  425.                             TL0=(65536-2)/256;
  426.                             ET0=1;  //允許T0中斷
  427.                             EA=1; //開總中斷
  428.                             TR0=1; //啟動定時器T0
  429.   }
  430. /**********T0中斷服務程序***********/
  431. void t0(void) interrupt 1 //using 1
  432.   {
  433.                             TH0=(65536-2)%256;
  434.                             TL0=(65536-2)/256;
  435.                             CLK=~CLK;
  436.   }  
  437. /**********AD轉換函數**********/
  438. void AD()
  439.   {
  440.                             STA=0;
  441.     OE=0;
  442.                             STA=1; //啟動AD轉換
  443.                             _nop_();
  444.                             STA=0;
  445.     while(EOC==1);
  446.     OE=1;
  447.     voc_ad=P1;
  448.   }
  449. /*******數據處理********/
  450. void VOC()
  451.   {
  452.                             AD();
  453.                             VOC2[6]='0'+voc_ad/51;
  454.                             VOC2[8]='0'+voc_ad%51*10/51;
  455.                             VOC2[9]='0'+voc_ad%51*10%51*10/51;
  456.   }
  457. /************切換程序*************/
  458. void change(void)
  459.   {
  460.     while(!key_set() && key_change())
  461.        {
  462.                                                           unsigned k=key_change();
  463.             switch(k)
  464.                {
  465.                  case 1:
  466.                                                      VOC();
  467.                                                      VOCdisp();
  468.                                                                                                   voc_warning();
  469.                                                                                                   break;
  470.                  case 2:
  471.                                                      DHT11();
  472.                                                      WENdisp();
  473.                                                                                                   wen_warning();
  474.                                                                                                   break;
  475.                  case 3:
  476.                                                      DHT11();
  477.                                                      SHIdisp();
  478.                                                                                                   shi_warning();
  479.                                                                                                   break;
  480.                  }
  481.                                           }        
  482.   }
  483. /**********************主函數**************************/
  484. void main()
  485.   {
  486.                             lcd_init();
  487.     delay_1ms(50);
  488.                             init();
  489.     num=0;
  490.                             while(1)

  491. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏14 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2017-6-3 03:58 | 只看該作者
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

板凳
ID:264022 發表于 2017-12-19 23:12 | 只看該作者
帖主,能把資料發給我嗎
回復

使用道具 舉報

地板
ID:518760 發表于 2019-4-22 16:58 | 只看該作者
我也想要附件
回復

使用道具 舉報

5#
ID:729397 發表于 2020-4-15 00:44 | 只看該作者
帖主附件有嗎
回復

使用道具 舉報

6#
ID:484435 發表于 2020-6-6 20:00 | 只看該作者
謝謝分享
回復

使用道具 舉報

7#
ID:484435 發表于 2020-6-9 09:52 | 只看該作者
謝謝分享
回復

使用道具 舉報

8#
ID:484435 發表于 2020-6-9 09:55 | 只看該作者
謝謝大佬
回復

使用道具 舉報

9#
ID:936286 發表于 2021-6-16 10:54 | 只看該作者
大佬有完整附件嗎?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美激情一区二区 | 欧美久久一区二区三区 | 亚洲一区二区三区免费在线 | 久久亚洲国产精品日日av夜夜 | 日韩看片 | 久久综合伊人一区二区三 | 久久久久久亚洲精品 | 国产欧美一区二区在线观看 | 午夜精品影院 | 欧美国产日韩一区 | 欧美h视频 | 一区在线观看 | 日韩国产欧美一区 | 亚洲网站在线播放 | 人和拘一级毛片c | 在线2区 | 亚洲精品99 | 伊人免费视频二 | 欧美日韩视频在线 | 亚洲精品18| 国产精品久久久久久一区二区三区 | 国产大片黄色 | 99综合网 | 视频在线一区二区 | 久久久国产一区二区三区 | 欧美日韩综合视频 | 亚洲人成人一区二区在线观看 | 亚洲精品短视频 | 亚洲一区二区综合 | 久久中文一区二区 | 精品国产91| 日本在线小视频 | 久久狠狠 | 日韩精品一二三区 | 亚洲欧美网 | www.天天操 | 国内精品伊人久久久久网站 | 中文字幕人成乱码在线观看 | 91色在线 | 欧美操操操 | 日本在线播放一区二区 |