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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于單片機的測溫濕度設計

[復制鏈接]
跳轉到指定樓層
樓主
ID:288425 發表于 2018-3-16 20:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
摘  要
溫度和濕度是兩個最基本的環境參數,與人們的生活息息相關。在工農業生產、氣象、環保、國防、科研等部門,經常需要對環境溫度和濕度進行測量和控制。準確測量溫濕度在生物制藥、食品加工、造紙等行業更是至關重要。因此研究溫濕度的測量和控制方法具有重要的意義。
本設計實現的是單片機溫濕度測量和控制系統,通過LCD顯示所測量的溫濕度。系統采用集溫濕度傳感器與A/D轉換器于一體的SHT11芯片,通過單片機進行處理顯示,其它模塊包括了實時時鐘/日期產生電路和超限報警處理電路,對測量的值進行實時顯示和報警處理。文章介紹了基于ATMEL公司的AT89C51系列單片機的溫濕度實時測量與控制系統和顯示系統的設計,包括介紹了硬件結構原理,并分析了相應的軟件的設計及其要點,包括軟件設計流程及其程序的實現。系統結構簡單、實用,提高了測量精度和效率。
關鍵詞:AT89C51、SHT11、LCD、DS1302、溫濕度控制
ABSTRACT
Temperature and humidityare two basic environmental parameters which are closely related to people’slives. In the industrial and agriculture production, meteorology, environmentalprotection, national defense, scientific research and other departments, weoften need to measure and control the temperature and humidity of theenvironment. Accurate measurement of temperature and humidity in thepharmaceutical, food processing, paper making and other sectors is essential. Sothe method of temperature and humidity control and measurement is of greatsignificance.
The design implementationof measurement and control temperature and humidity is MCU system, throughwhich the temperature and humidity measurement LCD. System adopts settemperature and humidity sensor and A/D converter for SHT11 chipmicrocontroller processing, through that other modules including real-timedisplay and alarm. The paper introduces the ATMEL company based on AT89C51 single-chip series of temperature andhumidity measurement and control system and real-time display system design,including the hardware structure and principle, and the corresponding softwaredesign, including the design of the software and its key process and procedure.System structure is simple, practical, and improve the measuring precision andefficiency.
Key words: AT89c51, SHT11、LCD、DS1302、temperature and humiditycontrol




目  錄
      






第1章 緒 論
1.1 研究的目的及意義
溫度和濕度與人們的生活息息相關。在工農業生產、氣象、環保、國防、科研等部門,經常需要對環境溫度與濕度進行測量及控制。準確測量溫濕度在生物制藥、食品加工、造紙等行業都是至關重要的。傳統的溫度計是用水銀柱來顯示的,它的精確度不高,不易讀數。而采用單片機對溫濕度進行控制,不僅具有控制方便、簡單和靈活等優點,而且可以大幅度提高溫濕度控制的技術指標。用LCD來顯示溫濕度的數字看起來更加直觀。
采用SHT11數字溫濕度傳感器作為檢測元件,能夠同時測試溫度和濕度。SHT11傳感器可以直接讀出被測的溫濕度值。同時單片機可以把測量出的數據通過串口傳到計算機上,來完成工業中的自動控制,給工業生產帶來了極大的便利。用單片機控制的溫濕度計不僅硬件電路簡單,而且測量精度比較高。用液晶顯示測量值看起來比較美觀。
無論在日常生活中還是在工業、農業方面都離不開對周圍環境進行溫濕度的測量。因此,研究溫濕度的測量具有非常重要的意義。
1.2 國內外研究情況
測量溫濕度的關鍵是溫濕度傳感器。過去測量溫度與濕度是分開的。隨著技術的進步和人們生活的需要出現了溫濕度共測的傳感器。溫度傳感器的發展經歷了3個階段:傳統的分立式溫度傳感器、模擬集成溫度傳感器、智能集成溫度傳感器。目前,國際上新型溫度傳感器正從模擬式向數字式、從集成化向智能化、網絡化的方向發展。溫度傳感器也是經歷了這樣一個階段逐漸走向數字智能化。
現今國內外用的最多的溫濕度傳感器是SHTXX系列。SHT11溫濕度傳感器應用于專利的工業COMS過程微加工技術,確保產品具有極高的可靠性與卓越的長期穩定性。傳感器包括一個電容式聚合體測濕元件和一個能隙式測溫元件,并與一個14位的A/D轉換器以及串行接口電路在同一芯片上實現無縫鏈接,從而具有超快響應,抗干擾能力強,性價比極高等優點。
采用SHT11數字溫濕度傳感器與單片機AT89C51相連比較容易,而且電路比較簡單,軟件設計也比較簡單。所以,本設計以SHT11數字溫濕度傳感器為例,介紹基于SHT11數字溫濕度傳感器的設計,該設計適用于人們的日常生活及工農業生產中用于溫濕度的測量。
1.3系統內容的設計
1.3.1 系統的主要性能指標
根據生活和一般工業環境,設計本產品的主要技術指標為:
·測溫范圍:20—+80℃;濕度測量范圍為30—90%Rh
·溫度測量精度:±0.5oC
·濕度測量誤差:≤4%Rh      
·可設置上、下限報警值,當濕度溫度超限時,發出報警信號
·電源工作范圍:DC4.5~5.5V
1.3.2 主要工作任務
根據本畢業設計實際的任務要求,選擇合適的溫濕度傳感器,完成溫濕度的測量,并設計顯示電路模塊、時鐘電路模塊、超限處理模塊、復位電路模塊的程序。系統開始工作后,根據初始條件讀取濕度值和溫度值,測量數據經處理后,將其與設定的溫濕度值比較,如果發現當前的溫濕度超限,則發出報警信號,未超限時,系統顯示正常的濕溫度度值。
1.4方案論證
方案一:采用單總線的DS18B20的溫度傳感器和HS110X相對濕度傳感器組成測量和控制系統。
方案二:采用集溫濕度傳感器和A/D轉換器于一體的SHT11芯片構成溫濕度的測量和控制系統。
由于傳統的模擬式溫濕度傳感器一般不僅要設計信號調理電路,還要進行復雜的校準和標定過程,其測量精度難以保證,并且使用分立的溫度傳感器和濕度傳感器測量電路比較麻煩。而SHT11是具有二線串行接口的單片全校準數字式新型相對濕度和溫度傳感器,集溫濕度傳感器和A/D轉換器于一體,可用來測量相對濕度、溫度和露點等參數,具有數字式輸出、免調試、免標定、免外圍電路及全互換的特點,使用起來比較方便,且電路簡單。該傳感器將CMOS芯片技術與傳感器技術融合,為開發高集成度、高精度、高可靠性的溫濕度測控系統提供了解決方案。因此本設計采用方案二。
本設計核心部件為AT89C51,信號采集及處理部分由SHT11構成,進入單片機經處理后通過LCD1604顯示溫濕度,信號顯示采用的液晶屏為5×7點陣,一行可顯示16字,四行。其他組成部分為實時時鐘發生電路,產生與現在相同的時間和具體日期,通過LCD1604液晶模塊顯示。
在軟件設計部分有對測量的溫濕度進行上下值的設定,當測量超過限定值時,通過超限報警處理電路對其進行處理,分別顯示不同的二極管燈亮,蜂鳴器產生長鳴。
硬件中包括一個開關,為復位開關。開機后,所有器件初始化,DS1302產生實時時間和日期,溫濕度傳感器SHT11開始進行溫濕度測量和計算,最后通過兩個LCD液晶顯示器顯示結果。在測量結果中有超過設定的溫濕度上下限的,通過超限模塊做出反應。
電路主要包括了AT89C51控制模塊、SHT11溫濕度測量模塊、DS1302時間模塊、LCD顯示模塊、超限處理模塊。其他是一些附件,比如復位、晶振電路。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image001.gif   
圖1.1 整體電路框圖



第2章 工具簡介
系統單片機代碼采用C語言編寫,并用Keil軟件檢查程序有無錯誤,在Proteus仿真軟件上進行仿真。
2.1 C語言
2.1.1 C語言的優點
C語言的運算符豐富,它包括的范圍相當廣泛,使得C語言的運算類型極其豐富,并且表達方式的類型多樣化,能夠實現在高級語言中不能實現的運算,它有32個關鍵字,9種控制語句。和匯編語言一樣,它能夠對位,字節和地址進行操作;數據類型很豐富,能實現各種復雜的數據類型,同時還加入了指針的概念,使得效率更高,同時支持圖形編輯,以及多種顯示器等;它所應用的結構式語言,這種方式會讓程序有層次,一目了然,同時語法顯示不嚴格,設計自由度高;C語言提供給用戶的方式是一函數的形式,它們可以方便調用,使得程序完全結構化;地址的訪問上,能夠訪問物理地址,對硬件進行直接操作;適用范圍廣,能夠適用于多種操作,例如:DOS、UNIX等,同時適用于多種機型。
2.1.2 C語言的缺點
它的缺點主要是數據封裝的安全性不高,因此這一點也成為了C語言和C++的最大的區別,另一方面由于語法以及變量的類型沒有嚴格限制,也造成了較低的安全性,再者從應用角度來說,它比較其他的高級語言來說較為難以掌握。
2.2Proteus簡介
Proteus軟件是來自英國Labcenter electronics公司的EDA工具軟件,Proteus軟件有十多年的歷史,在全球廣泛使用,除了其具有和其它EDA工具一樣的原理布圖、PCB自動或人工布線及電路仿真的功能外,其革命性的功能是,他的電路仿真是互動的,針對微處理器的應用,還可以直接在基于原理圖的虛擬原型上編程,并實現軟件源碼級的實時調試,如有顯示及輸出,還能看到運行后輸入輸出的效果,配合系統配置的虛擬儀器如示波器、邏輯分析儀等。
Proteus組合了高級原理布圖、混合模式SPICE仿真,PCB設計以及自動布線來實現一個完整的電子設計系統。此系統受益于15年來的持續開發,被《電子世界》在其對PCB設計系統的比較文章中評為最好產品—“The Route to PCB CAD”。Proteus 產品系列也包含了革命性的VSM技術,用戶可以對基于微控制器的設計連同所有的周圍電子器件一起仿真。用戶甚至可以實時采用諸如LED/LCD、鍵盤、
RS232終端等動態外設模型來對設計進行交互仿真。
其功能模塊:一個易用而又功能強大的ISIS原理布圖工具;PROSPICE混合模型SPICE仿真;ARES PCB設計。
PROSPICE 仿真器的一個擴展PROTEUS VSM:便于包括所有相關的器件的基于微處理器設計的協同仿真。此外,還可以結合微控制器軟件使用動態的鍵盤,開
關,按鈕,LEDs甚至LCD顯示CPU模型。
· 支持許多通用的微控制器,如PIC,AVR,HC11以及8051. 最新支持ARM
· 交互的裝置模型包括:LED和LCD顯示,RS232終端,通用鍵盤,I2C,SPI器件
· 強大的調試工具,包括寄存器和存儲器,斷點和單步模式
· IAR C-SPY 和Keil uVision2等開發工具的源層調試
· 應用特殊模型的DLL界面-提供有關元件庫的全部文件
最新版支持非常豐富仿真元件共7000多種,還有很多第三方模型。如MMC卡,以太網卡,ATA硬盤,麥克風,等等。
2.3Keil C51編譯器簡介
2.3.1 8051開發工具
KEIL C51標準C編譯器為8051微控制器的軟件開發提供了C語言環境,同時保留了匯編代碼高效,快速的特點。C51編譯器的功能不斷增強,使你可以更加貼近CPU本身,及其它的衍生產品。C51已被完全集成到uVision2的集成開發環境中,這個集成開發環境包含:編譯器,匯編器,實時操作系統,項目管理器,調試器。uVision2 IDE可為它們提供單一而靈活的開發環境。
2.3.2  uVision2集成開發環境
① 項目管理
工程(project)是由源文件、開發工具選項以及編程說明三部分組成的。一個單一的uVision2工程能夠產生一個或多個目標程序。產生目標程序的源文件構成“組”。開發工具選項可以對應目標,組或單個文件。
uVision2包含一個器件數據庫(device database),可以自動設置匯編器、編譯器、連接定位器及調試器選項,來滿足用戶充分利用特定微控制器的要求。此數據庫包含:片上存儲器和外圍設備的信息,擴展數據指針(extra data pointer)或者加速器(math accelerator)的特性。
uVision2可以為片外存儲器產生必要的連接選項:確定起始地址和規模。
② 編輯器和調試器
uVision2編輯器包含了所有用戶熟悉的特性。彩色語法顯像和文件辯識都對C源代碼進行和優化。可以在編輯器內調試程序,它能提供一種自然的調試環境,使得可以更快速地檢查和修改程序。
③ C51編譯器
KEILC51編譯器在遵循ANSI標準的同時,為8051微控制器系列特別設計。語言上的擴展能讓用戶使用應用中的所有資源。
1)存儲器和特殊功能寄存器的存取
C51編譯器可以實現對8051系列所有資源的操作。SFR的存取由sfr和sbit兩個關鍵字來提供。變量可旋轉到任一個地址空間。用關鍵字-at-還能把變量放入固定的存儲器存儲模式(大,中,小)決定了變量的存儲類型。連接定位器支持的代碼區可達32個,這就允許用戶在原有64K ROM的8015基礎上擴展程序。在V2的編譯器和許多高性能仿真器中,可以支持應用程序的調試。
2)中斷功能
C51允許用戶使用C語言編寫中斷服務程序,快速進、出代碼和寄存器區的轉換功能使C語言中斷功能更加高效。可再入功能是用關鍵字來定義的。多任務,中斷或非中斷的代碼要求必須具備可再入功能。
3)靈活的指針
C51提供了靈活高效的指針。
通用指針用3個字節來存儲存儲器類型及目標地址,可以在8051的任意存儲區內存取任何變量。
特殊指針在聲明的同時已指定了存儲器類型,指向某一特定的存儲區域。由
于地址的存儲只需1-2字節,因此,指針存取非常迅速。  








第3章 硬件設計
3.1芯片介紹
3.1.1 單片機——AT89C51
AT89C51是一種帶4k字節可編程可擦除只讀存儲器(FPEROM—Falsh Programmable and Erasable ReadOnly Memory)的低電壓,高性能CMOS8位微處理器,俗稱單片機。89C2051是一種帶2K字節可編程可擦除只讀存儲器的單片機。單片機的可擦除只讀存儲器可以反復擦除100次。該器件采用ATMEL高密度非易失存儲器制造技術制造,與工業標準的MCS-51指令集和輸出管腳相兼容。由于將多功能8位CPU和閃爍存儲器組合在單個芯片中,ATMEL的89C51是一種高效微控制器,89C2051是它的一種精簡版本。89C51單片機為很多嵌入式控制系統提供了一種靈活性高且價廉的方案。
① 主要特性:


·與MCS-51 兼容
·4K字節可編程閃爍存儲器  
·壽命:1000寫/擦循環
·數據保留時間:10年  
·全靜態工作:0Hz-24Hz  
·三級程序存儲器鎖定
·128*8位內部RAM  
·32可編程I/O線  
·兩個16位定時器/計數器
·5個中斷源
·可編程串行通道  
·低功耗的閑置和掉電模式
·片內振蕩器和時鐘電路  


② 管腳說明:
VCC:供電電壓
GND:接地
P0口:P0口為一個8位漏級開路雙向I/O口,每腳可吸收8TTL門電流。當P1口的管腳第一次寫1時,被定義為高阻輸入。P0能夠用于外部程序數據存儲器,它可以被定義為數據/地址的第八位。在FLASH編程時,P0 口作為原碼輸入口,當FLASH進行校驗時,P0輸出原碼,此時P0外部必須被拉高。
P1口:P1口是一個內部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接
收輸出4TTL門電流。P1口管腳寫入1后,被內部上拉為高,可用作輸入,P1口被外部下拉為低電平時,將輸出電流,這是由于內部上拉的緣故。在FLASH
編程和校驗時,P1口作為第八位地址接收。
P2口:P2口為一個內部上拉電阻的8位雙向I/O口,P2口緩沖器可接收,輸出4個TTL門電流,當P2口被寫“1”時,其管腳被內部上拉電阻拉高,且作
為輸入。并因此作為輸入時,P2口的管腳被外部拉低,將輸出電流。這是由于內部上拉的緣故。P2口當用于外部程序存儲器或16位地址外部數據存儲器進行存取時,P2口輸出地址的高八位。在給出地址“1”時,它利用內部上拉優勢,
當對外部八位地址數據存儲器進行讀寫時,P2口輸出其特殊功能寄存器的內容。P2口在FLASH編程和校驗時接收高八位地址信號和控制信號。
P3口:P3口管腳是8個帶內部上拉電阻的雙向I/O口,可接收輸出4個TTL門電流。當P3口寫入“1”后,它們被內部上拉為高電平,并用作輸入。作為輸入,由于外部下拉為低電平,P3口將輸出電流(ILL)這是由于上拉的緣故。 P3口也可作為AT89C51的一些特殊功能口,如下表所示:
表3.1.1 P3口管腳備選功能
  
P3.0 RXD
  
串行輸入口
P3.4 T0
計時器0外部輸入
P3.1 TXD
串行輸出口
P3.5 T1
計時器1外部輸入
P3.2 /INT0
外部中斷0
P3.6 /WR
外部數據存儲器寫選通
P3.3 /INT1
外部中斷1
P3.7 /RD
外部數據存儲器讀選通
P3口同時為閃爍編程和編程校驗接收一些控制信號。
RST:復位輸入。當振蕩器復位器件時,要保持RST腳兩個機器周期的高電平時間。
ALE/PROG:當訪問外部存儲器時,地址鎖存允許的輸出電平用于鎖存地址的
低位字節。在FLASH編程期間,此引腳用于輸入編程脈沖。在平時,ALE端以不
變的頻率周期輸出正脈沖信號,此頻率為振蕩器頻率的1/6。因此它可用作對外
部輸出的脈沖或用于定時目的。然而要注意的是:每當用作外部數據存儲器時,
將跳過一個ALE脈沖。如想禁止ALE的輸出可在SFR8EH地址上置0。此時, ALE
只有在執行MOVX,MOVC指令是ALE才起作用。另外,該引腳被略微拉高。如果
微處理器在外部執行狀態ALE禁止,置位無效。
/PSEN:外部程序存儲器的選通信號。在由外部程序存儲器取指期間,每個機器周期兩次/PSEN有效。但在訪問外部數據存儲器時,這兩次有效的/PSEN信
號將不出現。
/EA/VPP:當/EA保持低電平時,則在此期間外部程序存儲器(0000H-FFFFH),
不管是否有內部程序存儲器。注意加密方式1時,/EA將內部鎖定為RESET;當
/EA端保持高電平時,此間內部程序存儲器。在FLASH編程期間,此引腳也用于
施加12V編程電源(VPP)。
XTAL1:反向振蕩放大器的輸入及內部時鐘工作電路的輸入。
XTAL2:來自反向振蕩器的輸出。
③ 振蕩器特性:
XTAL1和XTAL2分別為反向放大器的輸入和輸出。該反向放大器可以配置為片內振蕩器。石晶振蕩和陶瓷振蕩均可采用。如采用外部時鐘源驅動器件,XTAL2
應不接。輸入至內部時鐘信號要通過一個二分頻觸發器,因此對外部時鐘信號的
脈寬無任何要求,但必須保證脈沖的高低電平要求的寬度。
④ 芯片擦除:
整個PEROM陣列和三個鎖定位的電擦除可通過正確的控制信號組合,并保持ALE管腳處于低電平10ms 來完成。在芯片擦操作中,代碼陣列全被寫“1”且在任何非空存儲字節被重復編程以前,該操作必須被執行。
此外,AT89C51設有穩態邏輯,可以在低到零頻率的條件下靜態邏輯,支持兩種軟件可選的掉電模式。在閑置模式下,CPU停止工作。但RAM,定時器,計數器、串口和中斷系統仍在工作。在掉電模式下,保存RAM的內容并且凍結振蕩器,禁止所用其他芯片功能,直到下一個硬件復位為止。  
⑤ 結構特點:


· 8位CPU;
· 片內振蕩器和時鐘電路;
· 32根I/O線;
· 布爾處理器;
· 外部存貯器尋址范圍ROM、RAM64K;
· 2個16位的定時器/計數器;
· 5個中斷源,兩個中斷優先級;
· 全雙工串行口;


3.1.2 LCD顯示——LCD1604
① LCD1604原理
1604采用標準的16腳接口,其中:
1腳:VSS為地電源
2腳:VDD接5V正電源  
3腳:V0為液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。  
4腳:RS為寄存器選擇,高電平時選擇數據寄存器、低電平時選擇指令寄存器。
5腳:RW為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和RW共同為低電平時可以寫入指令或者顯示地址,當RS為低電平RW為高電平時可以讀忙信號,當RS為高電平RW為低電平時可以寫入數據。
6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令
7~14腳:D0~D7為8位雙向數據線
15~16腳:空腳
1604液晶模塊內部的控制器共有11條控制指令,如表3.1.2所示,
表3.1.21604液晶指令表
  
指   令
  
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
清顯示
0
0
0
0
0
0
0
0
0
1
光標返回
0
0
0
0
0
0
0
0
1
*
置輸入模式
0
0
0
0
0
0
0
1
I/D
S
顯示開/關控制
0
0
0
0
0
0
1
D
C
B
光標或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
置功能
0
0
0
0
1
DL
N
F
*
*
置字符發生存儲器地址
0
0
0
1
字符發生存儲器地址(AGG)
置數據存儲器地址
0
0
1
顯示數據存儲器地址(ADD)
讀忙標志或地址
0
1
BF
計數器地址(AC)
寫數到CGRAM或DDRAM
1
0
要寫的數
從CGRAM或DDRAM讀數
1
1
讀出的數據
它的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明: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:讀數據
② LCD1604初始化
延時15mS寫指令38H(不檢測忙信號)、延時5mS寫指令38H(不檢測忙信號)、延時5mS寫指令38H(不檢測忙信號);以后每次寫指令、讀/寫數據操作均需要檢測忙信號。
寫指令38H:顯示模式設置
寫指令08H:顯示關閉
寫指令01H:顯示清屏
寫指令06H:顯示光標移動設置
寫指令0CH:顯示開及光標設置
3.1.3 DS1302原理及應用
DS1302是DALLAS公司推出的涓流充電時鐘芯片,內含有一個實時時鐘/日歷和31字節靜態RAM,通過簡單的串行接口與單片機進行通信。實時時鐘/日歷電路提供秒分時日、日期月年的信息。每月的天數和閏年的天數可自動調整,時鐘操作可通過AM/PM指示決定采用24或12小時格式。DS1302與單片機之間能簡單地采用同步串行的方式進行通信僅需用到三個口線:RES復位、I/O數據線、 SCLK串行時鐘。時鐘/RAM的讀/寫數據以一個字節或多達31個字節的字符組方式通信,DS1302工作時功耗很低,保持數據和時鐘信息時功率小于1mW。
DS1302是由DS1202改進而來,增加了以下的特性:雙電源管腳用于主電源和備份電源供應;Vcc1為可編程涓流充電電源;附加七個字節存儲器;它廣泛應用于電話傳真便攜式儀器以及電池供電的儀器儀表等產品領域。下面將主要的性能指標作一綜合:
· 實時時鐘具有能計算2100年之前的秒分時日日期星期月年的能力還有閏年調整的能力
·31×8位暫存數據存儲RAM
·串行I/O口方式使得管腳數量最少
·寬范圍工作電壓2.0-5.5V
·工作電流2.0V時,小于300nA
·讀/寫時鐘或RAM數據時有兩種傳送方式單字節傳送和多字節傳送字符組方式
·8腳DIP封裝或可選的8腳SOIC封裝根據表面裝配
·簡單3線接口
·與TTL兼容(Vcc=5V)
·可選工業級溫度范圍-40~+85
·與DS1202兼容
·在DS1202基礎上增加的特性
--對Vcc1有可選的涓流充電能力
--雙電源管用于主電源和備份電源供應
--備份電源管腳可由電池或大容量電容輸入
--附加的7 字節暫存存儲器
① DS1302的基本組成和工作原理
DS1302的管腳排列(圖3.1.1)及描述如下:
1)管腳描述:


X1、X2:32.768KHz晶振管腳
GND:地
RST:復位腳
I/O:數據輸入/輸出引腳
SCLK:串行時鐘
Vcc1、Vcc2:電源供電管腳


file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif
圖3.1.1 DS1302引腳圖
2) DS1302內部寄存器
CH: 時鐘停止位           寄存器2 的第7 位12/24 小時標志
CH=0 振蕩器工作允許      bit7=1,12 小時模式
CH=1 振蕩器停止          bit7=0,24 小時模式
WP: 寫保護位             寄存器2 的第5 位:AM/PM 定義
WP=0 寄存器數據能夠寫入  AP=1 下午模式
WP=1 寄存器數據不能寫入  AP=0 上午模式
TCS: 涓流充電選擇        DS: 二極管選擇位
TCS=1010使能涓流充電    DS=01 選擇一個二極管
TCS=其它 禁止涓流充電    DS=10 選擇兩個二極管
DS=00或11, 即使TCS=1010, 充電功能也被禁止
② DS1302與微控制器的接口軟件及功能應用舉例
下面首先給出基本的接口軟件然后舉例說明各種功能的應用
1) 寫保護寄存器操作
當寫保護寄存器的最高位為0時,允許數據寫入寄存器寫保護,寄存器可以
通過命令字節8E、8F來規定禁止寫入/讀出寫保護位不能在多字節傳送模式下寫
入。  
Write_Enable:
MOVCommand,#8Eh;命令字節為8E
MOVByteCnt,#1;單字節傳送模式
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#00h;數據內容為0 寫入允許
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
當寫保護寄存器的最高位為1時禁止數據寫入寄存器
Write_Disable:
MOVCommand,#8Eh;命令字節為8E
MOVByteCnt,#1;單字節傳送模式
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#80h;數據內容為80h 禁止寫入
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
2) 時鐘停止位操作
當把秒寄存器的第7位時鐘停止位設置為0時起動時鐘開始。
Osc_Enable:
MOVCommand,#80h;命令字節為80
MOVByteCnt,#1;單字節傳送模式
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#00h;數據內容為0 振蕩器工作允許
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
當把秒寄存器的第7位時鐘停止位設置為1時,時鐘振蕩器停止HT1380進入低功耗方式。
Osc_Disable:
MOVCommand,#80h;命令字節為80
MOVByteCnt,#1;單字節傳送模式
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#80h;數據內容為80h 振蕩器停止
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
3) 多字節傳送方式
當命令字節為BE或BF時,DS1302工作在多字節傳送模式,8個時鐘/日歷寄存器從寄存器0地址開始連續讀寫從0位開始的數據。當命令字節為FE或FF時,DS1302工作在多字節RAM傳送模式,31個RAM寄存器從0地址開始連續讀寫從0位開始的數據。例如寫入00年6月21日星期三13時59分59秒程序,設置如下:
Write_Multiplebyte:
MOVCommand,#0Beh;命令字節為BEh
MOVByteCnt,#8;多字節寫入模式此模塊為8 個
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#59h;秒單元內容為59h
MOVXmtDat+1,#59h;分單元內容為59h
MOVXmtDat+2,#13h;時單元內容為13h
MOVXmtDat+3,#21h;日期單元內容為21h
MOVXmtDat+4,#06h;月單元內容為06h
MOVXmtDat+5,#03h;星期單元內容為03h
MOVXmtDat+6,#0;年單元內容為00h
MOVXmtDat+7,#0;寫保護單元內容為00h
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
讀出寄存器0-7的內容程序設置如下:
Read_Multiplebyte;
MOVCommand,#0BFh;命令字節為BFh
MOVByteCnt,#8;多字節讀出模式此模塊為8 個
MOVR1,#RcvDat;數據地址覆給R1
ACALLReceive_Byte;調用讀出數據子程序
RET返回調用本子程序處
以上程序調用了基本數據接收(Receive_Byte)模塊及一些內存單元定義,
其源程序清單在附錄中給出下面的程序亦使用了這個模塊。
4) 單字節傳送方式
    例如寫入8時12小時模式程序設置如下:
Write_Singlebyte:
MOVCommand,#84h;命令字節為84h
MOVByteCnt,#1;單字節傳送模式
MOVR0,#XmtDat;數據地址覆給R0
MOVXmtDat,#88h;數據內容為88h
ACALLSend_Byte;調用寫入數據子程序
RET 返回調用本子程序處
    上面所列出的程序模塊Write_Enable、 Write_Disable 、Osc_Enable 、
Osc_Disable與單字節寫入模塊Write_Singlebyte的程序架構完全相同,僅只是幾個入口參數不同。此介紹是為了強調功能使用的不同才將其分為不同模塊,另外,與涓流充電相關的設定也是單字節操作方式,這里就不再單獨列出,用戶在使用中可靈活簡略。下面模塊舉例說明如何單字節讀出小時單元的內容:
    Read_Singlebyte:                  
MOVCommand,#85h; 命令字節為85h
MOVByteCnt,#1;單字節傳送模式
MOVR1,#RcvDat;數據地址覆給R1
ACALLReceive_Byte;調用讀出數據子程序
RET 返回調用本子程序處
3.1.4溫濕度傳感器SHT11
① SHT11簡介
SHT11是瑞士Scnsirion 公司推出的一款數字溫濕度傳感器芯片。它集溫度傳感器和濕度傳感器于一體,因此采用SHT11 進行溫濕度實時監測的系統具有精度高、成本低、體積小、接口簡單等優點;另外SHT11芯片內部集成了14位A/D 轉換器,且采用數字信號輸出,因此抗干擾能力也比同類芯片高。該芯片在溫濕度監測、自動控制等領域均已得到廣泛應用。其主要特點如下:
·高度集成,將溫度感測、濕度感測、信號變換、A/D 轉換和加熱器等功能集成到一個芯片上;
·提供二線數字串行接口SCK和DATA,接口簡單,支持CRC 傳輸校驗,傳輸可靠性高;
·測量精度可編程調節,內置A/D 轉換器(分辨率為8~12位,可以通過對芯片內部寄存器編程選擇);
·測量精確度高,由于同時集成溫濕度傳感器,可以提供溫度補償的濕度測量值和高質量的露點計算功能;
·封裝尺寸超小(7.62 mm×5.08mm×2.5 mm),測量和通信結束后,自動轉入低功耗模式;
·高可靠性,采用CMOSens工藝,測量時可將感測頭完全浸于水中。
② SHT11引腳功能
SHT11溫濕度傳感器采用SMD(LCC)表面貼片封裝形式,接口非常簡單,引腳
名稱及排列順序如圖3.1.2所示。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image003.gif
圖3.1.2 SHT11引腳圖
各引腳的功能如下:
·腳1和4--信號地和電源,其工作電壓范圍是2.4~5.5 V;
·腳2和腳3--二線串行數字接口,其中DA-TA為數據線,SCK為時鐘線;
·腳5~8--未連接。
③ SHT11的內部結構和工作原理
溫濕度傳感器SHT11將溫度感測、濕度感測、信號變換、A/D轉換和加熱器等功能集成到一個芯片上,其內部結構如圖3.1.3所示。該芯片包括一個電容性聚合體濕度敏感元件和一個用能隙材料制成的溫度敏感元件。這兩個敏感元件分別將濕度和溫度轉換成電信號,該電信號首先進入微弱信號放大器進行放大;然后進入一個14位的A/D 轉換器;最后經過二線串行數字接口輸出數字信號。SHT11在出廠前,都會在恒濕或恒溫環境巾進行校準,校準系數存儲在校準寄存器中;在測量過程中,校準系數會自動校準來自傳感器的信號。此外,SHT11內部還集成了一個加熱元件,加熱元件接通后可以將SHT11 的溫度升高5℃左右,同時功耗也會有所增加。此功能主要為了比較加熱前后的溫度和濕度值,可以綜合驗證兩個傳感器元件的性能。在高濕(>95%RH)環境中,加熱傳感器可預防傳感器結露,同時縮短響應時間,提高精度。加熱后SHT11溫度升高、相對濕度降低,較加熱前,測量值會略有差異。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image004.gif
                                  圖3.1.3 SHT內部結構
微處理器是通過二線串行數字接口與SHT11進行通信的。微處理器對SHT11的控制是通過5個5位命令代碼來實現的,命令代碼的含義如表3.1.3所列。
表3.1.3 SHT11控制命令代碼
  
命令代碼
  
含     義
00011
測量溫度
00101
測量濕度
00111
讀內部狀態寄存器
00110
寫內部狀態寄存器
11110
復位命令,使內部寄存器恢復默認值。下一次命令前至少等待11ms
其他
保留
④ SHT11傳輸特性
1)濕度值輸出
SHT11可通過DATA數據總線直接輸出數字量濕度值。該濕度值稱為“相對濕度”,需要進行線性補償和溫度補償后才能得到較為準確的濕度值。由于相對濕度數字輸出特性呈一定的非線性,因此為了補償濕度傳感器的非線性,可按下式修正濕度值:file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif= file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image008.gif+file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gif×file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif+file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image014.gif×file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image016.gif
式中:file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif為經過線性補償后的濕度值,file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif為相對濕度測量值,C1、C2、C3 為線性補償系數,取值如表3.1.4所列。
由于溫度對濕度的影響十分明顯,而實際溫度和測試參考溫度25℃有所不同,所以對線性補償后的濕度值進行溫度補償很有必要。補償公式如下:
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image019.gif= (T-25)×(file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image021.gif+file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image023.gif×file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif)+file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif
式中:file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image019.gif為經過線性補償和溫度補償后的濕度值,file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image027.gif為測試濕度值時的溫度(℃),file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image021.gif和file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image023.gif為溫度補償系數,取值如表3.1.5所列。
表3.1.4 濕度線性補償系數                    表3.1.5濕度值溫度補償系數                             


  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif
  
C1
C2
C3
12位
-4
0.0405
-2.8×file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image032.gif
8位
-4
0.648
-7.2×file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image034.gif
2)溫度值輸出
  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif
  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image021.gif
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image023.gif
12位
0.01
0.00008
8位
0.01
0.00128


由于SHT11是采用PTAT能隙材料制成的溫度敏感元件,因而具有很好的線性輸出。實際溫度值可由下式算得:     Temperature=d1+d2×SOT
式中:d1和d2為特定系數,d1取值與SHT11工作電壓有關,d2的取值則與SHT11內部A/D轉換器采用的分辨率有關,其對應關系分別如表3.1.6和表3.1.7。
表3.1.6 d1與工作電壓的對應關系            


  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image039.gif
  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image041.gif℃
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image041.gif℉
5
-40.00
-40.00
4
-39.75
-39.50
3.5
-39.65
-39.35
3
-39.60
-39.28
2.5
-39.55
-39.23
表3.1.7 d2與分辨率的對應關系
  
S0
  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image044.gif℃
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image044.gif℉
14位
0.01
0.018
12位
0.04
0.072


3)露點計算
露點是一個特殊的溫度值,是空氣保持某一定濕度必須達到的最低溫度。當空氣的溫度低于露點時,空氣容納不了過多的水分,這些水分會變成霧、露水或霜。露點可以根據當前相對濕度值和溫度值計算得出,具體的計算公式如下:
LogEW=0.66077+7.5×T/(237.3+T)+log10(file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif)-2
Dp=((0.66077-logEW)×237.3)/(logEW-8.16077)
式中:T為當前溫度值,SORH為相對濕度值,Dp為露點。
3.2模塊功能介紹
3.2.1 復位電路部分
這種復位電路的工作原理是:單片機的復位電路在剛接通電時,剛開始電容是沒有電的,電容內的電阻很低,通電后,5V的電通過電阻給電容進行充電,電容兩端的電會由0V慢慢的升到4V左右(此時間很短一般小于0.3秒),RC構成的微分電路在上電瞬間產生一個微分脈沖,其寬度大于兩個機器周期,89C51將復位。正因為這樣,復位腳的電由低電位升到高電位,引起了內部電路的復位工作,RST端電壓慢慢下降,降到一定電壓值以后,即為低電平,單片機開始正常工作(這是單片機的上電復位,也叫初始化復位);當按下復位鍵時,電容兩
端放電,電容又回到0V了,于是又進行了一次復位工作(這是手動復位原理)。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image046.jpg
圖3.2.1 手動復位及晶振電路
3.2.2 DS1302時鐘電路模塊
此模塊是系統時間的實時顯示而設計的,主要由芯片DS1302構成,其中引腳RST、CLK、I/O分別接單片機P3.0、P3.1、P3.2口,屬于控制引腳。此模塊是產生實時的系統時間和日歷,能對某個確定環境的實時溫濕度控制起到一定的作用。芯片連接電路簡單,時間日期準確。
  
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image048.jpg
圖3.2.2 DS1302時鐘電路模塊
3.2.3 SHT11傳感器模塊
此模塊是整個電路設計的信號采集及初步處理的模塊,由溫濕度傳感器芯片SHT11構成,主要的功能結構在前面的芯片介紹中已有,這里不重新介紹。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image050.jpg
圖3.2.3 SHT11傳感器模塊
3.2.4 顯示電路模塊
此模塊分為兩個顯示部分,一個部分是由LCD1604芯片組成的日期時間和實時溫濕度顯示的電路部分,另一部分是由LCD128×64液晶顯示模塊組成的電路部分。LCD1604是一個四行每行16字的液晶顯示屏,D0-D7接P0口,RS、RW、E 接P3.5、P3.6、P3.7起控制作用。LCD128×64組成部分是用來顯示“溫度和濕度的控制與測量”的,其作用是讓人了解此實驗的目的,作用不明顯,這里不做
重點介紹。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image052.jpg圖3.2.4 LCD1604(左)和LCD128×64(右)顯示及其連接電路
3.2.5 超限處理電路模塊
此部分電路是由5個發光二極管和一個蜂鳴報警器構成,分別是D1、D2、D3、D4和D5,蜂鳴器接單片機的P1.0口,發光二極管與單片機的連接部分如圖3.2.5所示。D1、D2、D3、D4、D5分別代表著發光、降溫、加熱、干燥和加濕,一旦傳感器測定的溫濕度超過設定的限額,就會產生不同的發光反應,起警示作用,同時蜂鳴報警器連續發出“滴”的聲音。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image054.jpg
圖3.2.5 超限處理電路模塊
3.3整體電路圖
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image056.jpg
圖3.3.1 整體電路圖


第4章 軟件設計
編程軟件采用的是Keil uvision3軟件,程序采用C語言編程。軟件部分在Keil上運行后,能正確顯示結果。具體模塊由一個C主函數文件和9個H文件構成。
H文件如下所示:


reg51.h;(8051的相關參數初始化)
absacc.h;
intrins.h;(偽本征函數)
math.h;(數學公式函數)
12864.h;(128×64液晶顯示函數)LCD1604.h;(1604液晶顯示函數)
DS1302.h;(實時時間/日期產生函數)
SHT11.h;(溫濕度采集計算函數)
set_key.h;(限額報警函數)


4.1程序框圖
4.1.1 主程序框圖:
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image057.gif
圖4.1.1 主程序框圖
4.1.2 溫濕度采集及處理框圖:
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image058.gif
圖4.1.2 溫濕度采集及處理框圖
4.1.3 LCD顯示框圖:   
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image059.gif
圖4.1.3 LCD顯示框圖
4.2主函數解析
#include<reg51.h>
#include<absacc.h>
#include<intrins.h>
#include<math.h>
#include<12864.h>
#include<LCD1604.h>
#include<DS1302.h>
#include<SHT11.h>
#include<set_key.h>
void Delay1ms(unsigned intcount)    //延時函數
{  
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
main()
{  
SYSTEMTIME CurrentTime;  //定義時間日期結構體
SHT_dat aa;         //定義溫濕度測量處理結構體
Init_12864();     //12864的顯示*/
Initial_DS1302();   //DS1302初始化*/
LCD_Initial();     //LCD初始化
GotoXY(0,0);          //LCD顯示函數
Print("Date:");
GotoXY(16,0);
Print("Temper:");
GotoXY(0,1);
Print("Time:");
GotoXY(16,1);
Print("Humidi:");
while(1)
{  
convert_SHT(&aa,TEMP);     //溫度轉換
  convert_SHT(&aa,HUMI);     //濕度轉換
  caculation_SHT(&aa);       //溫度和濕度的補償
  float_convert(&aa);        //將浮點數轉換成整型,各個位的數分別保存
  doing_temp(&aa);     //檢測溫度是否超限
  doing_humi(&aa);     //檢測濕度是否超限
  DS1302_GetTime(&CurrentTime);
  DateToStr(&CurrentTime);
  TimeToStr(&CurrentTime);
  GotoXY(5,0);      //第一行顯示日期
  Print(CurrentTime.DateString);
  GotoXY(23,0);      //第三行顯示溫度
  Print(aa.num_temp);
  GotoXY(28,0);
  Print("    ");
  GotoXY(5,1);      //第二行顯示時間
  Print(CurrentTime.TimeString);
  GotoXY(23,1);       //第四行顯示濕度
  Print(aa.num_humi);
GotoXY(28,1);
  Print("    ");
  Delay1ms(300);     //延時
  }
}


第5章 仿真與調試
整個軟件通過C語言編程,先在Keil C51集成開發環境下將編好的程序進行
編譯、調試,調試通過后會生成.HEX文件。具體過程如下:
新建一個項目文件,然后新建一個C語言程序,并把新建的C語言程序加
到項目中,然后編譯項目。
建立第一個C項目:
① 點擊 Project 菜單,選擇彈出的下拉式菜單中的 New Project,如圖。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image061.jpg
圖5.1 新建項目文件
② 選擇所要的單片機,本設計選擇常用的 Ateml 公司的 AT89C51。
③ 在項目中創建新的程序文件。執行File->New新建一個文件,然后在文件中進行程序的編寫。
④ 執行File-->Save將編寫的程序進行保存。將第一個程序命名為main.c,將文件保存在項目所在的目錄中。選“Add Fileto Group ‘Source Group 1’”彈出文件窗口,選擇剛剛保存的文件,按 ADD 按鈕,關閉文件窗,程序文件已加到項目中了。這時在 Source Group1 文件夾圖標左邊出現了一個小+號,說明
文件組中有了文件,點擊它可以展開查看。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image063.jpg
圖5.2 添加文件
⑤ 文件加載到項目之后,開始進行編譯運行,生成.hex文件。編譯結果如下圖:
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image065.jpg
圖5.3 生成.hex文件
編譯顯示沒有錯誤,說明編譯順利通過,已經生成了所需要的.hex文件。接下來在PROTEUS中進行仿真。打開已經繪制好的仿真電路原理圖,選中單片機AT89C51,右鍵單擊AT89C51,出現相應的對話框,找到編譯好的“*.HEX”文件,然后單擊“OK”就可以進行仿真。在下邊的圖形中,給出了不同的溫濕度的顯示值,實際溫濕度與理論溫濕度的差值在誤差允許范圍之內(圖5.4,溫度和濕度分別為60℃和80﹪,顯示為60.03℃和82.37﹪;圖5.5,溫度和濕度分別為68℃和70﹪,顯示為68.06℃和74.35﹪;圖5.6,溫度和濕度分別為48℃和31﹪,顯示為48.65℃和32.66﹪),說明設計成功。仿真結果如圖所示。
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image067.jpg
圖5.4 溫濕度顯示一
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image069.jpg
圖5.5 溫濕度顯示二
file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image071.jpg
圖5.6 整體顯示


結  論
單片機的應用如今已經在工業、電子等方方面面展示出了它的優越性,利用單片機在設計電路逐漸成了趨勢,它與外圍的簡單電路再加上優化程序就可以構建任意的產品,使得本設計成為現實。隨著單片機的日益發展,它必將在未來顯示出更大的活力,為電子設計增加更多精彩。
本次設計是基于PROTEUS的數字溫濕度的設計,包括硬件電路和軟件兩部分。設計采用的是高效單片機作為核心,集溫度傳感器和濕度傳感器于一體的SHT11作為主要的采集與測量系統,其中它自帶的A/D轉換器,使得溫濕度測量具有精度高、成本低、體積小、接口簡單等優點,還具有良好抗干擾能力。加上優化程序,使得本系統具有很高的實用性。由AT89C51單片機、晶振等組成的最小系統,可以使整個系統正常穩定的工作起來。由LCD為核心的顯示電路可以直觀的顯示測量結果。報警電路的設計采用了聲光并用的方式。為了實現系統的智能化,系統采用模塊設計,在軟件上設計了系統主程序,溫濕度采集和處理電路子程序,報警電路子程序,液晶顯示子程序,實時的時間日期子程序。
由于學習的知識有限,加上時間的倉促和經驗的缺乏,本設計整體上的性能還不是十分完善,設計中存在一些需要改進和優化的地方。測量精度有待進一步提高,軟件設計也存在不合理之處。但從設計過程中,學到了幾種芯片的使用,如:DS1302時鐘芯片,LCD1604,SHT11等。對于單片機也有了更進一步的認識,對用于單片機仿真的軟件操作能力也明顯提高,通過此設計,本人受益頗豐。


致  謝
經過近兩個多月的努力,在陳英老師的悉心指導下我順利的完成了畢業設計。此次的畢業設計使我受益匪淺。做畢業設計不僅是對我所學知識的一次檢驗,更是對我能力的一個挑戰。從接觸到畢業設計題目的那一刻起,我就開始仔細認真的查找相關資料和文獻,我一直都在盡自己最大的努力去完成它。完成畢業設計后,我發現自己不僅拓寬了專業理論知識,而且專業外的知識也豐富了不少,實際動手能力更是提高了很多。
在做畢業設計的過程中,陳英老師不僅給我提了許多指導性的意見,還傾注了大量的心血。她兢兢業業的工作作風、科學嚴謹的治學態度和寬以待人、認真負責的優秀品質給我留下了非常深刻的印象。沒有陳英老師方向性的指導和幫助,我是不可能按時完成畢業設計的。感謝陳英老師在百忙之中給予我的精心指導和幫助。在做畢業設計的過程中,陳英老師幫助我解決了許多新的疑點和難點,使我順利的完成了畢業設計。除此之外從陳老師那里,我還學到了嚴謹的工作態度和科學的學習方法,也學會了如何做人的道理,所有這些對我今后的成長成才都將產生深遠的影響。在此,我要向我的導師陳英老師表示最衷心的感謝!另外,本設計也得到了其他老師、同學的支持和幫助,謹在此一并感謝!


參考文獻
[1]劉文濤.單片機語言C51典型應用設計[M].北京:人民郵電出版社,2001,12:25-29
[2]周靈彬.基于Proteus的電路與PCB設計[M].北京:電子工業出版社,2010.8
[3]張毅剛主編.單片機原理及應用[M].北京:高等教育出版社,2009
[4]李光飛,樓然苗,胡佳文等.單片機課程設計實例指導[M].北京:北京航空航天大學出版社,2004,105-125
[5]凌玉華.單片機原理及應用系統設計[M].長沙:中南大學出版社,2006,222-228
[6]錢顯毅.傳感器原理與應用[M].東南大學出版社,2008.7
[7]馮建華,趙亮.單片機應用系統設計與產品開發[M].北京:人民郵電出版社, 2004.11
[8]譚浩強.C程序設計[M]. 北京:清華大學出版社,2005.7
[9]常喜茂,孔英會,付小寧.C51基礎與應用實例[M].北京:電子工業出版社 2009.
[10]孫余凱,吳鳴山,項綺明.傳感器應用電路300例[M].北京:電子工業出版社,2008.3
[11]康華光,陳大欽.模擬電子電路[M].北京:高教育出版社,2004:335-336.
[12]趙茂泰.智能儀器原理及應用[M].北京:電子工業出版社,2006:130-132.
[13]李光飛,樓然苗,胡佳文等.單片機課程設計實例指導[M].北京:北京航空航天大學出版社,2004,105-125
[14]佟玲,楊玉芬,張本華.智能溫濕度監控系統的組成與發展[J].沈陽農業大學工程學院學報.2006,23(4);25-30
[15]PualHorowitz and Winfield.The Art of Electronics.2nd ed[M].Cambridge UniversityPress,1999:1-1125.
[16]Allan R.Hambley.Electronics.2nd ed[M].PrenticeHall Inc.2000:1-461.
[17]hnsonD E, Johnson J R. Moore H P.A handbook of active filters[M].NewJersry,1980:1-72.




附錄A 系統源程序
DS1302.h
#ifndef _REAL_TIMER_DS1302
#define _REAL_TIMER_DS1302
sbit  DS1302_CLK = P3^1;             //實時時鐘時鐘線引腳  
sbit  DS1302_IO = P3^2;              //實時時鐘數據線引腳
sbit  DS1302_RST = P3^0;              //實時時鐘復位線引腳
sbit  ACC0 = ACC^0;
sbit  ACC7 = ACC^7;
typedef struct__SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9];
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型
#define AM(X) X
#define PM(X) (X+12)               // 轉成24小時制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR  0x84  
#define DS1302_DAY  0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR  0x8C
#define DS1302_RAM(X)(0xC0+(X)*2)    //用于計算 DS1302_RAM 地址的宏  
voidDS1302InputByte(unsigned char d)  //實時時鐘寫入一字節(內部函數)
{  
    unsigned char i;
    ACC = d;
    for(i=8; i>0; i--)
    {
        DS1302_IO = ACC0;            //相當于匯編中的 RRC
        DS1302_CLK = 1;
        DS1302_CLK = 0;        
ACC = ACC >> 1;  
    }  
}
unsigned charDS1302OutputByte(void)  //實時時鐘讀取一字節(內部函數)
{  
    unsigned char i;
    for(i=8; i>0; i--)
    {
        ACC = ACC >>1;            //相當于匯編中的 RRC  
        ACC7 = DS1302_IO;
        DS1302_CLK = 1;
        DS1302_CLK = 0;
    }  
    return(ACC);  
}
void Write1302(unsigned charucAddr, unsigned char ucDa) //ucAddr: DS1302地, ucData:
{
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302InputByte(ucAddr);        // 地址,命令  
    DS1302InputByte(ucDa);        // 寫1Byte數據
    DS1302_CLK = 1;
    DS1302_RST = 0;
}  
unsigned charRead1302(unsigned char ucAddr) //讀取DS1302某地址的數據
{
    unsigned char ucData;
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302InputByte(ucAddr|0x01);        // 地址,命令  
    ucData = DS1302OutputByte();         // 讀1Byte數據
    DS1302_CLK = 1;
    DS1302_RST = 0;
    return(ucData);
}
void DS1302_SetProtect(bitflag)        //是否寫保護
{  if(flag)
  Write1302(0x8E,0x10);
else
  Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsignedchar Address, unsigned char Value)       // 設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10)));  
void DateToStr(SYSTEMTIME*Time)
{
Time->DateString[0] = Time->Year/10 +'0';
Time->DateString[1] = Time->Year%10 +'0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 +'0';
Time->DateString[4] = Time->Month%10 +'0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 +'0';
Time->DateString[7] =Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME*Time)
{
Time->TimeString[0] =Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 +'0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 +'0';
Time->TimeString[4] = Time->Minute%10 +'0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 +'0';
Time->TimeString[7] = Time->Second%10 +'0';
Time->DateString[8] = '\0';
}
voidDS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  
ReadValue = Read1302(DS1302_MONTH);
Time->Month =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year =((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  
}
void Initial_DS1302(void)
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80)
  DS1302_SetTime(DS1302_SECOND,0);
}
/*******************************************************************voidBurstWrite1302(unsigned char *pWClock) //往DS1302寫入時鐘數據(多字節方式)
{
    unsigned char i;
    Write1302(0x8e,0x00);          // 控制命令,WP=0,寫操作?
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302InputByte(0xbe);         // 0xbe:時鐘多字節寫命令
for (i = 8;i>0; i--)       //8Byte = 7Byte 時鐘數據 + 1Byte 控制{
DS1302InputByte(*pWClock);  // 寫1Byte數據
pWClock++;
    }
    DS1302_CLK = 1;
    DS1302_RST = 0;
}  
void BurstRead1302(unsignedchar *pRClock) //讀取DS1302時鐘數據(時鐘多字節方式)
{
    unsigned char i;
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302InputByte(0xbf);              // 0xbf:時鐘多字節讀命令  
    for (i=8; i>0; i--)  
    {
       *pRClock = DS1302OutputByte();   // 讀1Byte數據  
       pRClock++;
    }
    DS1302_CLK = 1;
    DS1302_RST = 0;
}
void DS1302_TimeStop(bitflag)           // 是否將時鐘停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
  Write1302(DS1302_SECOND, Data|0x80);
else
  Write1302(DS1302_SECOND, Data&0x7F);
}
/******************************************************************/
#endif
LCD1604.h
#ifndef LCD_CHAR_1604
#define LCD_CHAR_1604
#include <intrins.h>
//Port Definition***************************************************
sbit LcdRs  = P3^5;
sbit LcdRw  = P3^6;
sbit LcdEn   = P3^7;
sfr  DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.數據端口
//內部等待函數**************************************************
unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
//while(DBPort&0x80);//
LcdEn=0;
return DBPort;   
}
//向LCD寫入命令或數據***************************************
#define LCD_COMMAND   0     // Command
#define LCD_DATA   1     // Data
#define LCD_CLEAR_SCREEN0x01      // 清屏
#define LCD_HOMING    0x02     // 光標返回原點
void LCD_Write(bit style,unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input;         _nop_();//注意順序
LcdEn=1; _nop_();//注意順序
LcdEn=0; _nop_();
LCD_Wait();
}
//設置顯示模式************************************************
#define LCD_SHOW   0x04   //顯示開
#define LCD_HIDE   0x00   //顯示關  
#define LCD_CURSOR   0x02 //顯示光標
#define LCD_NO_CURSOR          0x00    //無光標  
#define LCD_FLASH   0x01   //光標閃動
#define LCD_NO_FLASH          0x00    //光標不閃動
void LCD_SetDisplay(unsignedchar DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//設置輸入模式*********************************************
#define LCD_AC_UP   0x02
#define LCD_AC_DOWN   0x00     // default
#define LCD_MOVE   0x01     // 畫面可平移
#define LCD_NO_MOVE   0x00     //default
void LCD_SetInput(unsignedchar InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//移動光標或屏幕********************************************
/*
#define LCD_CURSOR  0x02  
#define LCD_SCREEN  0x08
#define LCD_LEFT  0x00
#define LCD_RIGHT  0x04
void LCD_Move(unsigned charobject, unsigned char direction)
{           
if(object==LCD_CURSOR)
  LCD_Write(LCD_COMMAND,0x10|direction);
if(object==LCD_SCREEN)
  LCD_Write(LCD_COMMAND,0x18|direction);
}
*/
//初始化****************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38);          //8位數據端口,2行顯示,5*7點陣
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //開啟顯示, 無光標
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC遞增, 畫面不動
}
//******************************************************************/
void GotoXY(unsigned char x,unsigned char y)  //x列,y行
{
if(y==0)
  LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
  LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char*str)
{
while(*str!='\0')
{   
LCD_Write(LCD_DATA,*str);
  str++;
}
}
/*
void LCD_LoadChar(unsignedchar user[8], unsigned char place)
{
unsigned char i;
LCD_Write(LCD_COMMAND,0x40|(place*8));
for(i=0; i<8; i++)
  LCD_Write(LCD_DATA,user);
}
*/
//******************************************************************/
#endif
set_key.h
#ifndef _setkey_h_
#define _setkey_h_  
#include<SHT11.h>
floatsetwen_h,setwen_l,setshi_h,setshi_l;
sbit hot =P1^4;// 加熱
sbit cold =P1^3;// 降溫
sbit speek =P1^2;// 發光
sbit ganzao =P1^5;//干燥
sbit jiashi =P1^6;//加濕
sbit speaker =P1^0;//  報警
void Delay_xMs(unsigned intx)
{
    unsigned int i,j;
    for( i =0;i < x;i++ )
    {
        for( j =0;j<50;j++ );
    }
}
void Speaker(void)  //報警程序
{
unsigned int i;
for(i=0;i<80;i++ )
{  speaker=~speaker;
  Delay_xMs(2);
}
}  
void doing_temp(SHT_dat *s)
{float xianshi_temp;
  setwen_h=80.00;  
  setwen_l=20.00;
xianshi_temp=s->temperature;  
if((xianshi_temp<setwen_h)&(xianshi_temp>setwen_l))
{ cold=0;hot=0;speek=0;speaker=0;ganzao=0;jiashi=0;}
if(xianshi_temp>setwen_h)  
{cold=1;hot=0;speek=1;Speaker();Delay_xMs(200);speaker=0;}
if(xianshi_temp<setwen_l)  
{cold=0;hot=1;speek=1;Speaker();Delay_xMs(200);speaker=0;}
}  
void doing_humi(SHT_dat *s)
{float xianshi_humi;
setshi_h=90.00;
setshi_l=30.00;
xianshi_humi=s->humidity;
if((xianshi_humi<setshi_h)&(xianshi_humi>setshi_l))
{cold=0;hot=0;speek=0;speaker=0;ganzao=0;jiashi=0;}
if(xianshi_humi>setshi_h)  
{ganzao=1;jiashi=0;speek=1;Speaker();Delay_xMs(200);speaker=0;}
if(xianshi_humi<setshi_l)  
{ganzao=0;jiashi=1;speek=1;Speaker();Delay_xMs(200);speaker=0;}
}
#endif
SHT11.h
#ifndef
#define _SHT11_h_
#define uchar unsigned char
#define uint  unsigned int
#define NOP() _nop_()
#define TEMP 0
#define HUMI 1
sbit  DQ=P2^7; //端口定義
sbit  SCK=P2^6;
typedef struct
{
float temperature;
float humidity;
float crc_temp;
float crc_humi;
uchar num_temp[5];
uchar num_humi[5];
}SHT_dat;
/*=========================================
               啟動函數
=========================================*/
void init_SHT()
{
DQ=1;
SCK=0;
NOP();
SCK=1;
NOP();
DQ=0;
NOP();
SCK=0;
NOP();
NOP();
NOP();
SCK=1;
NOP();  
DQ=1;
NOP();
SCK=0;
}
/*=========================================
              字節傳送函數
=========================================*/
uchar write_byte(ucharvalue)
{
uchar i,error=0;
for(i=0x80;i>0;i/=2)  //高位先傳送
  {
  if(i & value)DQ=1;  //循環相與,結果即為要發送的位
  else DQ=0;
  SCK=1;
  NOP();
  NOP();
  NOP();
  SCK=0;
}
DQ=1;      //釋放總線
SCK=1;
if(DQ==1) error=1;  //檢查應答,確認通訊正常
SCK=0;
return error;     //error=1,通訊有誤
}
/*=========================================
              讀數據函數
=========================================*/
uchar read_byte(uchar dat)
{
uchar i,val=0;
DQ=1;
for(i=0x80;i>0;i/=2)
{
  SCK=1;
  if(DQ) val=(val | i);
  SCK=0;
}
DQ=dat;
SCK=1;
NOP();
NOP();
NOP();
SCK=0;
DQ=1;
return val; }
/*=========================================
                 復位函數
=========================================*/
void reset_SHT()
{  uchar i;
   DQ=1;
   SCK=0;
   for(i=0;i<9;i++)     //DATA保持高電平,SCK時鐘出發9次復位
   {
    SCK=1;
    NOP();
    SCK=0;   
   }  
   init_SHT();
}
/*=========================================
  發送指令到SHT11執行溫度和濕度的測量轉換
=========================================*/
convert_SHT(SHT_dat *s,ucharmode)
{  uchar i,ack=0;
uchar valueM,valueL,checksum;
float com;
do{reset_SHT();
switch(mode)
{ case TEMP: ack=write_byte(0x03);break;
    case HUMI: ack=write_byte(0x05);break;
   default:  break;}
    }while(ack==1);   
for(i=0;i<65535;i++)     //等待測量結束
{
  if(DQ==0)break;
}                        //若長時間數據線DQ沒拉低,則說明測量有錯誤
valueM=read_byte(0);   //數據的高字節
valueL=read_byte(0);      //數據的低字節
checksum=read_byte(1);      //CRC校驗碼   
com=(float)valueM*256+(float)valueL;
if(mode==TEMP)
{  s->temperature=com;
  s->crc_temp=(float)checksum;  }
if(mode==HUMI)
{  s->humidity=com;
  s->crc_humi=(float)checksum;   }
}  
/*=========================================
   溫度和濕度補償及輸出溫度值和相對濕度值
=========================================*/
void caculation_SHT(SHT_dat*s)
{  const float c1=-4.0;
const float c2=+0.0405;
const float c3=-0.0000028;   //以上為12位濕度修正公示取值
const float t1=+0.01;
const float t2=+0.00008;   //以上為14位溫度修正公示取值  
float t=s->temperature;
float rh=s->humidity;  
float rh_lin;
float rh_ture;
float t_c;  
t_c=t * 0.01 - 40;               //溫度的補償
rh_lin=c3*rh*rh  + c2*rh + c1;                  //相對濕度非線性補償
rh_ture=( t_c - 25 ) * ( t1 + t2*rh ) +rh_lin; //相對濕度對于溫度依賴性補償
if( rh_ture > 100 ) rh_ture=100;     //相對濕度最大值修正
if( rh_ture < 0.1 ) rh_ture=0.1;     //相對濕度最小值修正  
if(t_c<0)t_c=0;
s->temperature=t_c;         //保存溫度補償后的結果
s->humidity=rh_ture;         //保存相對濕度補償后的結果
}
/*=========================================
            計算絕對濕度值
=========================================
float calc_dewpoint(floath,float t)
{  
float logEx,dew_point;
   logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
   dew_point = (logEx -0.66077)*237.3/(0.66077+7.5-logEx);
   return dew_point;
}
/*=========================================
            浮點數數據處理
=========================================*/
void float_convert(SHT_dat*s)
{
float com;
uint dat;
com=s->temperature;
com*=100;
dat=(uint)com;
s->num_temp[0]=dat/1000+0x30;   //十位
s->num_temp[1]=dat%1000/100+0x30;  //個位
s->num_temp[2]=0x2e;
s->num_temp[3]=dat%100/10+0x30;   //小數點第一位
s->num_temp[4]=dat%10+0x30;          //小數點第二位
com=s->humidity;
com*=100;
dat=(uint)com;
s->num_humi[0]=dat/1000+0x30;   //十位
s->num_humi[1]=dat%1000/100+0x30;  //個位
s->num_humi[2]=0x2e;
s->num_humi[3]=dat%100/10+0x30;   //小數點第一位
s->num_humi[4]=dat%10+0x30;          //小數點第二位
}     
#endif
12864.h
#ifndef _12864_h_
#define _12864_h_
#define uchar unsigned char
#define uint  unsigned int
#define PORT P0  
sbit  CS1=P2^4;   //端口定義
sbit  CS2=P2^3;
sbit  RS=P2^1;   
sbit  RW=P2^2;
sbit  E=P2^0;
sbit  bflag=P0^7;  //P0口的最高位
/*======================================
   "溫度與濕度的測量與控制"的取模建表
======================================*/
uchar code Str[]={
/*---------------溫----------------*/
0x10,0x30,0x32,0x3C,0x66,0x0F,0x0C,0x60,0x00,0x7F,0x7E,0x7F,0x7E,0x63,0x56,0x7F,
0x56,0x63,0x56,0x63,0x56,0x7F,0x7E,0x63,0x7E,0x7F,0x00,0x7F,0x00,0x60,0x00,0x00,
/*---------------度----------------*/
0x00,0x60,0xFE,0x7F,0xFE,0x1F,0x06,0x40,0x36,0x46,0x36,0x66,0xFE,0x6E,0xFF,0x3E,
0xB7,0x36,0xB6,0x36,0xFE,0x7E,0xFE,0x6E,0x36,0x46,0x36,0x40,0x00,0x00,0x00,0x00,
/*---------------和----------------*/
0x60,0x0C,0x66,0x06,0x66,0x03,0xFE,0x7F,0xFE,0x7F,0x63,0x01,0x63,0x03,0x60,0x02,
0xFC,0x1F,0xFC,0x1F,0x0C,0x0C,0x0C,0x0C,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,
/*---------------濕----------------*/
0x20,0x20,0x62,0x78,0xC6,0x1E,0x8C,0x06,0x00,0x60,0xFE,0x66,0xFE,0x6C,0xD6,0x7F, 0xD6,0x7F,0xD6,0x60,0xD6,0x7F,0xD6,0x7F,0xFE,0x68,0xFE,0x6E,0x00,0x66,0x00,0x00,
/*---------------度----------------*/
0x00,0x60,0xFE,0x7F,0xFE,0x1F,0x06,0x40,0x36,0x46,0x36,0x66,0xFE,0x6E,0xFF,0x3E,
0xB7,0x36,0xB6,0x36,0xFE,0x7E,0xFE,0x6E,0x36,0x46,0x36,0x40,0x00,0x00,0x00,0x00,
/*---------------的----------------*/
0x00,0x00,0xF8,0x3F,0xFC,0x3F,0x9F,0x19,0x9B,0x19,0xF8,0x3F,0xF8,0x3F,0x40,0x00,
0x70,0x00,0xBF,0x03,0x9F,0x63,0x18,0x60,0xF8,0x7F,0xF8,0x3F,0x00,0x00,0x00,0x00,
/*---------------測----------------*/
0x00,0x00,0x66,0x70,0xCC,0x1E,0x00,0x00,0xFE,0x63,0x06,0x38,0xF6,0x0F,0x06,0x00,
0xFE,0x1B,0x00,0x30,0xFC,0x07,0x00,0x60,0xFF,0x7F,0xFF,0x3F,0x00,0x00,0x00,0x00,
/*---------------量----------------*/
0x00,0x00,0x40,0x40,0x40,0x50,0xDF,0x57,0xDF,0x57,0x55,0x55,0x55,0x55,0xD5,0x7F,
0xD5,0x7F,0x55,0x55,0x55,0x55,0xDF,0x57,0xDF,0x57,0x40,0x50,0x40,0x40,0x00,0x00,
/*---------------與----------------*/
0x00,0x00,0x00,0x06,0x00,0x06,0xF0,0x06,0xFF,0x06,0xCF,0x06,0xCC,0x06,0xCC,0x06,
0xCC,0x06,0xCC,0x66,0xCC,0x60,0xCC,0x7F,0xCC,0x3F,0x0C,0x00,0x00,0x00,0x00,0x00,
/*---------------控----------------*/
0x30,0x03,0x30,0x63,0xFF,0x7F,0xFF,0x3F,0xB0,0x01,0x1C,0x60,0xDC,0x66,0x6C,0x66,
0x2D,0x66,0x0F,0x7E,0x0E,0x7E,0x2C,0x66,0x6C,0x66,0xDC,0x66,0x1C,0x60,0x00,0x00,
/*---------------制----------------*/
0x78,0x00,0x6E,0x3F,0x6E,0x3F,0x6C,0x03,0xFF,0x7F,0xFF,0x7F,0x6C,0x33,0x6C,0x3F,
0x60,0x1F,0x00,0x00,0xFC,0x0F,0x00,0x60,0xFF,0x7F,0xFF,0x3F,0x00,0x00,0x00,0x00,
/*---------------:----------------*/
0x00,0x00,0xC0,0x30,0xC0,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*---------------%----------------*/
0xF0,0x00,0x08,0x31,0xF0,0x0E,0x80,0x01,0x70,0x1E,0x08,0x21,0x00,0x1E,0x00,0x00,
/*---------------℃----------------*/0x00,0x00,0x0E,0x00,0x0A,0x00,0x0E,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x04,0x10,
0x04,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x08,0x38,0x04,0x00,0x00,0x00,0x00,
};
/*==========================
        函數聲明
==========================*/
void Ready_12864();
void Left();
void Right();
void Wreg(uchar c);
void Wdata(uchar c);
void Busy_12864();
void Pagefirst(uchar c);
void Linefirst(uchar c);
void Display(uchar *s,ucharpage,uchar line,uchar com,uchar dat);
void Init_12864();
void Delay1s();
void Delay1s(void)
{
uchar h,i,j,k;
for(h=5;h>0;h--)
for(i=4;i>0;i--)
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
void Ready_12864()
{
uint i,j;
Left();
    Wreg(0x3f);
Right();
Wreg(0x3f);     //開顯示,指令代碼為0x3f
Left();     //清左屏幕
for(i=0;i<8;i++)
{
  Pagefirst(i);
  Linefirst(0x00);
  for(j=0;j<64;j++)
  {   Wdata(0x00);
  }
}
Right();    //清右屏幕
for(i=0;i<8;i++)
  {
   Pagefirst(i);
    Linefirst(0x00);
    for(j=0;j<64;j++)
    {
      Wdata(0x00);
     }
  }
}
void Left()
{
CS1=0;
CS2=1;
}
void Right()
{
CS1=1;
CS2=0;
}
void Wreg(uchar c)     /*向12864的寄存器中寫入指令代碼*/
{
Busy_12864();
RS=0;
RW=0;
PORT=c;
E=1;
E=0;
}
void Wdata(uchar c)    /*向12864的緩沖器中寫入顯示數據*/
{
Busy_12864();
RS=1;
RW=0;
PORT=c;
E=1;
E=0;
}
void Busy_12864()     /*判忙程序*/
{
do{E=0;
    RS=0;
    RW=1;
    PORT=0xff;
    E=1;
    E=0;}while(bflag);
}
void Pagefirst(uchar c)    /*控制將要顯示的數據在12864中的頁數*/
{
uchar i;
i=c;
c=i|0xb8;
Busy_12864();
Wreg(c);
}  
void Linefirst(uchar c)     /*控制將要顯示的數據在12864中的列數*/
{
uchar i;
i=c;
c=i|0x40;
Busy_12864();
Wreg(c);
}
/*=========================================
    Display(s,page,line,com,dat)
參    數:參數s      為保存在內存中的數據的首地址
          參數page  為要顯示的字符在12864中的頁碼
          參數line  為要顯示的字符在12864中的列數
          參數com   為要顯示的字符在12864中顯示多少列
          參數dat   dat=0,是16×16的漢字顯示;
       dat=1,是24×24的漢字顯示
功能描述:
         在12864的指定的頁碼和列數中顯示字符,并由dat來選擇
         是顯示16×16的字或者是24×24的字符
         需要注意的是該函數針對的字符取模方式是縱向取模,字節倒序
=========================================*/  
void Display(uchar *s,ucharpage,uchar line,uchar com,uchar dat)
{       uchar i;               
   for(i=0;i<com;i++)
{
  Pagefirst(page);
  Linefirst(line+i);
  Wdata(*s);
  s++;
  Pagefirst(page+1);
  Linefirst(line+i);
  Wdata(*s);
  s++;
  if(dat==0)continue;
  else
  {
   Pagefirst(page+2);
   Linefirst(line+i);
      Wdata(*s);
   s++;
  }
}
}
void Init_12864()     /*在液晶顯示屏上顯示"溫度和濕度的測量與控制"*/
{  Ready_12864();
/************溫度和濕度的測量和控制********************/
Left();                 
Display(Str,1,16,16,0);
Display(Str+32,1,32,16,0);
Display(Str+64,1,48,16,0);
Display(Str+160,3,48,16,0);
Display(Str+192,5,16,16,0);
Display(Str+224,5,32,16,0);
Display(Str+256,5,48,16,0);
Right();
Display(Str+96,1,0,16,0);
Display(Str+128,1,16,16,0);
Display(Str+288,5,0,16,0);
Display(Str+320,5,16,16,0);     
Delay1s();
Delay1s();
Ready_12864();
/************溫度:和 濕度:和單位***************************/
Left();
Display(Str,2,24,16,0);
Display(Str+32,2,40,16,0);
Display(Str+352,2,56,8,0);
Display(Str+96,4,24,16,0);
Display(Str+128,4,40,16,0);
Display(Str+352,4,56,8,0);
  Right();
Display(Str+364,4,8,10,0);    //%
Display(Str+384,2,8,16,0);    //℃      
}
#endif     


file:///C:/Users/gaoyu/AppData/Local/Temp/msohtmlclip1/01/clip_image073.jpg附錄B 系統原理圖

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 蜜月va乱码一区二区三区 | 搞黄视频免费看 | 99精品欧美一区二区三区 | 先锋av资源网 | 久久精品美女 | 欧美一区二区三区四区视频 | 狠狠干天天干 | 欧美精品久久一区 | 色成人免费网站 | 伊人久久免费视频 | 理论片午午伦夜理片影院 | 久久精品青青大伊人av | 亚洲男人的天堂网站 | 亚洲精品一区二区三区蜜桃久 | 91夜夜夜| 中文字幕高清一区 | 免费观看一级特黄欧美大片 | jizz中国日本| 中文字幕韩在线第一页 | 中文字幕在线免费观看 | 99成人 | 北条麻妃一区二区三区在线观看 | 91视频一区二区三区 | 中文字幕一区二区三区日韩精品 | 亚洲网站观看 | 亚洲综合一区二区三区 | 福利一区二区 | 国精品一区 | 妞干网av | 日本 欧美 国产 | 亚洲免费视频网站 | 国产精品久久久久久久久久不蜜臀 | 精品1区2区 | 操视频网站 | 色久伊人 | 国内精品久久久久久影视8 最新黄色在线观看 | 亚洲免费观看 | 中文字幕日韩一区 | 中文字幕一区二区在线观看 | jlzzjlzz国产精品久久 | 婷婷福利视频导航 |