引言
溫度是工、農(nóng)業(yè)生產(chǎn)的主要環(huán)境因素,它對(duì)工農(nóng)業(yè)的生產(chǎn)有著重要的影響,所以對(duì)其進(jìn)行準(zhǔn)確快速的測(cè)量并進(jìn)行處理是具有很特殊的重要意義。測(cè)量溫度模塊是否正確、快速、及時(shí)決定著工農(nóng)業(yè)生產(chǎn)的產(chǎn)品的質(zhì)量是否符合預(yù)期設(shè)計(jì)的要求,而在當(dāng)今是世界中,質(zhì)量是企業(yè)生存的基本,所以許多對(duì)溫度要求很高的工、農(nóng)業(yè)生產(chǎn)企業(yè)把溫度測(cè)量控制系統(tǒng)看成是企業(yè)生存的基本。
在市場(chǎng)競(jìng)爭(zhēng)日益激烈的壓力面前,企業(yè)已經(jīng)意識(shí)到要想提升自己企業(yè)的競(jìng)爭(zhēng)能力,就必須采用新技術(shù)對(duì)企業(yè)產(chǎn)品進(jìn)行質(zhì)量等各方面的管理。而對(duì)溫度要求嚴(yán)格的產(chǎn)品,測(cè)量產(chǎn)品生產(chǎn)環(huán)境的溫度的技術(shù)決定著系統(tǒng)能否生存并繼續(xù)發(fā)展,所以很多工業(yè)生產(chǎn)企業(yè)都非常重視溫度控制系統(tǒng)。
對(duì)溫度進(jìn)行采集,并送到PC機(jī)實(shí)時(shí)處理,以前往往采用的是計(jì)算機(jī)的串行接口,但這一老式計(jì)算機(jī)接口存在著不少缺陷。比如接口規(guī)格不統(tǒng)一、非共享式接口、占用資源大等等這樣那樣的缺點(diǎn)。隨著計(jì)算機(jī)的發(fā)展,USB(通用串行總線)接口是一種計(jì)算機(jī)應(yīng)用領(lǐng)域的新型接口,USB接口的出現(xiàn)是計(jì)算機(jī)端接口的技術(shù)重大變革,其最早是由Compaq、Digital Equipment、IBM、Intel、Microsoft 、NEC和Northern Telecom 7家公司于1994年提出的,在2000年做出了改進(jìn),提出了USB2.0版本,隨著這一版本的提出,USB越來越流行,目前它已經(jīng)成為了一種標(biāo)準(zhǔn)接口,現(xiàn)在市場(chǎng)上的所有PC機(jī)都百分之百支持USB接口,本文將采用這一USB接口來對(duì)采集到的溫度實(shí)時(shí)傳輸。
基于USB接口的溫度控制系統(tǒng)就是通過溫度傳感器對(duì)現(xiàn)場(chǎng)溫度進(jìn)行測(cè)量,并利用微型處理器(單片機(jī)),通過USB接口實(shí)時(shí)的傳給計(jì)算機(jī),計(jì)算機(jī)利用軟件根據(jù)已經(jīng)設(shè)計(jì)好的要求對(duì)其進(jìn)行報(bào)警等相應(yīng)的處理。它是計(jì)算機(jī)技術(shù)、單片機(jī)技術(shù)、溫度傳感器技術(shù)的科技產(chǎn)物。適合于工業(yè)等需要對(duì)溫度進(jìn)行實(shí)時(shí)大范圍的精確的處理。
1 背景知識(shí)
在USB產(chǎn)生之前,外設(shè)與PC機(jī)的通信主要是通過PC機(jī)主板上所提供的各種接口來
實(shí)現(xiàn),如ISA接口、PCI接口、串行接口等,這些老式的接口存在著很多缺點(diǎn):非共享式接口、體積大、接口規(guī)格不統(tǒng)一、采用傳統(tǒng)的I/O模式等等。為了克服老式接口這些缺點(diǎn),PC機(jī)制造商和用戶迫切需要一種新型的外設(shè)連接方式。這時(shí)USB應(yīng)運(yùn)而生,它是一種快速、快速、雙向、同步、廉價(jià)、并支持熱插撥功能的串行接口。
早在1995年,就已經(jīng)有PC機(jī)帶有USB接口了,但由于缺乏軟件及硬件設(shè)備的支持,這些PC機(jī)的USB接口都閑置未用。1998年后,隨著微軟在Windows 98中內(nèi)置了對(duì)USB接口的支持模塊,加上USB設(shè)備的日漸增多,USB接口才逐步走進(jìn)了實(shí)用階段。
這幾年,隨著大量支持USB的個(gè)人電腦的普及,USB逐步成為PC機(jī)的標(biāo)準(zhǔn)接口已經(jīng)是大勢(shì)所趨。在主機(jī)(host)端,最新推出的PC機(jī)幾乎100%支持USB;而在外設(shè)(device)端,使用USB接口的設(shè)備也與日俱增,例如數(shù)碼相機(jī)、掃描儀、游戲桿、磁帶和軟驅(qū)、圖像設(shè)備、打印機(jī)、鍵盤、鼠標(biāo)等等。正是USB具有熱插拔、共享式接口、攜帶方便、標(biāo)準(zhǔn)統(tǒng)一、可以連接多個(gè)設(shè)備等這樣的優(yōu)點(diǎn),才使USB得于快速的發(fā)展。
本文將利用這一新型計(jì)算機(jī)接口來設(shè)計(jì)溫度控制系統(tǒng)。
2 系統(tǒng)概述
本章將對(duì)基于USB接口的溫度控制系統(tǒng)在工業(yè)上的應(yīng)用進(jìn)行分析,并介紹系統(tǒng)的特點(diǎn)、功能以及使用到的開發(fā)工具。
2.1 系統(tǒng)的特性
由于該系統(tǒng)利用USB接口,所以具有USB的實(shí)時(shí)傳送數(shù)據(jù),與上位機(jī)進(jìn)行信息交流,而上位機(jī)又可以連接在互聯(lián)網(wǎng)上,所以遠(yuǎn)程的PC機(jī)也可以利用互聯(lián)網(wǎng)對(duì)溫度檢測(cè)系統(tǒng)進(jìn)行查看等各種操作。該系統(tǒng)利用先進(jìn)的溫度傳感器,可以對(duì)溫度快速的進(jìn)行反應(yīng),把溫度數(shù)據(jù)傳到下位機(jī)進(jìn)行初步處理數(shù)據(jù),進(jìn)而與上位機(jī)通信。總的來說,該系統(tǒng)有以下幾點(diǎn)特點(diǎn):
·工作人員可以遠(yuǎn)離生產(chǎn)環(huán)境通過計(jì)算機(jī)對(duì)其進(jìn)行查看處理;
·多點(diǎn)溫度測(cè)量;
·全天候檢測(cè)溫度,并可以在沒有工作人員的參與下對(duì)生產(chǎn)環(huán)境進(jìn)行簡(jiǎn)單處理;
·對(duì)生產(chǎn)環(huán)境的溫度進(jìn)行設(shè)計(jì)極限溫度,一旦超過極限溫度,系統(tǒng)將對(duì)起進(jìn)行報(bào)警,并停止生產(chǎn)環(huán)境的工作;
·測(cè)量溫度誤差比較精確,在0.5℃內(nèi);
2.2 系統(tǒng)的功能
該系統(tǒng)主要有以下功能:
(1)對(duì)溫度進(jìn)行檢測(cè)。利用該系統(tǒng)可以遠(yuǎn)離惡劣生產(chǎn)環(huán)境的情況下,對(duì)其進(jìn)行溫度測(cè)量;
(2)對(duì)現(xiàn)場(chǎng)溫度進(jìn)行實(shí)時(shí)采集;并在PC機(jī)上顯示出來;
(3)在PC機(jī)上實(shí)時(shí)做出溫度圖像;工作人員在電腦上便可以直觀的得到系統(tǒng)溫度圖像;
(4)簡(jiǎn)單的系統(tǒng)控制;通過計(jì)算機(jī)上的應(yīng)用軟件可以對(duì)溫度設(shè)置,一旦超過極限溫度,發(fā)出報(bào)警,進(jìn)而通知工作人員快速的對(duì)生產(chǎn)現(xiàn)場(chǎng)進(jìn)行各種相應(yīng)操作,這樣可以防止溫度超出極限溫度;
(5)在上位機(jī)端的應(yīng)用軟件上提供系統(tǒng)使用幫助。用戶可以利用該功能幫助對(duì)系統(tǒng)進(jìn)行操作。
2.3 系統(tǒng)開發(fā)平臺(tái)
本次系統(tǒng)需要用到的開發(fā)工具為:keil C、 C++ builder、Protel、計(jì)算機(jī)、燒寫器。
Keil C是目前世界上最好的MC-51單片機(jī)的匯編和C語言的開發(fā)工具。支持匯編、c語言以及混合編程。同時(shí)具備功能強(qiáng)大的軟件仿真和硬件仿真。C++ builder 是計(jì)算機(jī)高級(jí)語言C++比較好用的編程工具,它是屬于一種可視化的計(jì)算機(jī)語言。 Protel是世界上最好的硬件電路圖制作的工具。
3 系統(tǒng)總體設(shè)計(jì)
3.1 系統(tǒng)整體方框圖
根據(jù)前面的分析,知道系統(tǒng)要實(shí)現(xiàn)以上功能,必須由以下幾部分組成:溫度采集單元、下位機(jī)溫度初步處理單元、USB設(shè)備接口、上位機(jī)應(yīng)用程序。
系統(tǒng)的結(jié)構(gòu)原理圖如圖3.1:

圖3.1系統(tǒng)整體實(shí)現(xiàn)的結(jié)構(gòu)原理圖
溫度傳感器單元對(duì)生產(chǎn)溫度環(huán)境進(jìn)行測(cè)量,將測(cè)量溫度傳給下位機(jī)(單片機(jī)),單片機(jī)對(duì)采集到的溫度進(jìn)行初步處理后,將處理了的數(shù)據(jù)通過USB接口上傳給PC機(jī)上位機(jī),而上位機(jī)將實(shí)時(shí)的顯示采集到的溫度,如果要對(duì)現(xiàn)場(chǎng)環(huán)境進(jìn)行處理,則上位機(jī)可以發(fā)送命令,經(jīng)過USB接口傳送到下位機(jī),下位機(jī)根據(jù)接受到的數(shù)據(jù)并對(duì)其進(jìn)行分析,進(jìn)而做出處理,如報(bào)警等各種操作。
3.2 系統(tǒng)方案比較
對(duì)于本系統(tǒng),方案的選擇是根據(jù)溫度傳感器來選擇。
目前市場(chǎng)上有兩種傳感器:模擬傳感器和數(shù)字集成傳感器,對(duì)于選擇不同的傳感器將會(huì)有不同的方案。下面給出兩種不同的方案,并對(duì)其進(jìn)行分析,最終選擇其中一種方案。
3.2.1系統(tǒng)兩種可行方案
方案1:選擇模擬傳感器
所謂模擬傳感器,簡(jiǎn)單的說就是傳感器對(duì)被測(cè)量的物質(zhì)感應(yīng),并隨著檢測(cè)的不同做出不同的反應(yīng),但這一反應(yīng)是有規(guī)律的,而且有規(guī)律的輸出模擬信號(hào)。由于單片機(jī)是數(shù)字信號(hào)系統(tǒng),只能識(shí)別數(shù)字信號(hào),所以這種方案要想利用單片機(jī)對(duì)溫度信號(hào)進(jìn)行處理,必須將對(duì)模擬輸出量數(shù)字化,也就是說要對(duì)其輸出的模擬電壓或電流轉(zhuǎn)換成數(shù)字信號(hào),這么一來就系統(tǒng)要加入模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)的處理單元,通常,實(shí)現(xiàn)這一功能的是A/D轉(zhuǎn)換器,市場(chǎng)對(duì)于這一A/D轉(zhuǎn)換器有不少類型。所以選擇這一方案也是可以有效而快速的設(shè)計(jì)出本系統(tǒng)。
圖3.2給出使用模擬傳感器這一方案的設(shè)計(jì)原理圖。

圖3.2 方案1的結(jié)構(gòu)原理圖
方案2:選擇數(shù)字傳感器
今天隨著計(jì)算機(jī)的飛速發(fā)展以及單片機(jī)的日益普及,世界進(jìn)入了數(shù)字時(shí)代,人們?cè)谔幚肀粶y(cè)信號(hào)時(shí)首先想到的是信息處理器(單片機(jī)或計(jì)算機(jī))。具有輸出數(shù)字信號(hào)便于電腦處理的傳感器就是所謂的數(shù)字傳感器。
數(shù)字傳感器是近幾年才出現(xiàn)的并得到廣泛的應(yīng)在在實(shí)踐當(dāng)中,所謂數(shù)字傳感器,進(jìn)一步的講,就是將模擬傳感器產(chǎn)生的信號(hào)經(jīng)過放大、A/D轉(zhuǎn)換、線性化及量綱處理后變成純粹的數(shù)字信號(hào),是在模擬傳感器上加入數(shù)字處理單元,并將數(shù)字單元集成在一塊芯片上,所以輸出的是數(shù)字信號(hào),便于數(shù)字處理機(jī)對(duì)其直接進(jìn)行處理。
圖3.3給出利用數(shù)字傳感器設(shè)計(jì)的方案圖:

圖3.3 方案2的結(jié)構(gòu)原理圖
3.2.2方案最終選擇
以上已經(jīng)提出了兩種方案,下面對(duì)這兩重方案進(jìn)行分析,并做最后方案選擇:
分析近幾年來傳感器的發(fā)展,我們知道傳感器在未來的發(fā)展中將會(huì)向以下的方向發(fā)展:(1)向高精度發(fā)展。隨著自動(dòng)化生產(chǎn)程度的不斷提高,對(duì)傳感器的要求也在不斷提高,必須研制出具有靈敏度高、精確度高、響應(yīng)速度快、互換性好的新型傳感器以確保生產(chǎn)自動(dòng)化的可靠性。目前能生產(chǎn)精度在萬分之一以上的傳感器的廠家為數(shù)很少,其產(chǎn)量也遠(yuǎn)遠(yuǎn)不能滿足要求。(2)向高可靠性、寬溫度范圍發(fā)展。傳感器的可靠性直接影響到電子設(shè)備的抗干擾等性能,研制高可靠性、寬溫度范圍的傳感器將是永久性的方向。提高溫度范圍歷來是大課題,大部分傳感器其工作范圍都在-20℃~70℃,在軍用系統(tǒng)中要求工作溫度在-40℃~85℃范圍,而汽車鍋爐等場(chǎng)合要求傳感器工作在-20℃~120℃,在冶煉、焦化等方面對(duì)傳感器的溫度要求更高,因此發(fā)展新興材料(如陶瓷)的傳感器將很有前途。(3)向微型化發(fā)展。各種控制儀器設(shè)備的功能越來越大,要求各個(gè)部件體積能占位置越小越好,因而傳感器本身體積也是越小越好,這就要求發(fā)展新的材料及加工技術(shù),目前利用硅材料制作的傳感器體積已經(jīng)很小。如傳統(tǒng)的加速度傳感器是由重力塊和彈簧等制成的,體積較大、穩(wěn)定性差、壽命也短,而利用激光等各種微細(xì)加工技術(shù)制成的硅加速度傳感器體積非常小、互換性可靠性都較好。(4)向微功耗及無源化發(fā)展。傳感器一般都是非電量向電量的轉(zhuǎn)化,工作時(shí)離不開電源,在野外現(xiàn)場(chǎng)或遠(yuǎn)離電網(wǎng)的地方,往往是用電池供電或用太陽能等供電,開發(fā)微功耗的傳感器及無源傳感器是必然的發(fā)展方向,這樣既可以節(jié)省能源又可以提高系統(tǒng)壽命。目前,低功耗損的芯片發(fā)展很快,如TI2702運(yùn)算放大器,靜態(tài)功耗只有1.5mA,而工作電壓只需2~5V。(5)向智能化數(shù)字化發(fā)展。傳感器一般都是非電量向電量的轉(zhuǎn)化,工作時(shí)離不開電源,在野外現(xiàn)場(chǎng)或遠(yuǎn)離電網(wǎng)的地方,往往是用電池供電或用太陽能等供電,開發(fā)微功耗的傳感器及無源傳感器是必然的發(fā)展方向,這樣既可以節(jié)省能源又可以提高系統(tǒng)壽命。目前,低功耗損的芯片發(fā)展很快,如TI2702運(yùn)算放大器,靜態(tài)功耗只有1.5mA,而工作電壓只需2~5V。
由于模擬傳感器,沒有把模擬轉(zhuǎn)化為數(shù)字處理單元集成在一塊芯片上,這樣必帶來傳感檢測(cè)單元的體積大等各個(gè)方面的影響,再者,模擬轉(zhuǎn)化成數(shù)字單元也需要單片機(jī)對(duì)其進(jìn)行處理,這樣會(huì)浪費(fèi)時(shí)間、資源。所以這樣一來我們知道數(shù)字傳感器在未來必將取代模擬傳感器。而且隨著數(shù)字傳感器的發(fā)展,現(xiàn)在市場(chǎng)上數(shù)字傳感也不是那么貴,本次系統(tǒng)對(duì)溫度精度的要求不是很高,所以選擇方案二。
4 系統(tǒng)硬件設(shè)計(jì)
4.1 中央處理器----AT89C51
AT89C51由美國(guó)Atmel 公司生產(chǎn)的,是一種帶4K字節(jié)閃爍可編程可擦除只讀存儲(chǔ)器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低電壓,高性能CMOS8位單片機(jī),該器件采用ATMEL高密度非易失存儲(chǔ)器制造技術(shù)制造,與工業(yè)標(biāo)準(zhǔn)的MCS-51指令集和輸出管腳相兼容。下文將對(duì)AT89C51單片機(jī)做簡(jiǎn)單介紹。
(1) AT89C51的特點(diǎn)
AT89C51具有以下幾個(gè)特點(diǎn):
①中央處理器CPU;
②AT89C51與MCS-51系列的單片機(jī)在指令系統(tǒng)和引腳上完全兼容;
③片內(nèi)有4k字節(jié)在線可重復(fù)編程快擦寫程序存儲(chǔ)器;
④全靜態(tài)工作,工作范圍:0Hz~24MHz;
⑤三級(jí)程序存儲(chǔ)器加密;
⑥128×8位內(nèi)部RAM;
⑦32位雙向輸入輸出線;
⑧兩個(gè)十六位定時(shí)器/計(jì)數(shù)器
⑨五個(gè)中斷源,兩級(jí)中斷優(yōu)先級(jí);
⑩一個(gè)全雙工的異步串行口;
(2)AT89C51的結(jié)構(gòu)圖如圖4.1
圖4.1 89C51的結(jié)構(gòu)圖
由上圖,知:AT89C51主要由CPU、存儲(chǔ)器、I/O端口等幾部分組成。
(3)AT89C51的功能描述
AT89C51是一種低損耗、高性能、CMOS八位微處理器,片內(nèi)有4k字節(jié)的在線可重復(fù)編程、快速擦除快速寫入程序的存儲(chǔ)器,能重復(fù)寫入/擦除1000次,數(shù)據(jù)保存時(shí)間為十年。它與MCA-51系列單片機(jī)在指令系統(tǒng)和引腳上完全兼容,不僅可完全代替MCS-51系列單片機(jī),而且能使系統(tǒng)具有許多MCS-51系列產(chǎn)品沒有的功能。
AT89C51可構(gòu)成真正的單片機(jī)最小應(yīng)用系統(tǒng),縮小系統(tǒng)體積,增加系統(tǒng)的可靠性,降低系統(tǒng)的成本。只要程序長(zhǎng)度小于4K,四個(gè)I/O口全部提供給用戶。可用5V電壓編程,而且擦寫時(shí)間僅需10毫秒,僅為8751/87C51的擦除時(shí)間的百分之一,與8751/87C51的12V電壓擦寫相比,不易損壞器件,沒有兩種電源的要求,改寫時(shí)不拔下芯片,適合許多嵌入式控制領(lǐng)域。工作電壓范圍寬(2.7V~6V),全靜態(tài)工作,工作頻率寬在0Hz~24MHz之間,比8751/87C51等51系列的6MHz~12MHz更具有靈活性,系統(tǒng)能快也能慢。
AT89C51芯片提供三級(jí)程序存儲(chǔ)器加密,提供了方便靈活而可靠的硬加密手段,能完全保證程序或系統(tǒng)不被仿制。P0口是三態(tài)雙向口,通稱數(shù)據(jù)總線口,因?yàn)橹挥性摽谀苤苯佑糜趯?duì)外部存儲(chǔ)器的讀/寫操作。
(4)AT89C51引腳功能及說明
圖4.2是AT89C51的引腳

圖4.2
①口線:P0、P1、P2、P3口。
P0口是三態(tài)雙向口,通稱數(shù)據(jù)總線口,為一個(gè)8位漏級(jí)開路雙向I/O口,每腳可吸收8TTL門電流。當(dāng)P1口的管腳第一次寫1時(shí),被定義為高阻輸入。P0能夠用于外部程序數(shù)據(jù)存儲(chǔ)器,它可以被定義為數(shù)據(jù)/地址的第八位。在FIASH編程時(shí),P0 口作為原碼輸入口,當(dāng)FIASH進(jìn)行校驗(yàn)時(shí),P0輸出原碼,此時(shí)P0外部必須被拉高。因?yàn)橹挥性摽谀苤苯佑糜趯?duì)外部存儲(chǔ)器的讀/寫操作。P0口也用以輸出外部存儲(chǔ)器的低8位地址。由于是分時(shí)輸出,故應(yīng)在外部加鎖存器將此地址數(shù)據(jù)鎖存,地址鎖存信號(hào)用ALE。
P1口是專門供用戶使用的I/O口,是準(zhǔn)雙向口。P1口是一個(gè)內(nèi)部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接收輸出4TTL門電流。
P2口是從系統(tǒng)擴(kuò)展時(shí)作高8位地址線用。不擴(kuò)展外部存儲(chǔ)器時(shí),P2口也可以作為用戶I/O口線使用,P2口也是準(zhǔn)雙向口。
P3口是雙功能口,該口的每一位均可獨(dú)立地定義為第一I/O功能或第二功能。作為第一功能使用時(shí)操作同P1口。P3口的第二功能如表4.1所示。
②控制口線:PSEN(片外選取控制)、ALE(地址鎖存控制)、EA(片外存儲(chǔ)器選擇)、RESET(復(fù)位控制);
③電源及時(shí)鐘:VCC、VSS、XTAL1、XTAL2 操作方法。
表4.1 P3口的第二功能

④操作方法
程序存儲(chǔ)器加密。AT89C51芯片程序存儲(chǔ)器有三級(jí)硬件加密,能夠有效地保證系統(tǒng)不被仿制和軟件不被復(fù)制,加密等級(jí)設(shè)置見附錄2。
工作模式。AT89C51有間歇和掉電兩種工作模式。間歇模式是由軟件來設(shè)置的,當(dāng)外圍器件仍然處于工作狀態(tài)時(shí),CPU可根據(jù)工作情況適時(shí)地進(jìn)入睡眠狀態(tài),內(nèi)部RAM和所有特殊的寄存器值將保持不變。這種狀態(tài)可被任何一個(gè)中斷所終止或通過硬件復(fù)位。
掉電模式是VCC電壓低于電源下限,振蕩器停止振動(dòng),CPU停止執(zhí)行指令。該芯片內(nèi)RAM和特殊功能寄存器值保持不變,直到掉電模式被終止。只有VCC電壓恢復(fù)到正常工作范圍而且在振蕩器穩(wěn)定振蕩后,通過硬件復(fù)位掉電模式可被終止。
4.2 溫度傳感器DS18B20
溫度傳感器是該系統(tǒng)的測(cè)量器件,溫度傳感器的好壞直接影響到測(cè)量結(jié)果,所以本文將對(duì)溫度傳感器的選擇詳細(xì)介紹。根據(jù)本次設(shè)計(jì)論文的要求,包括精度要求等,經(jīng)過分析,本文決定選擇數(shù)字溫度傳感器DSB8B20。下面將給予介紹。
(1) DS18B20的概述
DS18B20是DALLAS公司生產(chǎn)的一線式數(shù)字溫度傳感器,具有3引腳TO-92小體積封裝形式;溫度測(cè)量范圍為-55℃~+125℃,可編程為9位~12位A/D轉(zhuǎn)換精度,測(cè)溫分辨率可達(dá)0.0625℃,被測(cè)環(huán)境的溫度用符號(hào)擴(kuò)展的16位數(shù)字量方式串行輸出;其工作電源既可在遠(yuǎn)端引入,也可采用寄生電源方式產(chǎn)生;多個(gè)DS18B20可以并聯(lián)到3根或2根線上,CPU只需一根端口線就能與諸多DS18B20通信,占用微處理器的端口較少,可節(jié)省大量的引線和邏輯電路。以上特點(diǎn)使DS18B20非常適用于遠(yuǎn)距離多點(diǎn)溫度檢測(cè)系統(tǒng)。
(2)DS18B20的內(nèi)部結(jié)構(gòu)
圖4.3是DS18B20的內(nèi)部結(jié)構(gòu)圖

圖4.3 DS18B20的內(nèi)部結(jié)構(gòu)
由圖可知,DS18B20主要由4部分組成:64位ROM、溫度傳感器、非揮發(fā)的溫
警觸發(fā)器TH和TL、配置寄存器。DS18B20的管腳排列如圖4.4所示,

圖4.4 DS18B20的管腳排列
DS18B20的3個(gè)管腳說明如下:
DQ為數(shù)字信號(hào)輸入/輸出端。是漏極開路一線接口。也在寄生電源接線方式時(shí),給設(shè)備提供電源。
GND為電源地。
VDD為外接供電電源輸入端(在寄生電源接線方式時(shí)接地)。
DS18B20的64位ROM保存了設(shè)備的唯一序列碼,是DS18B20的地址序列碼,每一個(gè)DS18B20的地址序列碼是不同的,這樣就可以實(shí)現(xiàn)一根總線上掛接多個(gè)DS18B20。高速閃存(scratchpad)包括2個(gè)字節(jié)的溫度寄存器。保存了溫度傳感器的數(shù)字輸出。該閃存還提供了對(duì)上限(TH)和下限(TL)的超標(biāo)報(bào)警寄存器、配置寄存器(一個(gè)字節(jié))的訪問。TH、TL和配置寄存器是EEPROM,所以系統(tǒng)掉電時(shí)可以保存數(shù)據(jù)。
DS18B20利用DALLAS的單總線控制協(xié)議,實(shí)現(xiàn)了利用單線控制信號(hào)在總線上進(jìn)行通信。由于所有的設(shè)備通過漏極開路端(DQ腳)連在總線上,控制線需要一個(gè)大約5K上拉電阻。在這一總線控制系統(tǒng)中,微控制器通過唯一的64位地址序列碼識(shí)別和訪問總線上的器件。由于地址序列碼不同,所以連接在總線上的DS18B20可以說是無限的 。
(3)DS18B20的寄存器
DS18B20存儲(chǔ)器組織結(jié)構(gòu)如表4.2所示:
表4.2 存儲(chǔ)器的組織圖
高速閃存(上電狀態(tài))
字節(jié)0 | 溫度底字節(jié) |
字節(jié)1 | 溫度高字節(jié) |
字節(jié)2 | 高溫報(bào)警用戶字節(jié)“1” |
字節(jié)3 | 低溫報(bào)警用戶字節(jié)“2” |
字節(jié)4 | 配置寄存器 |
字節(jié)5 | 保留(FFH) |
字節(jié)6 | 保留(0CH) |
字節(jié)7 | 保留(10H) |
字節(jié)8 | CRC校驗(yàn) |
字節(jié)0和字節(jié)1分別包含溫度寄存器的LSB和MSB,這些字節(jié)是只讀的,字節(jié)2和字節(jié)3提供對(duì)TH(上限報(bào)警觸發(fā)寄存器)和TL(下限報(bào)警觸發(fā)寄存器)的訪問,字節(jié)4包配置寄存數(shù)據(jù),字節(jié)5、6和7保留做器件內(nèi)部使用,不能被改寫,當(dāng)讀時(shí),這些字節(jié)返回全1值,字節(jié)8是只讀的,含有字節(jié)0到字節(jié)的CRC校驗(yàn)。
高速閃存的第四個(gè)字節(jié)包含配置寄存器,其組織結(jié)構(gòu)如下表4.3所示:
表4.3 配置寄存器
Bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
表4.4 測(cè)溫分辨率配置
R1 | R1 | 分辨率 | 最大轉(zhuǎn)換時(shí)間 |
0 | 0 | 9bit | 93.75ms |
0 | 1 | 10bit | 187.5ms |
1 | 0 | 11bit | 375ms |
1 | 1 | 12bit | 750ms |
(4)DS18B20的讀寫時(shí)序
訪問DS18B20的順序如下:
----初始化;
----ROM命令(接著是任何需要的數(shù)據(jù)交換);
----DS18B20的函數(shù)命令(接著是任何需要的數(shù)據(jù)交換);
每一次訪問DS18B20時(shí)必須要按照這一順序,如果其中的任何一個(gè)步驟缺少或打亂,DS18B20將不會(huì)響應(yīng)。
①初始化時(shí)序
初始化時(shí)序如圖4.5:

圖4.5 DS18B20初始化時(shí)序
所有與DS18B20的通信都要首先初始化,從而才能進(jìn)行下一部的工作:控制器發(fā)出復(fù)位脈沖,DS18B20以存在脈沖響應(yīng)。圖4.5給出了描述。當(dāng)DS18B20發(fā)出存在脈沖對(duì)復(fù)位響應(yīng)時(shí),它指示控制器該DS18B20已經(jīng)在總線上并準(zhǔn)備好操作。
②讀/寫時(shí)序
控制器在寫時(shí)序到數(shù)據(jù)到DS18B20,在讀時(shí)序從DS18B20中讀數(shù)據(jù),每一個(gè)總線時(shí)序傳送一個(gè)數(shù)據(jù)位。
讀/寫時(shí)序見下圖4.6

(a)寫時(shí)序

(b)讀時(shí)序
圖4.6 DS18B20的工作時(shí)序圖
③寫時(shí)序
有兩種類型的寫時(shí)序:寫1時(shí)序和寫0時(shí)序。控制器用寫“1”時(shí)序?qū)戇壿嫛?” 到DS18B20,用寫“0”時(shí)序?qū)戇壿嫛?”到DS18B20。所有寫時(shí)序必須持續(xù)60μs,每一個(gè)寫時(shí)序之間必須要至少有1μs的恢復(fù)時(shí)間。兩種類型的寫時(shí)序都從控制器把總線拉低開始。
為產(chǎn)生寫“1”的時(shí)序,在將總線拉低之后,總線控制器必須在15μs內(nèi)釋放總線。總線釋放后,5K的上拉電阻將總線電平抬高。為產(chǎn)生寫“0”時(shí)序,在總線拉低后,控制器在整個(gè)時(shí)序內(nèi)必須持續(xù)控制總線為低電平(至少60μs)。
DS18B20在控制器發(fā)出寫時(shí)序后的15-60μs的時(shí)間內(nèi)采樣總線。如果在采樣窗口期間總線為高,“1”就被寫到DS18B20;如果在采樣窗口期間為低電平,則“0”就被寫入DS18B20。
④讀時(shí)序
當(dāng)總線發(fā)出讀時(shí)序時(shí),DS18B20可以發(fā)送數(shù)據(jù)到控制器。所有讀時(shí)序必須持續(xù)最少60μs,每一個(gè)讀時(shí)序之間必須有至少1μs的恢復(fù)時(shí)間。讀時(shí)序從控制設(shè)備將總線拉低至少1μs后釋放總線開始。控制器啟動(dòng)讀時(shí)序后,DS18B20開始在總線上傳送“1”或者“ 0”。DS18B20通過保持總線為高發(fā)送“1”,將總線拉低發(fā)送“0”。發(fā)送“0”時(shí),DS18B20在60μs時(shí)釋放總線; 發(fā)送“1” 時(shí),總線被上拉電阻高電平空閑狀態(tài)。從DS18B20輸出的數(shù)據(jù)在啟動(dòng)時(shí)序的下降沿后15μs有效。因此,控制器必須在時(shí)序開始的15μs內(nèi)釋放總線,然后采樣總線狀態(tài)。
通過讀/寫時(shí)序,控制器可以發(fā)出控制命令,對(duì)DS18B20進(jìn)行讀寫操作。
(5)DS18B20的常用命令
①SKIP ROM [CCH]
控制器可以用這一命令同時(shí)訪問總線上的所有設(shè)備而不需要發(fā)送ROM序列碼信息。控制器可以使總線上的所有DS18B20同時(shí)進(jìn)行溫度轉(zhuǎn)換。
②SEARCH ROM [F0]
當(dāng)系統(tǒng)開始上電時(shí),控制器必須識(shí)別總線上所有從機(jī)的ROM序列碼,以確定從機(jī)的數(shù)目和它們的類型。控制器需要執(zhí)行 search ROM循環(huán)足夠多次才能識(shí)別所有的從設(shè)備。如果只有一個(gè)從屬設(shè)備在總線上,可使用簡(jiǎn)單的Read ROM命令期待Search ROM。每一個(gè)Search ROM命令之后必須返回到事務(wù)序列的步驟(初始化)。
③READ ROM[33]
這一命令只有在總線上只有一個(gè)設(shè)備的時(shí)候使用,它使得控制器可以不用Search ROM命令就可以讀出從機(jī)的64位ROM序列碼。當(dāng)多于一個(gè)從機(jī)設(shè)備在總線上時(shí),如果還使用該命令,由于所有的設(shè)備企圖響應(yīng)該設(shè)備,這樣將產(chǎn)生數(shù)據(jù)沖突。
④CONVRTT [44]
這一命令開始一次溫度轉(zhuǎn)換。變換之后,數(shù)據(jù)保存在暫存器的2個(gè)字節(jié)溫度寄存器中,DS18B20回到低功耗空閑狀態(tài)。如果設(shè)備工作在寄存電壓模式,則這一命令發(fā)送后10μs之內(nèi),整個(gè)變換期間控制器必須在總線上能夠有較強(qiáng)的上拉。如果DS18B20由外部電源供電,那么Convert T命令后控制器可以發(fā)出讀時(shí)序。如果溫度變換正在進(jìn)行,那么返回“0”;如果已經(jīng)完畢,則返回“1”。
⑤WRITE SCTATCHPAD [4EH]
這一命令使得控制器可以寫3個(gè)字節(jié)數(shù)據(jù)到DS18B20的寄存器中。第一字節(jié)數(shù)據(jù)
到TH寄存器中,第二字節(jié)寫到TL中,第3字節(jié)寫到配置寄存器中。數(shù)據(jù)以最低有效位先發(fā)送。所有3字節(jié)必須在控制器發(fā)出復(fù)位或者數(shù)據(jù)丟失之前寫完。
⑥READ SCRTCHPAD[BEH]
這一命令使得控制器可以讀寄存器的內(nèi)容。數(shù)據(jù)傳送開始于字節(jié)0的最低位,直到寄存器的第9字節(jié)被讀出,任何時(shí)候,如果只需部分寄存器數(shù)據(jù),控制器可以結(jié)束讀操作。
上面已經(jīng)介紹了數(shù)字溫度傳感器的原理,下面將利用DS18B20設(shè)計(jì)溫度采集模塊電路。
4.3 溫度采集模塊電路設(shè)計(jì)
以上已經(jīng)介紹了AT89C51和數(shù)字溫度傳感器DS18B20基本知識(shí),下面將利用它們來設(shè)計(jì)本系統(tǒng)的溫度采集電路。DS18B20連接到單片機(jī)的方法很簡(jiǎn)單,它有兩種方法連接到電路上,既外接電源方式和寄生電源方式,這里使用的是系統(tǒng)提供的外接電源方式,而不采用寄生電源,只要VCC、DQ、GND連接到單片機(jī)的電源正極、一個(gè)I/O端口、電源地就可以了。但是要注意的是在DQ數(shù)據(jù)線中要加一個(gè)4.7K的上拉電阻,這一個(gè)是必須要加的,無論它是接在P1口還是P0口,這點(diǎn)特別注意,特別提醒。之外在電源兩端之間加個(gè)0.01U的電容,這樣的作用主要是濾波。

圖4.7 單片機(jī)和DS18B20接口圖
由圖4.7,知DS18B20工作在外部電源供電方式。單片機(jī)采用采用P1.1口與DS18B20通信。下面根據(jù)單片機(jī)的初始化時(shí)序和讀寫時(shí)序,寫出DS18B20和單片機(jī)之間的讀寫操作,這里只給了溫度的讀取,下位機(jī)部分程序在附錄中給出。
這里特別提醒的是DS18B20對(duì)時(shí)序要求很高,精度要求很高,所以程序的延時(shí)對(duì)是否能讀起數(shù)據(jù)起到非常關(guān)鍵的作用。
DS18B20讀寫數(shù)據(jù)程序如下:
void delaym(int time) //延時(shí)為(time*2+2)us
{ int s;
for(s=0;s<time; s++)
}
void write_bite(unit8 bite) //寫一位數(shù)據(jù)位
{ DQ=0;
if(bite==1)
DQ=1; //如果寫"1",DQ=1;
delaym(29);//延時(shí)60us提供DS18B20采樣
DQ=1; //釋放DQ
}
unit8 read_bite(void) //讀一位數(shù)據(jù)位
{ DQ=0; //將總線DQ拉低開始讀時(shí)序
delaym(0); //延時(shí)2us
DQ=1; //釋放DQ;
delaym(1); //延時(shí)4us后再讀數(shù)據(jù)
return(DQ);
}
void write_byte(unit8 dat) //寫一字節(jié)數(shù)據(jù)
{ unit8 i;
unit8 temp;
for(i=0;i<8;i++)
{ temp=dat>>1; //右移一位
temp&=0x01;
write_bite(temp);
}
}
unit8 read_byte(void)
{ unit8 i,value=0;
for(i=0;i<8;i++)
{ if(read_bite())
value|=0x01<<i;//讀一字節(jié)數(shù)據(jù),一個(gè)讀時(shí)序讀一位,并做移位
delaym(29) ; //延時(shí)60us有以完成讀一位,之后再讀下一位
}
return(value);
}
unit8 DS18B20_RESET(void)
{ unit8 data;
DQ=0;
delaym(239); //保持DQ低480us
DQ=1;
delaym(35);
da=DQ;
delaym(211);
return (data);//有芯片應(yīng)答data=0,無則data=1
}
4.4 系統(tǒng)接口模塊電路設(shè)計(jì)
本系統(tǒng)的采集模塊采集到數(shù)據(jù)后,必須要經(jīng)過CH372傳到上位機(jī)應(yīng)用軟件才能實(shí)現(xiàn)控制下位機(jī)的各種操作。而CH372是USB接口芯片,下位機(jī)和上位機(jī)通信的要通過CH372接口芯片來完成,其和計(jì)算機(jī)的連接很簡(jiǎn)單,所以這一部分主要的硬件實(shí)現(xiàn)是CH372和單片機(jī)AT89C51的連接問題。
4.4.1 USB簡(jiǎn)介
USB(Universal Serial Bus)是外圍設(shè)備與計(jì)算機(jī)進(jìn)行連接的新型接口,既一種新型的通用串型總線接口,USB具有即插即用、熱插撥、接口體積小、節(jié)省系統(tǒng)資源、傳輸可靠、提供電源、良好的兼容性、共享試通信等優(yōu)點(diǎn)。
在USB產(chǎn)生之前,外部設(shè)備和計(jì)算機(jī)的通信主要是通過計(jì)算機(jī)主板所提供的各種接口,比如ISA接口、PCI接口、PS/2接口、串行接口,并行接口等,這些接口,存在這樣那樣的缺陷,比如接口規(guī)格不統(tǒng)一、不共享等為了克服上述外圍設(shè)備的缺陷,P制造商和用戶迫切需要一種新型的外設(shè)接口,USB正是在這樣的環(huán)境下產(chǎn)生的,它是一種快速、雙向、同步、廉價(jià)、并支持熱插撥功能的串行接口。
USB是一種新型的接口,那么它必定有它的通信標(biāo)準(zhǔn),也就是我們所說的協(xié)議,下面簡(jiǎn)單介紹USB的通信協(xié)議。
一般的,對(duì)終端用戶來看,USB系統(tǒng)是USB設(shè)備連接到主機(jī)的簡(jiǎn)單連接,但對(duì)開放人員來說,這中連接可分為三個(gè)層次:功能層、USB設(shè)備層、USB總線接口層,且每一層都由主機(jī)和USB設(shè)備的不同功能模塊組成。可以用下面的圖型來形容。下圖4.8是這種分層通信機(jī)制的簡(jiǎn)化。

圖4.8 USB通信層次模型
由圖,一個(gè)USB設(shè)備由三個(gè)功能模塊組成:USB總線接口、USB邏輯設(shè)備、功能單元。USB總線接口是USB設(shè)備中的串行引擎(SIE);USB邏輯單元被看作是一個(gè)端點(diǎn)的集合;功能單元客戶軟件被看作接口的集合。
USB傳輸類型包括批量傳輸、同步傳輸、中斷傳輸和控制傳輸,每種傳輸類型的傳輸速度、可靠性以及應(yīng)用范圍都不同。控制傳輸可靠性是最高的,但速度最慢;同步傳輸速度快,滿足實(shí)時(shí)性,但可靠性低。在具體應(yīng)用中,端點(diǎn)傳輸類型可根據(jù)傳輸速度和可靠性選擇。
在USB通信協(xié)議中,主機(jī)取得絕對(duì)主動(dòng)權(quán)利,設(shè)備只能是“聽命令行事”,通過一定的命令格式(設(shè)備請(qǐng)求)完成通信。USB設(shè)備請(qǐng)求包括標(biāo)準(zhǔn)請(qǐng)求、廠商請(qǐng)求和設(shè)備類請(qǐng)求。設(shè)備的枚舉是標(biāo)準(zhǔn)請(qǐng)求命令完成的;廠商請(qǐng)求是用戶定義的請(qǐng)求;設(shè)備類請(qǐng)求是特定的USB設(shè)備類發(fā)出的請(qǐng)求,例如海量?jī)?chǔ)存類、打印機(jī)類和HID(人機(jī)接口)類。固件編程中設(shè)備請(qǐng)求必須遵循一定的格式,包括請(qǐng)求類型、設(shè)備請(qǐng)求、值、索引和長(zhǎng)度。
4.4.2 USB芯片選擇
USB的傳輸速度可分為低速(1.5Mbps)、全速(12Mbps)和高速(480Mb/s),按傳輸速度來分,供選擇的USB芯片類型主要有:低速(1.5Mbps)和全速(12Mbps),可選擇Philips公司的PDIUSBD12和Cypress公司的EZ-USB2100系列以及國(guó)產(chǎn)的CH372芯片; 高速(480Mbps)可選Philips公司的ISP1581和Cypress公司的USB接口芯片CY7C68013。
本次系統(tǒng)要傳輸?shù)乃俾时容^少,可以所以選擇全速的USB接口芯片,由于國(guó)產(chǎn)的芯片已經(jīng)有所好轉(zhuǎn),再加上資料比較齊全,這次系統(tǒng)設(shè)計(jì)所選擇的USB接口芯片是國(guó)產(chǎn)芯片CH372。
芯片介紹:
CH372是南京沁恒電子有限公司生產(chǎn)的新型USB接口芯片,具有8位數(shù)據(jù)總線和讀、寫、片選控制線以及中斷輸出,可以方便地掛接到單片機(jī)/DSP/MCU/MPU等控制器的系統(tǒng)總線上;它屏蔽了USB通信協(xié)議,用戶如果沒有涉及到底層開放,那么只要了解芯片的普通用法就可以快速的設(shè)計(jì)USB設(shè)備。利用CH372進(jìn)行USB設(shè)備的通信設(shè)計(jì)可以如下的方框圖4.9
圖4.9 CH372和單片機(jī)框架連接
下面給出CH372的引腳圖(圖4.10)及部分命令:
圖4.10 CH372的管腳
CH372芯片占用兩個(gè)地址位,當(dāng)A0 引腳為高電平時(shí)選擇命令端口,可以寫入命令;當(dāng)A0引腳為低電平時(shí)選擇數(shù)據(jù)端口,可以讀寫數(shù)據(jù)。單片機(jī)通過8 位并行口對(duì)CH372 芯片進(jìn)行讀寫,所有操作都是由一個(gè)命令碼、若干個(gè)輸入數(shù)據(jù)和若干個(gè)輸出數(shù)據(jù)組成,部分命令不需要輸入數(shù)據(jù),部分命令沒有輸出數(shù)據(jù)。命令操作步驟如下:
①在A0=1 時(shí)向命令端口寫入命令代碼;
②如果該命令具有輸入數(shù)據(jù),則在A0=0 時(shí)依次寫入輸入數(shù)據(jù),每次一個(gè)字節(jié);
③如果該命令具有輸出數(shù)據(jù),則在A0=0 時(shí)依次讀取輸出數(shù)據(jù),每次一個(gè)字節(jié);
④命令完成,可以暫停或者轉(zhuǎn)到①繼續(xù)執(zhí)行下一個(gè)命令。
CH372的命令如表4.5:
表 4.5 CH372命令
代碼 | 命令名稱 | 輸入數(shù)據(jù) | 輸出數(shù)據(jù) | 命令用途 |
05H | RESET_ALL | | (等40mS) | 執(zhí)行硬件復(fù)位 |
06H | CHECK_EXIST | 任意數(shù)據(jù) | 按位取反 | 測(cè)試工作狀態(tài) |
12H | SET_USB_ID | VID 字節(jié) PID 字節(jié) | | 設(shè)置USB的廠商VID和PID |
15H | SET_USB_MODE | 模式代碼 | (等20uS) 操作狀態(tài) | 設(shè)置USB工作模式 |
22H | GET_STATUS | | 中斷狀態(tài) | 獲取中斷狀態(tài)并取消請(qǐng)求 |
28H | RD_USB_DATA | | | 從當(dāng)前USB中斷的端點(diǎn)緩沖區(qū)讀取數(shù)據(jù)塊并釋放當(dāng)前緩沖區(qū) |
2AH | WR_USB_DATA5 | | | 向USB端點(diǎn)1的上傳緩沖區(qū)寫入數(shù)據(jù)塊 |
2BH | WR_USB_DATA7 | | | 向USB端點(diǎn)2的上傳緩沖區(qū)寫入數(shù)據(jù)塊 |
4.4.3 USB設(shè)備端的接口設(shè)計(jì)
CH372芯片在本地端提供了通用的被動(dòng)并行接口,包括:8位雙向數(shù)據(jù)總線D7~D0、讀選通輸入引腳RD#、寫選通輸入引腳WR#、片選輸入引腳CS#、中斷輸出引腳INT#以及地址輸入引腳A0。通過被動(dòng)并行接口,CH372 芯片可以很方便地掛接到各種8位單片機(jī)、DSP、MCU 的系統(tǒng)總線上,并且可以與多個(gè)外圍器件共存。CH372芯片的RD#和WR#可以分別連接到單片機(jī)的讀選通輸出引腳和寫選通輸出引腳。CS#由地址譯碼電路驅(qū)動(dòng),用于當(dāng)單片機(jī)具有多個(gè)外圍器件時(shí)進(jìn)行設(shè)備選擇。INT#輸出的中斷請(qǐng)求是低電平有效,可以連接到單片機(jī)的中斷輸入引腳或者普通I/O 引腳,單片機(jī)可以使用中斷方式或者查詢方式獲知中斷請(qǐng)求。當(dāng)WR#為高電平并且CS#和RD#及A0 都為低電平時(shí),CH372 中的數(shù)據(jù)通過D7~D0輸出;當(dāng)RD#為高電平并且CS#和WR#及A0 都為低電平時(shí),D7~D0上的數(shù)據(jù)被寫入CH372 芯片中;當(dāng)RD#為高電平并且CS#和WR#都為低電平而A1 為高電平時(shí),D7~D0 上的數(shù)據(jù)被作為命令碼寫入CH372芯片中。CH372 芯片的VD+和VD-引腳應(yīng)該直接連接到USB 總線上。如果為了芯片安全而串接保險(xiǎn)電阻或者電感,那么交直流等效串聯(lián)電阻應(yīng)該在5Ω之內(nèi)。
USB定義了四種傳輸類型:控制傳輸、快傳輸、中斷傳輸和同步傳輸。南京沁恒公司的USB接口芯片CH372支持控制傳輸、批量傳輸、中斷傳輸。CH372主要有兩種數(shù)據(jù)流傳輸方式:?jiǎn)蜗驍?shù)據(jù)流方式和請(qǐng)求應(yīng)答方式。其中請(qǐng)求應(yīng)答方式步驟如下:
① 計(jì)算機(jī)應(yīng)用層按事先約定的格式將數(shù)據(jù)請(qǐng)求發(fā)送給CH372芯片;
② CH372 芯片以中斷方式通知單片機(jī);
③ 單片機(jī)進(jìn)入中斷服務(wù)程序,獲取CH372的中斷狀態(tài)并分析;
④ 如果是上傳,則釋放當(dāng)前USB 緩沖區(qū),然后退出中斷程序;
⑤ 如果是下傳,則從數(shù)據(jù)下傳緩沖區(qū)中讀取數(shù)據(jù)塊;
⑥ 分析接收到的數(shù)據(jù)塊,準(zhǔn)備應(yīng)答數(shù)據(jù),也可以先退出中斷程序再處理;
⑦ 單片機(jī)將應(yīng)答數(shù)據(jù)寫入批量端點(diǎn)的上傳緩沖區(qū)中,然后退出中斷程序;
⑧ CH372 芯片將應(yīng)答數(shù)據(jù)返回給計(jì)算機(jī);
⑨ 計(jì)算機(jī)應(yīng)用層接收到應(yīng)答數(shù)據(jù)。
這種傳輸方式是必需要有計(jì)算機(jī)斷發(fā)出響應(yīng)才可以進(jìn)行的。在本次系統(tǒng)設(shè)計(jì)中,可以通過向計(jì)算機(jī)發(fā)出命令,下位機(jī)根據(jù)命令來進(jìn)行各種操作,包括設(shè)計(jì)報(bào)警溫度,采集溫度等。
由于系統(tǒng)不需要那么多I/O口,所以本次系統(tǒng)設(shè)計(jì)的單片機(jī)端不需要擴(kuò)展,直接用端片機(jī)的I/O端口,值得注意的是MCU不擴(kuò)展,那么P0只能口只能作為I/O口使用,而不能作為數(shù)據(jù)/地址端口復(fù)用。這一點(diǎn)必須注意,而P0口做普通I/O使用必需要加上拉電阻1K到10K左右。否則系統(tǒng)將無法運(yùn)行,這點(diǎn)特別提醒要注意的地方。
最終CH372與單片機(jī)AT89C51之間的連接圖,如下圖4.11

4.11 CH372和89C51的連接圖
圖中P2作為CH372芯片8位雙向數(shù)據(jù)總線通信端口來使用。P1和P0端口作為普通的I/O口,USB 總線包括一對(duì)5V 電源線和一對(duì)(D+、D-)數(shù)據(jù)信號(hào)線。通常,+5V 電源線是紅色,接地線是黑色,D+信號(hào)線是綠色,D-信號(hào)線是白色。USB 總線提供的電源電流最大可以達(dá)到500mA,一般情況下,低功耗的USB 產(chǎn)品可以直接使用USB 總線提供的5V 電源。如果USB 產(chǎn)品通過其它供電方式提供常備電源,那么CH372 應(yīng)該與單片機(jī)一起使用該常備電源并且斷開USB總線的電源;如果需要同時(shí)使用USB 總線的電源,那么可以通過阻值約為1Ω的電阻R1 連接USB 總線的5V 電源線與USB 產(chǎn)品的5V 常備電源,并且兩者的接地線直接相連接。
CH372 的CS#固定為低電平,一直處于片選狀態(tài),在單片機(jī)程序中,可以控制各個(gè)I/O引腳模擬并口時(shí)序與CH372 進(jìn)行數(shù)據(jù)交換。比如控制P05、P06、P07來讀、寫命令。
圖4.11中,可選電阻R2 用于在電源斷電后將電解電容C5 中的電能及時(shí)釋放掉,使VCC 及時(shí)下降到0V,確保在下次通電時(shí)CH372 能夠可靠地上電復(fù)位。電容C3 用于CH372 內(nèi)部電源節(jié)點(diǎn)退耦,C3 是容量為0.01μF 的獨(dú)石或高頻瓷片電容,如果對(duì)EMI 沒有要求那么可以省掉C3。電容C4和C5用于外部電源退耦,C4 是容量為0.1μF的獨(dú)石或高頻瓷片電容。晶體X1、電容C1 和C2 用于CH372的時(shí)鐘振蕩電路。X1的頻率是12MHz,C1和C2是容量為15pF-30pF 的獨(dú)石或高頻瓷片電容。
本次系統(tǒng)設(shè)計(jì)的USB接口硬件設(shè)計(jì)已經(jīng)完成。而且應(yīng)用部分的硬件設(shè)計(jì)也已經(jīng)完成,下節(jié)將給出整體硬件設(shè)計(jì)的電路圖。
4.5 系統(tǒng)硬件整體實(shí)現(xiàn)
下位機(jī)的應(yīng)用部分是DS18B20,DS18B20采集到溫度信號(hào),并轉(zhuǎn)換成數(shù)字信號(hào)然后輸出到單片機(jī)AT89C51,單片機(jī)對(duì)數(shù)字信號(hào)進(jìn)行處理,然后將處理的數(shù)據(jù)通過USB接口芯片傳到上位機(jī)的USB設(shè)備驅(qū)動(dòng)程序,上位機(jī)的主USB控制驅(qū)動(dòng)程序接受來自USB設(shè)備驅(qū)動(dòng)程序的數(shù)據(jù),在計(jì)算機(jī)端的應(yīng)用軟件進(jìn)行各種操作。反之,計(jì)算機(jī)的控制命令通過USB總線接口,把控制命令通過USB芯片傳到單片機(jī),由于本系統(tǒng)已經(jīng)對(duì)計(jì)算機(jī)程序的命令編碼過,所以單片機(jī)接受來自上位機(jī)命令,對(duì)其進(jìn)行判斷,從而做出不同的響應(yīng)。
硬件電路整體實(shí)現(xiàn)電路圖在附件中給出。
5 系統(tǒng)軟件設(shè)計(jì)
本系統(tǒng)進(jìn)行軟件設(shè)計(jì)包括下位機(jī)軟件設(shè)計(jì)和上位機(jī)軟件設(shè)計(jì),下位機(jī)軟件設(shè)計(jì)可以使用匯編語言和單片機(jī)C語言,上位機(jī)設(shè)計(jì)可以采用的很多計(jì)算機(jī)高級(jí)語言,比如VC++、Delphi、C++ builder等,在這里選擇C++ builder來編寫上位機(jī)程序。至于下位機(jī)程序,主要有匯編語言、PL/M語言和C語言。匯編語言有執(zhí)行效率高、速度快、與硬件結(jié)合緊密等特點(diǎn),尤其在I/O端口管理時(shí),使用匯編語言有快捷、直觀的優(yōu)點(diǎn)。但是使用匯編語言相對(duì)于高級(jí)語言,比如單片機(jī)C語言來講,難度要大很多,而且匯編語言的呈現(xiàn)可讀性低、開放性差。所以下位機(jī)的程序設(shè)計(jì)選擇單片機(jī)C語言。下面簡(jiǎn)單介紹本次軟件設(shè)計(jì)的編程工具。
5.1 軟件設(shè)計(jì)開發(fā)工具
Keil C51是單片機(jī)的編寫軟件,是美國(guó)Keil Software公司出品的51系列兼容單片機(jī)C語言軟件開發(fā)系統(tǒng),與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢(shì),因而易學(xué)易用。用過匯編語言后再使用C來開發(fā),體會(huì)更加深刻。 Keil C51軟件提供豐富的庫函數(shù)和功能強(qiáng)大的集成開發(fā)調(diào)試工具,全Windows界面。另外重要的一點(diǎn),只要看一下編譯后生成的匯編代碼,就能體會(huì)到Keil C51生成的目標(biāo)代碼效率非常之高,多數(shù)語句生成的匯編代碼很緊湊,容易理解。在開發(fā)大型軟件時(shí)更能體現(xiàn)高級(jí)語言的優(yōu)勢(shì)。
C++ builder是Inprise公司1998 年推出的,面向?qū)ο蟮?2位Windows程序設(shè)計(jì)開放工具,C++ builder不僅繼承了Delphi使用簡(jiǎn)便、功能強(qiáng)大、效率高等特點(diǎn),而且它還結(jié)合了C++語言的所有優(yōu)點(diǎn)。 C++ builder可以說是至今為止功能最強(qiáng)、最簡(jiǎn)單易學(xué)的Windows開發(fā)工具之一。C++ builder 6具有非常友好的集成開發(fā)環(huán)境,提供一百多個(gè)VCL組件,使開發(fā)人員不需要太多的時(shí)間編碼,就能實(shí)現(xiàn)很多復(fù)雜的功能。它的編譯器 能夠自動(dòng)列出VCL組件的屬性和方法供程序員選擇,而不必手工輸入復(fù)雜的代碼。正式因?yàn)檫@些優(yōu)點(diǎn),所以本次系統(tǒng)設(shè)計(jì)選擇 C++ builder作為上位機(jī)軟件設(shè)計(jì)的開發(fā)工具。
5.2 系統(tǒng)軟件設(shè)計(jì)
系統(tǒng)要對(duì)溫度進(jìn)行采集,首先必須利用上位機(jī)對(duì)下位機(jī)(單片機(jī))發(fā)出命令,單片機(jī)根據(jù)接收到的命令,根據(jù)預(yù)先的規(guī)則對(duì)不同的命令做出不同的處理。然后把處理結(jié)果發(fā)回上位機(jī),上位機(jī)接收到溫度數(shù)據(jù)后,根據(jù)溫度數(shù)據(jù)畫出數(shù)據(jù)采集圖像。這就是系統(tǒng)要實(shí)現(xiàn)功能,根據(jù)這一要求,設(shè)計(jì)出系統(tǒng)的軟件。
系統(tǒng)整體模塊流程圖如圖5.1
圖5.1 系統(tǒng)整體模塊圖
下面分別設(shè)計(jì)下位機(jī)和上位機(jī)的程序流程圖。
5.2.1下位機(jī)的軟件設(shè)計(jì)
單片機(jī)端的應(yīng)用程序主要實(shí)現(xiàn)的功能就是對(duì)DS18B20進(jìn)行采集溫度,把采集到的溫度通過USB接口芯片上傳到計(jì)算機(jī)端的應(yīng)用程序。
下位機(jī)的程序設(shè)計(jì)流程圖5.2


圖5.2 下位機(jī)的程序設(shè)計(jì)流程圖
下位機(jī)的程序流程圖中包括單片機(jī)和DS18B20和單片機(jī)的通信流程圖,以及單片機(jī)和USB設(shè)備接口芯片的通信流程圖。
其中DS18B20和單片機(jī)的通信流程圖如下圖5.3
這里是單片機(jī)如何根據(jù)DS18B20的特性來控制它,進(jìn)行溫度轉(zhuǎn)換,并讀取溫度。把溫度數(shù)據(jù)保存在單片機(jī)端。

圖5.3 DS18B20的程序流程圖
單片機(jī)先初始化DS18B20溫度傳感器,對(duì)其復(fù)位,然后按DS18B20的時(shí)序來讀寫命令,DS18B20根據(jù)命令進(jìn)行操作,單片機(jī)和DS18B20的通信過程主要為:?jiǎn)纹瑱C(jī)對(duì)DS18B20復(fù)位,跳過讀寫系列號(hào)操作(送0xCC命令到DS18B20),啟動(dòng)溫度轉(zhuǎn)換,再次復(fù)位,送讀溫度命令0xBE,讀出溫度。這就是單片機(jī)和DS18B20的通信過程,將得到的溫度單片機(jī)在進(jìn)行處理,把溫度數(shù)據(jù)傳到上位機(jī)。上位機(jī)實(shí)時(shí)顯示溫度值。為了便于說明DS18B20和單片機(jī)間的通信過程,下面給出讀出DS18B20溫度的程序:
unsigned int readtemperature(void) //讀溫度
{ unit8 a=0,b=0;
unit8 c,d;
unsigned int t=0;
float tt=0;
c=DS18B20_RESET();
write_byte(0xCC); // 跳過讀序號(hào)列號(hào)的操作
write_byte(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
d=DS18B20_RESET();
write_byte(0xCC); //跳過讀序號(hào)列號(hào)的操作
write_byte(0xBE); //讀取溫度寄存器等前兩個(gè)就是溫度
a=read_byte();
b=read_byte();
t=b;
t<<=8;
t=t|a;
return(t); }
單片機(jī)讀出溫度后,接下來的工作就是單片機(jī)和CH372芯片的通信。CH372已經(jīng)屏蔽了USB通訊協(xié)議,所以只要知道CH372單片機(jī)之間的通信過程,就很方便的寫出它們的通信流程圖。圖5.4是CH372和89C51的程序流程圖。
(1)單片機(jī)向CH372上傳數(shù)據(jù) (2) 下載數(shù)據(jù)到單片機(jī)
圖5.4 單片機(jī)和CH372的通信流程圖
上傳數(shù)據(jù)是通過查詢DS18B2是否轉(zhuǎn)換完,轉(zhuǎn)換完,則上傳,否則等待;上位機(jī)的應(yīng)用軟件向下位機(jī)發(fā)送數(shù)據(jù),CH372的端點(diǎn)接受器接受來著來自計(jì)算機(jī)的數(shù)據(jù),通過中斷來通知單片機(jī),單片機(jī)開始接受收據(jù),并進(jìn)行處理。
5.2.2 上位機(jī)軟件設(shè)計(jì)
上位機(jī)接受來自下位機(jī)的數(shù)據(jù),根據(jù)數(shù)據(jù)進(jìn)行操作,實(shí)現(xiàn)各種功能。有一點(diǎn)必須要注意的是,要利用動(dòng)態(tài)連接庫的知識(shí),才能打開USB設(shè)備,從而進(jìn)行通信,所以在編寫應(yīng)用軟件前,一定要了解C++ builder 動(dòng)態(tài)連接庫的使用。由于CH372驅(qū)動(dòng)程序提供的動(dòng)態(tài)連接庫是用VC編寫的,C++ builder要建立起PC機(jī)和CH372的通信,必須要使用VC編寫的動(dòng)態(tài)連接庫,但C++ builder不能直接使用VC編寫的動(dòng)態(tài)連接庫。關(guān)于這點(diǎn),在調(diào)試部分將做更多說明,這里只介紹上位機(jī)軟件整體設(shè)計(jì)方面的內(nèi)容。
下面給出上位機(jī)的程序流程圖5.5:

圖5.5 上位機(jī)流程圖
這就是上位機(jī)軟件的設(shè)計(jì)思想,具體實(shí)現(xiàn)在程序中有將進(jìn)一步說明。
6 系統(tǒng)調(diào)試
前面幾章節(jié),已經(jīng)對(duì)整個(gè)系統(tǒng)進(jìn)行了設(shè)計(jì),可是對(duì)于硬件來說,這只是完成一部分的工作 ,硬件系統(tǒng)真正的挑戰(zhàn)在于調(diào)試,很多情況下,電路圖是在理論是正確的,可以實(shí)現(xiàn)的,可是真正的到了實(shí)際中,會(huì)出現(xiàn)很多情況,但不管怎么樣,重要的一點(diǎn)是結(jié)合設(shè)計(jì)理論知識(shí)來分析系統(tǒng),逐步調(diào)試系統(tǒng)。
6.1 硬件調(diào)試
系統(tǒng)硬件電路并不是很復(fù)雜,但調(diào)試中必需要注意以下幾點(diǎn),否則將會(huì)出現(xiàn)系統(tǒng)工作不穩(wěn)定情況,嚴(yán)重的話,將CH372芯片燒壞,這是電路特別需要的地方。下面給出硬件調(diào)式中碰到的問題,并提出如何解決。
(1)CH372的WR、RD、A0信號(hào)線是由單片機(jī)89C51的P0口提供的,P0口作為I/O口使用,必須要加上拉電阻,很多資料寫著加1K-10K的上拉電阻,但這對(duì)于本系統(tǒng)是不正確的。
實(shí)際上在本系統(tǒng)中P0口的上拉F范圍是30K-125K,最好選擇100K的上拉電阻。因?yàn)槿绻皇?0K,那么流入CH372的芯片的電流為500uA,遠(yuǎn)遠(yuǎn)超過了芯片規(guī)定的最高電流160uA,這樣肯定會(huì)燒壞芯片。所以這個(gè)上拉電阻的范圍是一定要根據(jù)芯片的參數(shù)來設(shè)計(jì),而不能從其他資料上說的選擇1K-10K。這點(diǎn)要特別注意。
(2)在CH372的濾波電容0.1uF中,并聯(lián)一個(gè)5K-10K的電阻。這樣的作用是系統(tǒng)在斷電時(shí),把電容中的電能及時(shí)的釋放掉,使VCC及時(shí)的下降到0V,確保電路下使用通電時(shí)CH372能夠可上電復(fù)位。
如果不加這個(gè)電阻,不少情況下,一旦下位機(jī)通電,芯片很久才顯示出來,上位機(jī)需要較久時(shí)間來確認(rèn)接口芯片,所以應(yīng)該加5K-10K的電阻,這是系統(tǒng)的一個(gè)改進(jìn)。
(3)共用晶振問題。USB接口芯片CH372和單片機(jī)都要需要晶振才能工作,但CH372的晶振必須是12M。單片機(jī)可以和CH372共用同一個(gè)晶振,但必需是12M。這樣的優(yōu)點(diǎn)是可以節(jié)約材料,但是不便于PCB排版,還有如果有芯片壞了,也不容易覺察出是不是CH372壞,還是單片機(jī)壞了,所以這里考慮單片機(jī)和CH372不能共用晶振。方便硬件調(diào)試。
(4)DS18B20的接法。DS18B20連接到單片機(jī)的接法很簡(jiǎn)單,這里提出需要注意的一點(diǎn)是,DS18B20用在P11做通信端口,但必須接4.7K的上拉電阻。P1口是I/O口用驅(qū)動(dòng)外部電路時(shí),一般都不用接上拉電阻的,但這里需要上拉電阻。這一點(diǎn)也就要注意。否則DS18B20工作不穩(wěn)定,有可能有干擾。
本次系統(tǒng)調(diào)試硬件主要出現(xiàn)的問題就是上面所提到的,只要根據(jù)理論來分析,綜合實(shí)際應(yīng)用,便可以做出正確的硬件,這樣為后期軟件調(diào)試減少很多麻煩,否則,后期軟件調(diào)試的時(shí)候,出現(xiàn)問題有可能是軟件問題,或者是硬件問題,混合起來處理會(huì)很不方便,需花很多時(shí)間。
6.2 軟件調(diào)試
本系統(tǒng)的軟件調(diào)試主要有下位機(jī)端的軟件調(diào)試和上位機(jī)端的軟件調(diào)試。
6.2.1 下位機(jī)的軟件調(diào)試
下位機(jī)的軟件調(diào)試主要分兩部分:?jiǎn)纹瑱C(jī)和CH372Z時(shí)間的通信、單片機(jī)與溫度傳感器DS18B20的通信。
(1)單片機(jī)和CH372之間的通信
這一部分是必須首先要調(diào)試出來的, 因?yàn)橐揽窟@一部分通過計(jì)算機(jī)才能顯示出單片機(jī)和溫度傳感器之間的通信。
硬件部分利用具有上拉電阻的P0口作為CH372的WR、RD、A0線,所以通過軟件控制P0口信號(hào)來達(dá)到控制CH372的讀寫命令和讀寫數(shù)據(jù)。只要注意CH372的讀寫時(shí)間要求就可以很快實(shí)現(xiàn)。單片機(jī)的P2口是作為CH372的數(shù)據(jù)口,利用它來發(fā)送和接受CH372的數(shù)據(jù)。
這里特別強(qiáng)調(diào)的一點(diǎn)是CH372的初始化程序,如果初始化不成功,電腦無法識(shí)別硬件,后期將無法進(jìn)行。所以初始化程序必須注意的一點(diǎn)。下面給出CH372的初始化程序。
#define VID 0x8888 //廠商ID
#difine PID 0x9999 //產(chǎn)品ID
CH372_Init() //初始化CH372
{ int i;
CH372_WR_CMD_PORT(CMD_SET_USB_ID); //設(shè)置USB設(shè)備VID和PID
CH372_WR_DATA_PORT(VID&0xff); //寫入廠商ID的低字節(jié)
CH372_WR_DATA_PORT(VID>>8); //寫入廠商ID的高字節(jié)
CH372_WR_DATA_PORT(PID&0xff); //寫入產(chǎn)品ID的低字節(jié)
CH372_WR_DATA_PORT(PID>>8); //寫入產(chǎn)品ID的高字節(jié)
CH372_WR_CMD_PORT(CMD_SET_USB_MODE); //設(shè)置CH372工作模式
CH372_WR_DATA_PORT(2);//工作模式2
for( i=200;i>0;i--) //20us時(shí)間復(fù)位
if (CH372_RD_DATA_PORT==CMD_RET_SUCCESS) //復(fù)位成功
break;
}
另外,CH372最大可以傳送64個(gè)字節(jié),每一個(gè)讀寫函數(shù)每一次操作的只能一個(gè)字節(jié),要讀寫多個(gè)字節(jié),這里使用的是循環(huán)的方法。
CH372初始化成功后,下位機(jī)連接到PC機(jī)上,安裝了CH372驅(qū)動(dòng)程序的PC機(jī)就可以識(shí)別硬件。完成這部分工作之后先進(jìn)入上為機(jī)和下位機(jī)聯(lián)合的調(diào)試,然后再調(diào)試DS18B20和DS18B20之間的通信。
(2)單片機(jī)和DS18B20之間的通信
單片機(jī)要根據(jù)DS18B20的時(shí)序要求和讀寫要求來讀取溫度數(shù)據(jù)。由于DS18B20是一線式數(shù)字溫度傳感器,對(duì)時(shí)序要求比較高,延時(shí)程序誤差大,則不能讀出數(shù)據(jù)。還有要按照訪問DS18B20的順序來操作。這里再次說明訪問DS18B20的順序如下:①初始化;②ROM命令;③DS18B20的函數(shù)命令。
總之,這部分編程主要注意的就是延時(shí)程序的準(zhǔn)確性。并按照DS18B20的操作順序便可以把溫度數(shù)字傳到單片機(jī)。
6.2.2 上位機(jī)的軟件調(diào)試
上位機(jī)的編程工具是C++ builder,主要是VCL控件的使用。主要有兩個(gè)模塊組成:通信模塊和圖像處理模塊。其中通信模塊負(fù)責(zé)處理上位機(jī)和下位機(jī)之間的通信,圖像處理模塊負(fù)責(zé)溫度采集圖像。
對(duì)于通信模塊,主要是調(diào)用CH372的動(dòng)態(tài)連接庫,但由于廠家的CH372動(dòng)態(tài)連接庫是使用Visual C++制作的,C++ builder 不能直接運(yùn)用,否則將會(huì)有出錯(cuò)信息。所以要經(jīng)過一定的處理。
處理這一問題主要有兩種方法:顯式連接法和使用C++Builder中提供的導(dǎo)入庫生成工具。由于顯示連接對(duì)于在系統(tǒng)中多次調(diào)用動(dòng)態(tài)連接庫的多個(gè)函數(shù)很不方便,這里選擇使用C++Builder中提供的導(dǎo)入庫生成工具。步驟如下:
(1)用C++Builder提供的implib.exe工具重新生成該動(dòng)態(tài)庫(xxx.dll)的導(dǎo)入庫(xxx.lib)。命令如下:
implib ch372.lib ch372.dll。
ch372.dll為已有動(dòng)態(tài)庫,ch372.lib為要生成的導(dǎo)入庫。由此生成的導(dǎo)入庫ch372.lib格式與C++Builder開發(fā)平臺(tái)是相容的;
(2)在動(dòng)態(tài)庫的頭文件ch372.h中,對(duì)其輸出函數(shù)重新說明,語句如下:
extern _stdcall HANDLE WINAPI CH375OpenDevice(
ULON GiIndex );// 指定CH372
設(shè)備序號(hào),0對(duì)應(yīng)第一個(gè)設(shè)備
(3)然后采用隱式鏈接法,將重新生成的導(dǎo)入庫(ch372.lib)和重新說明的頭文件(ch372.h)加入到C++Builder應(yīng)用程序的工程項(xiàng)目中,進(jìn)行編譯和連接。
對(duì)于圖像處理模塊,應(yīng)用軟件根據(jù)接受到的溫度,利用C++ builder在窗體上畫出動(dòng)態(tài)連接圖,主要采用窗體Canvas屬性來實(shí)現(xiàn)。
6.2.3 上位機(jī)和下位機(jī)聯(lián)機(jī)調(diào)試
下位機(jī)(單片機(jī))對(duì)CH372初始化成功之后,上位機(jī)就能夠識(shí)別下位機(jī)設(shè)備(USB設(shè)備),上位機(jī)調(diào)試部分也初步完成,那就進(jìn)入系統(tǒng)整體調(diào)試。
整體調(diào)試主要分三步:
(1)測(cè)試單片機(jī)和PC機(jī)能否正常通信;
這里利用的方法如下:在下位機(jī)的程序部分設(shè)計(jì)一個(gè)往上位機(jī)發(fā)送的字符數(shù)組,比如“1214”,然后在PC機(jī)上進(jìn)行操作,看是否能成功接受數(shù)組,如果能,則說明單片機(jī)可以往上位機(jī)發(fā)生數(shù)據(jù),不行則修改上位機(jī)和下位機(jī)相關(guān)部分的程序。接下來PC往下位機(jī)發(fā)送數(shù)據(jù),如果下位機(jī)能夠成功返回相同的數(shù)據(jù)到PC機(jī)上,則說明上為機(jī)和下位之間的通信已經(jīng)成功。
(2)測(cè)試單片機(jī)能否對(duì)DS18B20正常的讀取溫度;
完成上面一步才能進(jìn)行這一步調(diào)試,前面已經(jīng)提到,DS18B20的對(duì)時(shí)序要求很高,一定要準(zhǔn)確,并且按DS18B20的順序來進(jìn)行操作,在硬件電路原理沒有錯(cuò)的情況下,如果溫度讀起不正確,或者無法讀取溫度,只能是出現(xiàn)兩種錯(cuò)誤,一是時(shí)序問題,沒有按照DS18B20的時(shí)序精度來對(duì)其進(jìn)行操作,二是單片機(jī)訪問DS18B20的順序問題,單片機(jī)沒有嚴(yán)格按照訪問DS18B20的順序?qū)ζ鸢l(fā)送命令,單片機(jī)訪問DS18B20的順序這里再次聲明:初始化、ROM命令、DS18B20的函數(shù)命令。
這一部分出現(xiàn)的兩個(gè)問題,大部分情況下出現(xiàn)的是時(shí)序問題,所以特別注意單片機(jī)對(duì)于DS18B20的精確延時(shí)。
(3)采集溫度;
各部分通信正常后,便可以采集數(shù)據(jù)并處理。因?yàn)橄到y(tǒng)采集過程是上位機(jī)每發(fā)送一條采集命令,下位機(jī)就上傳一次溫度數(shù)據(jù),所以這一步主要調(diào)試的是上位機(jī)要間隔多長(zhǎng)時(shí)間定時(shí)向下位機(jī)發(fā)送采集命令,使系統(tǒng)能快速采集溫度并上傳,并防止發(fā)生讀寫等沖突。
6.3 系統(tǒng)性能指標(biāo)
系統(tǒng)性能指標(biāo)主要是:
(1)測(cè)量溫度誤差小于或者等于0.5℃;
(2)溫度顯示分辨率為0.0625℃;
(3)測(cè)量溫度范圍在0℃~70℃;
(4)具有控制報(bào)警功能。
7 系統(tǒng)的簡(jiǎn)單操作說明
若用戶使用本系統(tǒng),將可以對(duì)其進(jìn)行以下的簡(jiǎn)單操作:
(1)首先打開USB設(shè)備;在上位機(jī)軟件上打開USB設(shè)備,建立起上位機(jī)和下位機(jī)的通信機(jī)制。使用本系統(tǒng)都首先要打開USB設(shè)備。
(2)對(duì)計(jì)算機(jī)端的應(yīng)用軟件進(jìn)行溫度讀取操作,將立即得到該環(huán)境溫度的實(shí)時(shí)溫度;
(3)可以在上位機(jī)上輸入報(bào)警極限溫度,上位機(jī)把極限溫度發(fā)送到下位機(jī),并且保留在上位機(jī),一旦超過,則報(bào)警;
(4)上位機(jī)應(yīng)用軟件提供實(shí)時(shí)使用幫助功能。如果用戶不知道怎么樣使用軟件,則可以通過幫助,便能快速使用本系統(tǒng)軟件。
8 總結(jié)
在此次畢業(yè)設(shè)計(jì)的開發(fā)過程中,感覺C 語言(單片機(jī)C語言和C++)的熟練程度是項(xiàng)目開發(fā)的關(guān)鍵。許多問題其實(shí)原理上都是非常成熟的東西,從一些資料上都可以找到。在自己的題目中,要做的也就是將原理表述的溫度采集后傳到單片機(jī)。因此,開發(fā)工作本身沒有多少創(chuàng)造性,沒有多少高深的知識(shí),要具備的僅是對(duì)C 語言的熟練,以及學(xué)會(huì)解決遇到的問題。
做完這次畢業(yè)設(shè)計(jì)的另一個(gè)體會(huì)就是對(duì)于硬件的設(shè)計(jì)不能硬搬書上或者是相關(guān)材料上的。往往由于系統(tǒng)硬件體系不同,所以需要一定的變通,書和材料只能起到提示參考的作用。比如本系統(tǒng)單片機(jī)的上拉電阻,書上都說一般用的是1K-10K,可是實(shí)際在這個(gè)系統(tǒng)中是不適用的,如果用1K-10K,由于進(jìn)入CH372的電流段過大,這個(gè)沖擊電流會(huì)燒壞芯片。而關(guān)于芯片的參數(shù)很多情況下,設(shè)計(jì)人員并不在乎,所以往往只憑書上的知識(shí)來設(shè)計(jì)電路,忽略了細(xì)節(jié),這就是本次系統(tǒng)設(shè)計(jì)中存在的問題。
本系統(tǒng)設(shè)計(jì)采用的傳感器DS18B20對(duì)延時(shí)要求很高,往往在調(diào)試的過程中,溫度無法顯示,檢查硬件電路和軟件問題都沒有發(fā)現(xiàn)出問題,當(dāng)時(shí)首先要考慮的是溫度傳感器DS18B20芯片已經(jīng)壞了,經(jīng)過多次分析,覺得芯片才第一次使用,壞的可能性很小,而一線溫度傳感器對(duì)時(shí)序要求很高,所以溫度無法讀起,首先考慮到單片機(jī)無法正確按照DS18B20的時(shí)序讀取溫度。最后確實(shí)讀到了溫度數(shù)據(jù)。單片機(jī)的延時(shí)程序一般對(duì)系統(tǒng)來說,要求不是很精確,可是本次設(shè)計(jì)卻要求非常嚴(yán)格,這點(diǎn)必須注意。
之外,上位機(jī)應(yīng)用軟件的編寫工具是C++ builder , 國(guó)內(nèi)很多資料都是介紹的都是基本控件的使用,涉及到畫圖的資料比較少,特別是畫動(dòng)態(tài)圖象,本系統(tǒng)只能是另做窗體來畫出系統(tǒng)的溫度采集圖像。而且C ++的動(dòng)態(tài)連接問題并不是書上介紹的那樣,真正操作起來碰到了不少問題,連接錯(cuò)誤等等。
謝 辭
首先,我要感謝我的導(dǎo)師龍老師,在這次畢業(yè)設(shè)計(jì)的整個(gè)過程中,她給與我極大的幫助。
經(jīng)過這次畢業(yè)設(shè)計(jì),使我真正的運(yùn)用了大學(xué)里學(xué)到的很多理論知識(shí),應(yīng)用到實(shí)際系統(tǒng)的設(shè)計(jì)中,這次畢業(yè)設(shè)計(jì)可以說是一個(gè)實(shí)戰(zhàn),一個(gè)理論與實(shí)踐的有機(jī)結(jié)合,這次畢業(yè)設(shè)計(jì)歷程3個(gè)月,通過3個(gè)月的時(shí)間了,我不斷的學(xué)習(xí)新知識(shí),掌握新東西,并且即學(xué)即用,龍老師在這里畢業(yè)設(shè)計(jì)過程中就我碰到的問題給以正確有效的引導(dǎo),使我能夠順利的做完畢業(yè)時(shí)間,她治學(xué)嚴(yán)謹(jǐn)、知識(shí)淵博、態(tài)度熱情認(rèn)真,給我留下了深刻的印象,所以我在這里非常的感謝我的導(dǎo)師老老師,也感謝學(xué)校給以我這樣的一次鍛煉的機(jī)會(huì),感謝本次畢業(yè)設(shè)計(jì)中給以我?guī)椭乃械睦蠋煛⑼瑢W(xué)!
參考文獻(xiàn)
[1] 張培仁.基于C語言編程--MS-51單片機(jī)用力和應(yīng)用[M] .清華大學(xué)出版社 .2003.1
[2] 席衛(wèi)文.C++ builder 6程序設(shè)計(jì)與實(shí)例[M] .冶金工業(yè)出版社.2003.6
[3] 余明興.Borland C++ Builder 5 實(shí)例精講[M] . 清華大學(xué)出版社.2001.6
[4] 雷曉平.單片機(jī)及其應(yīng)用[M].電子可見大學(xué)出版社. 2003.3
[5] 陳啟美. 計(jì)算機(jī)USB接口技術(shù)[M] 南京大學(xué)出版社. 2003.1
[6] 徐科 楊朝霖.C++ builder實(shí)用技術(shù)與經(jīng)典案例[M].清華大學(xué)出版社. 2002.11
[7] 王成儒 李英偉.USB2.0原理與工程開發(fā)[M].國(guó)防工業(yè)出版社.2002.3
[8] 沙占友 葛家怡.集成化智能傳感器原理與應(yīng)用[M].電子工業(yè)出版社.2004.1
[9] 劉明業(yè).集成電路/計(jì)算機(jī)硬件描述語言VHDL高等教程[M].清華大學(xué)出版社.2003.6
[10] Universal Serial Bus Specification Revision 1.1. Compaq Computer Corporation,Intel
Corporation,Microsoft Corporation,NEC Corporation: September 23, 1998.
附 錄
1.protel原理圖

1PCB圖

2本系統(tǒng)部分程序
(1)下位機(jī)部分程序圖
#include <reg51.h>
#include <string.h>
#include "ch372.h"
#define uchar unsigned char
#define uint unsigned int
#define VID 0x8888
#define PID 0x9999
#define USBCMD_WR 100 //上傳數(shù)據(jù)
#define USBCMD_RD 101 //設(shè)置報(bào)警溫度
#define DS18B20 102 //檢測(cè)是否有溫度傳感器
#define CH375PORT P2
sbit CH375_WR=P0^5; //控制CH372的寫數(shù)據(jù)信號(hào)
sbit CH375_RD=P0^6; //控制CH372的讀數(shù)據(jù)信號(hào)
sbit CH375_A0=P0^7; //控制CH372的寫命令信號(hào)
data uchar buffer[64];
data uchar USBCMD;
bit UsbRecvOk;
sbit LED0=P1^1;
sbit LED1=P1^2;
sbit DQ=P1^0;
static float bwendu;
//DS18B20的程序
void delaym(uchar time) //延時(shí)為(time*2+3)us
{
for(;time>0;time--);
}
uchar read_byte(void)
{uchar i,value=0;
for(i=0;i<8;i++)
{value>>=1;
DQ=0; //將總線DQ拉低開始讀時(shí)序
DQ=1; //釋放DQ;
delaym(1);
if(DQ) value|=0x80;
delaym(6); //讀取時(shí)間間隙,要大于1us
}
return (value);
}
void write_byte(uchar value)
{ uchar i;
for(i=0;i<8;i++)
{DQ=0;
DQ=value&0x01; //每次寫1位,通過val右移得到
delaym(5); //延時(shí)34us(15~60us采樣時(shí)間)
DQ=1;
value>>=1;
}
delaym(5); //2次寫的時(shí)間間隙要大于1us
}
uchar DS18B20_RESET(void)
{uchar da;
DQ=0;
delaym(29); //保持DQ低480us
DQ=1;
delaym(3); //等待15~60us
da=DQ;
delaym(25);
return (da);//有芯片應(yīng)答da=0,無則da=1
}
unsigned int readtemperature(void) //讀溫度
{ uchar a=0,b=0; // c為溫度的小數(shù)部分?
unsigned int t=0;
DS18B20_RESET();
write_byte(0xCC); // 跳過讀序號(hào)列號(hào)的操作
write_byte(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
DS18B20_RESET();
write_byte(0xCC); //跳過讀序號(hào)列號(hào)的操作
write_byte(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
a=read_byte();
b=read_byte();
t=b;
t<<=8;
t=t|a;
return(t);
}
void Delayms(uint m)
{
uint i;
while(m-->0)
for (i=0; i<500; i++);
}
void CH375_CMD(uchar x) //向CH372寫命令
{
CH375_A0=1;
CH375PORT=x;
CH375_WR=0;
CH375_WR=1;
}
void CH375_DAT_WR(uchar x) //向CH372寫數(shù)據(jù)
{
CH375_A0=0;
CH375PORT=x;
CH375_WR=0;
CH375_WR=1;
}
uchar CH375_DAT_RD() //從CH372讀數(shù)據(jù)
{
uchar x;
CH375_A0=0;
CH375PORT=0xff;
CH375_RD=0;
x=CH375PORT;
CH375_RD=1;
return x;
}
void CH375_Init( ) //CH372初始化
{
CH375_CMD(CMD_SET_USB_ID); //寫 VID和PID
CH375_DAT_WR(VID&0xff);
CH375_DAT_WR(VID>>8);
CH375_DAT_WR(PID&0xff);
CH375_DAT_WR(PID>>8);
CH375_CMD(CMD_SET_USB_MODE);
CH375_DAT_WR(2);
}
void LoadUpData( uchar data *Buf, uchar Len ) //上傳數(shù)據(jù)
{
uchar i;
CH375_CMD(CMD_WR_USB_DATA7);
CH375_DAT_WR(Len);
for ( i=0; i<Len; i++ )
CH375_DAT_WR(Buf[i]); /* 加載數(shù)據(jù) */
}
void CH375Interrupt( ) interrupt 0 using 1
{
unsigned char Status;
unsigned char length, i;
EX0 = 0;
CH375_CMD(CMD_GET_STATUS);
Status = CH375_DAT_RD();
switch(Status)
{
case USB_INT_EP2_OUT: /* 批量端點(diǎn)下傳成功 */
CH375_CMD(CMD_RD_USB_DATA);
length = CH375_DAT_RD();
if(length>64) length=64;
for(i=0; i<length; i++)
buffer[i] = CH375_DAT_RD();
LED1=0;
UsbRecvOk=1;
USBCMD=buffer[0];
break;
case USB_INT_EP2_IN:
LED1=0;
CH375_CMD(CMD_UNLOCK_USB);
break;
case USB_INT_EP1_IN:
CH375_CMD(CMD_UNLOCK_USB);
break;
}
EX0 = 1;
}
void main( )
{ uint wendu;
float tt;
uchar a,b;
uchar reset; //DS18B20復(fù)位成功
uint k;
EA=1; EX0 = 1;
CH375_CMD(CMD_RESET_ALL);
Delayms(50);
CH375_Init();
UsbRecvOk=0;
LED0=1;
LED1=0;
while(1)
{ k++;
if(UsbRecvOk)
{
UsbRecvOk=0;
switch(USBCMD)
{
case USBCMD_RD:
wendu=readtemperature(); //讀溫度
b=wendu&0x0f;
a=(wendu>>4)&0xff;
buffer[0]=a; //溫度整數(shù)部分
buffer[1]=b; //溫度小數(shù)部分
LoadUpData(buffer,3); //上傳溫度
tt=a+b*0.0625;
break;
case USBCMD_WR: //設(shè)置報(bào)警溫度
bwendu=buffer[1]+buffer[2]*0.1;
break;
case DS18B20 : //檢測(cè)有無溫度傳感器
reset=DS18B20_RESET();
buffer[0]=reset;
LoadUpData(buffer,3);
}
}
if(tt>=bwendu)
LED0=0;
else
LED0=1;
}
}
(2)上位機(jī)部分程序:
//----------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//----------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//----------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TButton *Button3;
TEdit *Edit1;
TEdit *Edit2;
TButton *Button4;
TLabel *Label1;
TLabel *Label2;
TShape *Shape1;
TShape *Shape2;
TShape *Shape3;
TButton *Button5;
TTimer *Timer1;
TTimer *Timer2;
TShape *Shape4;
TLabel *Label3;
TLabel *Label4;
TLabel *Label5;
TLabel *Label6;
TLabel *Label7;
TLabel *Label8;
TLabel *Label9;
TLabel *Label10;
void __fastcall Button4Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button5Click(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
ULONG index ;
float baojing; //存放設(shè)置的報(bào)警溫度
unsigned char sent[64],jieshou[64];
unsigned long length;
unsigned int image[64];
unsigned int x1,y1; //坐標(biāo)
};
//----------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//----------------------------------------------------------------------
#endif
//----------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "CH375DLL.H"
//----------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//----------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{ Form1->Timer1->Enabled=false; //關(guān)定時(shí)器
Form1->Timer2->Enabled=false;
baojing=50;
}
//----------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Form1->Close(); //關(guān)閉窗口
CH375CloseDevice(0);//關(guān)閉CH372
}
//----------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{ length=64;
if(LoadLibrary("CH375DLL.DLL")==NULL)
ShowMessage("無法加載DLL文件");
if ( CH375OpenDevice(0) == INVALID_HANDLE_VALUE )
ShowMessage("無法打開CH372") ;
else
ShowMessage("成功打開CH372");
sent[0]=102;
CH375WriteData(0,&sent,&length); //發(fā)送檢測(cè)溫度傳感器的命令
CH375ReadData(0,&jieshou,&length); //接受收據(jù)
if(jieshou[0])
ShowMessage("無法檢測(cè)到溫度傳感器");
Form1->Timer1->Enabled=false;
Form1->Label9->Canvas->Pen->Width=6; //畫系統(tǒng)坐標(biāo)軸
Form1->Label9->Canvas->MoveTo(0,0); Form1->Label9->Canvas->LineTo(0,270);
Form1->Label9->Canvas->MoveTo(0,270); Form1->Label9->Canvas->LineTo(350,270);
Form1->Label9->Canvas->Pen->Width=1;
Form1->Label9->Canvas->Pen->Style=psDashDotDot;
Form1->Label9->Canvas->MoveTo(0,220); Form1->Label9->Canvas->LineTo(350,220);
Form1->Label9->Canvas->MoveTo(0,170); Form1->Label9->Canvas->LineTo(350,170);
Form1->Label9->Canvas->MoveTo(0,120); Form1->Label9->Canvas->LineTo(350,120);
Form1->Label9->Canvas->MoveTo(0,70);
Form1->Label9->Canvas->LineTo(350,70);
Form1->Label9->Canvas->MoveTo(0,20); Form1->Label9->Canvas->LineTo(350,20);
x1=0;
y1=30;
}
//----------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Form1->Timer1->Enabled=true;
}
//----------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{ float j;
unsigned int t1,t2;
unsigned long length=64;
unsigned char value,i;
unsigned char n,m;
i=StrToInt(Edit1->GetTextLen());
if(i==0)
ShowMessage("請(qǐng)輸入數(shù)據(jù)");
else
j=StrToFloat(Edit1->Text);
if(j>50)
value=Application->MessageBox(" 你設(shè)置的報(bào)警溫度已經(jīng)超過上限溫度:50", "information", 5);
switch(value)
{ case 4: Edit1->Text=InputBox("溫度","請(qǐng)輸入報(bào)警溫度","");
break;
case 2: break;
}
j=StrToFloat(Edit1->Text);
baojing=j;
t1=(int)(j);
t2=(int)(j*10);
m=(char) t1; //整數(shù)部分
n=(char)(t2%10); //小數(shù)部分
sent[0]=101;
sent[1]=m;
sent[2]=n;
if(CH375WriteData(0,&sent,&length))
Form1->Shape1->Brush->Color=clTeal; //下傳成功
else ShowMessage("無法設(shè)置報(bào)警溫度");
}
//----------------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
Form1->Timer1->Enabled=false; //打開定時(shí)器
}
//----------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
unsigned char a,b,c,i;// a為溫度整數(shù)部分,b為溫度小數(shù)部分
unsigned long len=64;
float wendu;
sent[0]=101;
CH375WriteData(0,&sent,&len) ;
if(CH375ReadData(0,&jieshou,&len))
{ a=jieshou[0]; //a溫度的整數(shù)部分
b=jieshou[1]; //b為小數(shù)部分
wendu=(float)(a+b*0.0625);
Edit2->Text=FloatToStr(wendu);
Form1->Shape2->Brush->Color=clRed;
if(wendu>=baojing)
Form1->Shape4->Brush->Color=clRed;
else
Form1->Shape4->Brush->Color=clWhite;
if(c>0.5)
a=a+1; //四舍五入;
Form1->Label9->Canvas->Pen->Width=2; //畫動(dòng)態(tài)圖象
Form1->Label9->Canvas->Pen->Color=clRed;
Form1->Label9->Canvas->MoveTo(x1,270-y1*5);
Form1->Label9->Canvas->LineTo(x1+10,270-a*5);
y1=a;
x1=x1+10;
if(x1>350)
{ Form1->Label9->Refresh();
x1=0,y1=30;
Form1->Label9->Canvas->Pen->Color=clBlack; //重新畫坐標(biāo)
Form1->Label9->Canvas->Pen->Width=6;
Form1->Label9->Canvas->MoveTo(0,0); Form1->Label9->Canvas->LineTo(0,270);
Form1->Label9->Canvas->MoveTo(0,270); Form1->Label9->Canvas->LineTo(350,270);
Form1->Label9->Canvas->Pen->Width=1;
Form1->Label9->Canvas->Pen->Style=psDashDotDot;
Form1->Label9->Canvas->MoveTo(0,220); Form1->Label9->Canvas->LineTo(350,220);
Form1->Label9->Canvas->MoveTo(0,170); Form1->Label9->Canvas->LineTo(350,170);
Form1->Label9->Canvas->MoveTo(0,120); Form1->Label9->Canvas->LineTo(350,120);
Form1->Label9->Canvas->MoveTo(0,70); Form1->Label9->Canvas->LineTo(350,70);
Form1->Label9->Canvas->MoveTo(0,20); Form1->Label9->Canvas->LineTo(350,20);}
}
else
{Form1->Timer1->Enabled=false;
ShowMessage("接收不成功"); }
}
//----------------------------------------------------------------------
3上位機(jī)應(yīng)用軟件
