A. 基於單片機的溫度控制系統設計
第一章 緒論 1. 1 選題背景 防潮、防霉、防腐、防爆是倉庫日常工作的重要內容,是衡量倉庫管理質量的重要指標。它直接影響到儲備物資的使用壽命和工作可靠性。為保證日常工作的順利進行,首要問題是加強倉庫內溫度與濕度的監測工作。但傳統的方法是用與濕度表、毛發濕度表、雙金屬式測量計和濕度試紙等測試器材,通過人工進行檢測,對不符合溫度和濕度要求的庫房進行通風、去濕和降溫等工作。這種人工測試方法費時費力、效率低,且測試的溫度及濕度誤差大,隨機性大。因此我們需要一種造價低廉、使用方便且測量准確的溫濕度測量儀。1.2 設計過程及工藝要求 一、基本功能~ 檢測溫度、濕度~ 顯示溫度、濕度~ 過限報警 二、主要技術參數 ~ 溫度檢測范圍 : -30℃-+50℃~ 測量精度 : 0.5℃~ 濕度檢測范圍 : 10%-100%RH~ 檢測精度 : 1%RH~ 顯示方式 : 溫度:四位顯示 濕度:四位顯示~ 報警方式 : 三極體驅動的蜂鳴音報警 第二章 方案的比較和論證 當將單片機用作測控系統時,系統總要有被測信號懂得輸入通道,由計算機拾取必要的輸入信息。對於測量系統而言,如何准確獲得被測信號是其核心任務;而對測控系統來講,對被控對象狀態的測試和對控制條件的監察也是不可缺少的環節。感測器是實現測量與控制的首要環節,是測控系統的關鍵部件,如果沒有感測器對原始被測信號進行准確可靠的捕捉和轉換,一切准確的測量和控制都將無法實現。工業生產過程的自動化測量和控制,幾乎主要依靠各種感測器來檢測和控制生產過程中的各種參量,使設備和系統正常運行在最佳狀態,從而保證生產的高效率和高質量。2. 1溫度感測器的選擇 方案一:採用熱電阻溫度感測器。熱電阻是利用導體的電阻隨溫度變化的特性製成的測溫元件。現應用較多的有鉑、銅、鎳等熱電阻。其主要的特點為精度高、測量范圍大、便於遠距離測量。鉑的物理、化學性能極穩定,耐氧化能力強,易提純,復制性好,工業性好,電阻率較高,因此,鉑電阻用於工業檢測中高精密測溫和溫度標准。缺點是價格貴,溫度系數小,受到磁場影響大,在還原介質中易被玷污變脆。按IEC標准測溫范圍-200~650℃,網路電阻比W(100)=1.3850時,R0為100Ω和10Ω,其允許的測量誤差A級為±(0.15℃+0.002 |t|),B級為±(0.3℃+0.005 |t|)。銅電阻的溫度系數比鉑電阻大,價格低,也易於提純和加工;但其電阻率小,在腐蝕性介質中使用穩定性差。在工業中用於-50~180℃測溫。 方案二:採用AD590,它的測溫范圍在-55℃~+150℃之間,而且精度高。M檔在測溫范圍內非線形誤差為±0.3℃。AD590可以承受44V正向電壓和20V反向電壓,因而器件反接也不會損壞。使用可靠。它只需直流電源就能工作,而且,無需進行線性校正,所以使用也非常方便,借口也很簡單。作為電流輸出型感測器的一個特點是,和電壓輸出型相比,它有很強的抗外界干擾能力。AD590的測量信號可遠傳百餘米。綜合比較方案一與方案二,方案二更為適合於本設計系統對於溫度感測器的選擇。 2. 2 濕度感測器的選擇 測量空氣濕度的方式很多,其原理是根據某種物質從其周圍的空氣吸收水分後引起的物理或化學性質的變化,間接地獲得該物質的吸水量及周圍空氣的濕度。電容式、電阻式和濕漲式濕敏原件分別是根據其高分子材料吸濕後的介電常數、電阻率和體積隨之發生變化而進行濕度測量的。方案一:採用HOS-201濕敏感測器。HOS-201濕敏感測器為高濕度開關感測器,它的工作電壓為交流1V以下,頻率為50HZ~1KHZ,測量濕度范圍為0~100%RH,工作溫度范圍為0~50℃,阻抗在75%RH(25℃)時為1MΩ。這種感測器原是用於開關的感測器,不能在寬頻帶范圍內檢測濕度,因此,主要用於判斷規定值以上或以下的濕度電平。然而,這種感測器只限於一定范圍內使用時具有良好的線性,可有效地利用其線性特性。方案二:採用HS1100/HS1101濕度感測器。HS1100/HS1101電容感測器,在電路構成中等效於一個電容器件,其電容量隨著所測空氣濕度的增大而增大。不需校準的完全互換性,高可靠性和長期穩定性,快速響應時間,專利設計的固態聚合物結構,由頂端接觸(HS1100)和側面接觸(HS1101)兩種封裝產品,適用於線性電壓輸出和頻率輸出兩種電路,適宜於製造流水線上的自動插件和自動裝配過程等。相對濕度在1%---100%RH范圍內;電容量由16pF變到200pF,其誤差不大於±2%RH;響應時間小於5S;溫度系數為0.04 pF/℃。可見精度是較高的。綜合比較方案一與方案二,方案一雖然滿足精度及測量濕度范圍的要求,但其只限於一定范圍內使用時具有良好的線性,可有效地利用其線性特性。而且還不具備在本設計系統中對溫度-30~50℃的要求,因此,我們選擇方案二來作為本設計的濕度感測器。2. 3 信號採集通道的選擇 在本設計系統中,溫度輸入信號為8路的模擬信號,這就需要多通道結構。方案一、採用多路並行模擬量輸入通道。這種結構的模擬量通道特點為:(1) 可以根據各輸入量測量的餓要求選擇不同性能檔次的器件。總體成本可以作得較低。(2) 硬體復雜,故障率高。(3) 軟體簡單,各通道可以獨立編程。方案二、採用多路分時的模擬量輸入通道。 這種結構的模擬量通道特點為:(1) 對ADC、S/H要求高。(2) 處理速度慢。(3) 硬體簡單,成本低。(4) 軟體比較復雜。綜合比較方案一與方案二,方案二更為適合於本設計系統對於模擬量輸入的要求,比較其框圖,方案二更具備硬體簡單的突出優點,所以選擇方案二作為信號的輸入通道。本文來源於: http://www.waibaowang.net/dianzi/
B. 基於單片機的溫度控制系統的設計
利用溫度感測器DS18B20檢測環境溫度並直接輸出數字溫度信號給單片機AT89C52進行處理。
在LCD液晶上顯示當前環境溫度值、預設溫度值、使用者設定的溫度差以及目前風扇所處的檔位。其中預設溫度值只能為整數形式,檢測到的當前環境溫度可精確到小數點後一位。
同時採用PWM脈寬調制方式來改變直流風扇電機的轉速。
並通過兩個按鍵改變預設溫度值,一個提高預設溫度,另一個降低預設溫度值。通過另一個按鍵控制溫度差的大小。
設有紅外熱釋感測器檢測環境范圍內是否有人,如果有人確定出風方向,如果無人,降低轉速或一定時間內自動關閉。
回答
正如你所說的,一共用了DS18B20模塊,LCD模塊,紅外感測模塊,按鍵,直流電機模塊,程序方面只有一個PWM。現在一一為你分析:
DS18B20模塊:
下圖是它的原理圖,採用單匯流排來進行開發,不像電賽的哪個溫度感測器需要AD轉換,它是可以直接傳出數字信號的。
C. 用單片機430做 溫度測量系統設計
單片機430做 溫度測量系統設計
同學,你好 學哥之前做過的,可以給你參考
D. 基於單片機的熱水器溫度控制系統
東華理工大學畢業設計(論文)
基於單片機的熱水器溫度控制
摘 要
溫度是日常生活中不可缺少的物理量,溫度在各個領域都有積極的意義。很多行業中以及日常生活中都有大量的用電加熱設備,如用於加熱處理的加熱熱水器,用於洗浴的電熱水器及各種不同用途的溫度箱等,採用單片機對它們進行控制具有控制方便、簡單、靈活性大等特點,而且還可以大幅提高被控系統的性能,從而能被大大提高產品的質量。因此,智能化溫度控制技術正被廣泛地應用。
本溫度設計採用現在流行的AT89C51單片機為控制器,用PID控制方法,再配以其他電路對熱水器的水溫進行控制。
關鍵詞:89C51; PID; 溫度控制
I
1/41頁
東華理工大學畢業設計(論文)
ABSTRACT
Temperature is essential physical in daily life ,and in various fields has positive implications.A lot of businesses and daily lives have a lot of electric heating equipment.Such as electric water heater for bathing and variety of different uses of the temperature boxes. MCU to control them with easy to control,simple,flexibility and other characteristics,also can significantly improve the performance of the controlled system,which can be greatly improved proct quality. Therefore,intelligent temperature control technology is being widely used.
The temperature control design uses the now popular AT89C51 MCU controller,with PID control method, which together with
E. 用單片機做溫度檢測系統 論文,
用DS18B20做的電子溫度計,非常簡單。
#include <reg51.h>
#include\"AscLed.h\"
#include <intrins.h>
#include <stdio.h>
//********************************************************
#define Seck (500/TK) //1秒中的主程序的系數
#define OffLed (Seck*5*60) //自動關機的時間5分鍾!
//********************************************************
#if (FHz==0)
#define NOP_2uS_nop_()
#else
#define NOP_2uS_nop_();_nop_()
#endif
//**************************************
#define SkipK 0xcc //跳過命令
#define ConvertK 0x44 //轉化命令
#define RdDs18b20K 0xbe //讀溫度命令
//*******************************************
extern LedOut(void);
//*************************************************
sbit PNP1=P3^4;
sbit PNP2=P3^5;
sbit BEEP=P3^2;
//***********************************
#defineDQ PNP2 //原來的PNP2 BEEP
//***********************************
static unsigned char Power=0;
//************************************
union{
unsigned char Temp[2]; //單位元組溫度
unsigned int Tt; //2位元組溫度
}T;
//***********************************************
typedef struct{
unsigned char Flag; //正數標志 0;1==》負數
unsigned char WenDu; //溫度整數
unsigned int WenDuDot; //溫度小數放大了10000
}WENDU;
//***********************************************
WENDU WenDu;
unsigned char LedBuf[3];
//----------------------------------
//功能:10us 級別延時
// n=1===> 6Mhz=14uS 12MHz=7uS
//----------------------------------
void Delay10us(unsigned char n){
do{
#if (FHz==1)
NOP_2uS;NOP_2uS;
#endif
}while(--n);
}
//-----------------------------------
//功能:寫18B20
//-----------------------------------
void Write_18B20(unsigned char n){
unsigned char i;
for(i=0;i<8;i++){
DQ=0;
Delay10us(1);//延時13us 左右
DQ=n & 0x01;
n=n>>1;
Delay10us(5);//延時50us 以上
DQ=1;
}
}
//------------------------------------
//功能:讀取18B20
//------------------------------------
unsigned char Read_18B20(void){
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++){
temp=temp>>1;
DQ=0;
NOP_2uS;//延時1us
DQ=1;
NOP_2uS;NOP_2uS;//延時5us
if(DQ==0){
temp=temp&0x7F;
}else{
temp=temp|0x80;
}
Delay10us(5);//延時40us
DQ=1;
}
return temp;
}
//-----------------------------------
void Init (void){
DQ=0;
Delay10us(45);//延時500us
DQ=1;
Delay10us(9);//延時90us
if(DQ){ //0001 1111b=1f
Power =0; //失敗0
}else{
Power++;
DQ=1;
}
}
//----------------------------------
void Skip(void){
Write_18B20(SkipK);
Power++;
}
//----------------------------------
void Convert (void){
Write_18B20(ConvertK);
Power++;
}
//______________________________________
void Get_Ds18b20L (void){
T.Temp[1]=Read_18B20(); //讀低位
Power++;
}
//______________________________________
void Get_Ds18b20H (void){
T.Temp[0]=Read_18B20(); //讀高位
Power++;
}
//------------------------------------
//規范化成浮點數
// sssss111;11110000
// sssss111;1111(0.5,0.25,0.125,0.0625)
//------------------------------------
void ReadTemp (void){
unsigned char i;
unsigned intF1=0;
char j=1;
code int Code_F[]={6250,1250,2500,5000};
WenDu.Flag=0;
if (T.Temp[0] >0x80){ //負溫度
T.Tt =~T.Tt+1; //取反+1=源嗎 +符號S
WenDu.Flag=-1;
}
T.Tt <<= 4; //左移4位
WenDu.WenDu=T.Temp[0]; // 溫度整數
//**************************************************
T.Temp[1]>>=4;
//---------------------------
for (i=0;i<4;i++){ //計算小數位
F1 +=(T.Temp[1] & 0x01)*Code_F;
T.Temp[1]>>=1;
}
WenDu.WenDuDot=F1; //溫度的小數
Power=0;
}
//----------------------------------
void Delay1S (void){
static unsigned int i=0;
if (++i==Seck) {i=0ower++;}
}
//----------------------------------
void ReadDo (void){
Write_18B20(RdDs18b20K);
Power++;
}
/**********************************
函數指針定義
***********************************/
code void (code *SubTemp[])()={
Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L,
Get_Ds18b20H,ReadTemp
};
//**************************************
void GetTemp(void){
(*SubTemp[Power])();
}
//---------------------------------------------------
//將溫度顯示,小數點放大了10000.
void GetBcd(void){
LedBuf[0]=WenDu.WenDu / 10;
LedBuf[1]=WenDu.WenDu % 10 +DotK;
LedBuf[2]=(WenDu.WenDuDot/1000)%10;
if(LedBuf[0]==0)LedBuf[0]=Black;
if(WenDu.Flag==0) return;
if(LedBuf[0] !=Black){
LedBuf[2]=LedBuf[1];
LedBuf[1]=LedBuf[0];
LedBuf[0]=Led_Pol; //'-'
}else{
LedBuf[0]=Led_Pol; //'-'
}
}
/*
//---------------------------------------------------
void JbDelay (void){
static long i;
if (++i>=OffLed){
P1=0xff;
P2=0xff;
PCON=0x02;
}
}
*/
/*****************************************************
主程序開始
1:2002_10_1 設計,採用DS18B20測量
2:採用函數數組讀取DS18B20.LED數碼管顯示正常!
3:改變FHz可以用6,12MHz工作!
******************************************************/
code unsigned char Stop[3] _at_ 0x3b;
void main (void){
P1=0xff;
WenDu.WenDu=0;
while (1){
GetTemp();
GetBcd();
// JbDelay();
LedOut();
}
}
復制代碼
20091012_[1].jpg (12 KB)
2009-10-21 23:21 上傳
下載次數:0
F. 基於單片機的溫濕度檢測系統設計
<<pic單片機應用系統開發典型實例〉〉有差不多的例子,不過 是數碼顯示,不是液晶顯示。液晶程序上網上找就行啊,www.pic16.com上有很多程序,或許有現成的。
G. 高分求單片機溫度採集系統的課程設計
DS18B20數字溫度計使用
1.DS18B20基本知識
DS18B20數字溫度計是DALLAS公司生產的1-Wire,即單匯流排器件,具有線路簡單,體積小的特點。因此用它來組成一個測溫系統,具有線路簡單,在一根通信線,可以掛很多這樣的數字溫度計,十分方便。
1、DS18B20產品的特點
(1)、只要求一個埠即可實現通信。
(2)、在DS18B20中的每個器件上都有獨一無二的序列號。
(3)、實際應用中不需要外部任何元器件即可實現測溫。
(4)、測量溫度范圍在-55。C到+125。C之間。
(5)、數字溫度計的解析度用戶可以從9位到12位選擇。
(6)、內部有溫度上、下限告警設置。
2、DS18B20的引腳介紹
TO-92封裝的DS18B20的引腳排列見圖1,其引腳功能描述見表1。
(底視圖)圖1
表1 DS18B20詳細引腳功能描述 序號
名稱
引腳功能描述
1
GND
地信號
2
DQ
數據輸入/輸出引腳。開漏單匯流排介面引腳。當被用著在寄生電源下,也可以向器件提供電源。
3
VDD
可選擇的VDD引腳。當工作於寄生電源時,此引腳必須接地。
3. DS18B20的使用方法
由於DS18B20採用的是1-Wire匯流排協議方式,即在一根數據線實現數據的雙向傳輸,而對AT89S51單片機來說,硬體上並不支持單匯流排協議,因此,我們必須採用軟體的方法來模擬單匯流排的協議時序來完成對DS18B20晶元的訪問。
由於DS18B20是在一根I/O線上讀寫數據,因此,對讀寫的數據位有著嚴格的時序要求。DS18B20有嚴格的通信協議來保證各位數據傳輸的正確性和完整性。該協議定義了幾種信號的時序:初始化時序、讀時序、寫時序。所有時序都是將主機作為主設備,單匯流排器件作為從設備。而每一次命令和數據的傳輸都是從主機主動啟動寫時序開始,如果要求單匯流排器件回送數據,在進行寫命令後,主機需啟動讀時序完成數據接收。數據和命令的傳輸都是低位在先。
DS18B20的復位時序
DS18B20的讀時序
對於DS18B20的讀時序分為讀0時序和讀1時序兩個過程。
對於DS18B20的讀時隙是從主機把單匯流排拉低之後,在15秒之內就得釋放單匯流排,以讓DS18B20把數據傳輸到單匯流排上。DS18B20在完成一個讀時序過程,至少需要60us才能完成。
DS18B20的寫時序
對於DS18B20的寫時序仍然分為寫0時序和寫1時序兩個過程。
對於DS18B20寫0時序和寫1時序的要求不同,當要寫0時序時,單匯流排要被拉低至少60us,保證DS18B20能夠在15us到45us之間能夠正確地采樣IO匯流排上的「0」電平,當要寫1時序時,單匯流排被拉低之後,在15us之內就得釋放單匯流排。
4. 實驗任務
用一片DS18B20構成測溫系統,測量的溫度精度達到0.1度,測量的溫度的范圍在-20度到+100度之間,用8位數碼管顯示出來。
5. 電路原理圖
6. 系統板上硬體連線
(1). 把「單片機系統」區域中的P0.0-P0.7用8芯排線連接到「動態數碼顯示」區域中的ABCDEFGH端子上。
(2). 把「單片機系統」區域中的P2.0-P2.7用8芯排線連接到「動態數碼顯示」區域中的S1S2S3S4S5S6S7S8端子上。
(3). 把DS18B20晶元插入「四路單匯流排」區域中的任一個插座中,注意電源與地信號不要接反。
(4). 把「四路單匯流排」區域中的對應的DQ端子連接到「單片機系統」區域中的P3.7/RD端子上。
7. C語言源程序
#i nclude <AT89X52.H>
#i nclude <INTRINS.h>
unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00,0x40};
unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,
25,28,31,34,38,41,44,48,
50,53,56,59,63,66,69,72,
75,78,81,84,88,91,94,97};
unsigned char displaycount;
unsigned char displaybuf[8]={16,16,16,16,16,16,16,16};
unsigned char timecount;
unsigned char readdata[8];
sbit DQ=P3^7;
bit sflag;
bit resetpulse(void)
{
unsigned char i;
DQ=0;
for(i=255;i>0;i--);
DQ=1;
for(i=60;i>0;i--);
return(DQ);
for(i=200;i>0;i--);
}
void writecommandtods18b20(unsigned char command)
{
unsigned char i;
unsigned char j;
for(i=0;i<8;i++)
{
if((command & 0x01)==0)
{
DQ=0;
for(j=35;j>0;j--);
DQ=1;
}
else
{
DQ=0;
for(j=2;j>0;j--);
DQ=1;
for(j=33;j>0;j--);
}
command=_cror_(command,1);
}
}
unsigned char readdatafromds18b20(void)
{
unsigned char i;
unsigned char j;
unsigned char temp;
temp=0;
for(i=0;i<8;i++)
{
temp=_cror_(temp,1);
DQ=0;
_nop_();
_nop_();
DQ=1;
for(j=10;j>0;j--);
if(DQ==1)
{
temp=temp | 0x80;
}
else
{
temp=temp | 0x00;
}
for(j=200;j>0;j--);
}
return(temp);
}
void main(void)
{
TMOD=0x01;
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
ET0=1;
EA=1;
while(resetpulse());
writecommandtods18b20(0xcc);
writecommandtods18b20(0x44);
TR0=1;
while(1)
{
;
}
}
void t0(void) interrupt 1 using 0
{
unsigned char x;
unsigned int result;
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
if(displaycount==2)
{
P0=displaycode[displaybuf[displaycount]] | 0x80;
}
else
{
P0=displaycode[displaybuf[displaycount]];
}
P2=displaybit[displaycount];
displaycount++;
if(displaycount==8)
{
displaycount=0;
}
timecount++;
if(timecount==150)
{
timecount=0;
while(resetpulse());
writecommandtods18b20(0xcc);
writecommandtods18b20(0xbe);
readdata[0]=readdatafromds18b20();
readdata[1]=readdatafromds18b20();
for(x=0;x<8;x++)
{
displaybuf[x]=16;
}
sflag=0;
if((readdata[1] & 0xf8)!=0x00)
{
sflag=1;
readdata[1]=~readdata[1];
readdata[0]=~readdata[0];
result=readdata[0]+1;
readdata[0]=result;
if(result>255)
{
readdata[1]++;
}
}
readdata[1]=readdata[1]<<4;
readdata[1]=readdata[1] & 0x70;
x=readdata[0];
x=x>>4;
x=x & 0x0f;
readdata[1]=readdata[1] | x;
x=2;
result=readdata[1];
while(result/10)
{
displaybuf[x]=result%10;
result=result/10;
x++;
}
displaybuf[x]=result;
if(sflag==1)
{
displaybuf[x+1]=17;
}
x=readdata[0] & 0x0f;
x=x<<1;
displaybuf[0]=(dotcode[x])%10;
displaybuf[1]=(dotcode[x])/10;
while(resetpulse());
writecommandtods18b20(0xcc);
writecommandtods18b20(0x44);
}
}
關鍵詞:單匯流排; 數字溫度感測器; 多點溫度測控
1 前言
隨著科學技術的發展,特別是現代儀器的發展,微型化、集成化、數字化正成為感測器發展的一個重要方向[1]。美國Dallas半導體公司推出的數字化溫度感測器DS1820採用單匯流排協議,即與微機介面僅需佔用一個I/O埠,無需任何外部元件,直接將溫度轉化成數字信號,以9位數字碼方式串列輸出,從而大大簡化了感測器與微處理器的介面。
2 工作原理
目前大多數感測器系統都採用放大--傳輸--數模轉換這種處理模式。這種模式一般要佔用數條數
據/控制線,限制了單片機功能的擴展。而一線匯流排技術則很好地解決了這個問題。
一線匯流排技術就是在一條匯流排上僅有一個主系統和若干個從系統組成的計算機應用系統。由於匯流排上的所有器件都通過一條信號線傳輸信息,匯流排上的每個器件在不同的時間段驅動匯流排,這相當於把數據匯流排、地址匯流排和控制匯流排合在了一起。所以整個系統要按單匯流排協議規定的時序進行工作。為了使其它設備也能使用這條匯流排,一線匯流排協議採用了一個三態門,使得每一個設備在不傳送數據時空出該數據線給
其它設備。一線匯流排在外部需要一個上拉電阻器,所以在匯流排空閑時是高電平。
掛在單匯流排上的器件稱為單匯流排器件,為了區分匯流排上的不同器件,生產單匯流排器件時,廠家都刻錄了一個64位的二進制ROM代碼作為晶元的唯一序列號。這樣通過定址就可以把每個器件識別出來。64位ROM的結構如下:開始8位是產品類型的編號(DS1820為10H),接著是每個器件的唯一的序號,共
有48位,最後8位是前56位的CRC校驗碼,這也是多個DS1820可以採用一線進行通信的原因。 3 DS1820介紹
DS1820是美國Dallas半導體公司推出的第一片支持"一線匯流排"介面的溫度感測器。它具有微型化、低功耗、高性能、抗干擾能力強、易配微處理器等優點,可直接將溫度轉化成串列數字信號供微機處理[2]。
DS1820的工作原理是:DS1820採用3腳PR-35封裝或8腳SOIC封裝,其中 GND為地;I/O為數據輸入/輸出端(即單線匯流排),該腳為漏極開路輸出,常態下呈高電平;VDD是外部+5V電源端,不用時應接地;NC為空腳。圖1 所示為DS1820的內部框圖,它主要包括寄生電源、溫度感測器、64位激光ROM單線介面、存放中間數據的高速暫存器(內含便箋式RAM),用於存儲用戶設定的溫度上下限值的TH和TL解發器存儲與控制邏輯、8位循環冗餘校驗碼(CRC)發生器等七部分。
DS1820 特點如下:硬體介面簡單,性能穩定,單線介面,僅需一根口線與MCU連接無需外圍元件;由匯流排提供電源;測溫范圍為-55~75℃;精度為0.5℃;9位溫度讀數;A/D變換時間為200ms;用戶自設定溫度報警上下限,其值是非易失性的;報警搜索命令可識別那片DS1820超溫度限。
DS1820的溫度測量原理如下[3]:DS1820測量溫度時使用特有的溫度測量技術,其測量電路框圖如圖2所示。內部計數器對一個受溫度影響的振盪器的脈沖計數,低溫時振盪器的脈沖可以通過門電路,而當到達某一設置高溫時,振盪器的脈沖無法通過門電路。計數器設置為-55℃時的值,如果計數器到達0之前,門電路未關閉,則溫度寄存器的值將增加,這表示當前溫度高於-55℃。同時,計數器復位在當前溫度值上,電路對振盪器的溫度系數進行補償,計數器重新開始計數直到回零。如果門電路仍然未關閉,則重復以上過程。溫度表示值為9bit,高位為符號位。
4 溫度檢測系統設計
由於每片DS1820含有唯一的硅串列數,所以在一條匯流排上可掛接多個DS1820晶元。從DS1820讀出的信息或寫入DS1820的信息,僅需要一根口線(單線介面)。讀寫及溫度變換功率來源於數據匯流排,匯流排本身也可以向所掛接的DS1820供電,而無需額外電源。DS1820提供9位溫度讀數,構成多點溫度檢測系統而無需任何外圍硬體。對DS1820的使用,多採用單片機實現數據採集。處理時,將DS1820信號線與單片機一位口線相連,單片機可掛接多片DS1820,從而實現多點溫度檢測系統。由於DS1820隻有三個引腳,其中兩根是電源線VDD和GND,另外兩根用作匯流排DQ(Data In/Out),由於其輸出和輸入均是數字信號且與TTL電平兼容,因此其可以與微處理器直接進行介面,從而省去了一般感測器所必需的中間轉換環節。
本設計中以DS1820為感測器、AT89C52單片機為控制核心組成的多點溫度測試系統如圖3所示[4]。用6隻DS1820同時測控6路溫度(視實際需要還可擴展通道數)。89C52單片機P1.1口接單線匯流排。DS1820採用寄生電源供電方式。為保證在有效的DS1820時鍾周期內能提供足夠的電流,圖3中採用一個MOSFET管和89C52的H.0口來完成對DS1820的匯流排上拉。鍵盤掃描和動態掃描的顯示共用一片可編程介面晶元8279,顯示採用8位共陰極LED數碼管,它可用來顯示通道數、溫度測量值以及TH、TL的值。
程序處理是整個系統的關鍵,即簡潔的硬體結構是靠復雜的軟體來支持的。多個器件掛在一條匯流排上為了識別不同的器件,在程序設計過程中一般有四個步驟:初始化命令;傳送ROM命令;傳送RAM命令;數據交換命令。
需要注意的是,無論是單點還是多點溫度檢測,在系統安裝及工作之前,應將主機逐個與DS1820掛接,讀出其序列號。其工作過程為:主機發出一個脈沖,待 "0"電平大於480μs後,復位DA1820,在DS1820所發響應脈沖由主機接收後,主機再發讀ROM命令代碼33H,然後發一個脈沖(15μs),並接著讀取DS1820序列號的一位。用同樣方法讀取序列號的56位。另外,由於DS1820單線通信功能是分時完成的,遵循嚴格的時隙概念,因此,系統對DS1820和各種操作必須按協議進行,即初始化DS1820(發復位脈沖)→發ROM功能命令→發存儲器操作命令→處理數據。系統對 DS1820操作的總體流程圖如圖4所示。
在正常測溫情況下,DS1820的測溫分辨力為0.5℃。採用下述方法可獲得高解析度的溫度測量結果:首先用DS1820提供的讀暫存器指令(BEH)讀出以0.5℃為解析度的溫度測量結果,然後切去測量結果中的最低有效位(LSB),得到所測實際溫度的整數部分Tz,然後再用BEH指令取計數器1的計數剩餘值Cs和每度計數值CD。考慮到DS1820測量溫度的整數部分以0.25和0.75℃為進位界限的關系.
結束語
對應於傳統概念,這一粒三極體一樣的感測器相當於傳統的溫度感測器+ 數字化+ CPU+ 匯流排協議及介面。一線器件採用單條連線,解決了控制、通信和供電等問題,降低了系統成本,並簡化了設計,為未來感測器的發展和應用開辟了新的領域。
http://www.mcublog.com/blog/blog2007/shuizhongzehui/archives/2007/22353.html
http://blog.21ic.com/user1/422/archives/2006/12900.html
有流程圖,電路圖和資料,不過網路上傳不了
H. 基於單片機的自動溫控系統的設計.畢業論文開題報告
熱電致冷器件特別適合於小熱量和受空間限制的溫控領域。改變加在器件上的直流電的極性即可變致冷為加熱,而吸熱或放熱率則正比於所加直流電流的大小。Pe1tier 溫控器的設定溫度可以在一個較寬的范圍內任意選擇,可選擇低於或高於環境溫度。
在本系統中我們選用了天津藍天高科電源有限公司生產的半導體致冷器件 TES1-12739,其最大溫差電壓 14.7V,最大溫差電流3.9A最大致冷功率33.7W。
1.5 其它部分
系統採用Samsung(三星)公司生產的真空熒光數碼顯示屏 VFD用來實時顯示當前溫度,以觀察控制效果。鍵盤和串列通信介面用來設定控制溫度和調整PID參數。系統電路原理圖如圖3所示。
2 系統軟體設計
系統開始工作時,首先由單片機控制軟體發出溫度讀取指令,通過數字溫度感測器 DS18B20 采樣被控對象的當前溫度值T1並送顯示屏實時顯示。然後,將該溫度測量值與設定值T比較,其差值送 PID控制器。PID 控制器處理後輸出一定數值的控制量,經DA 轉換為模擬電壓量,該電壓信號再經大電流驅動電路,提高電流驅動能力後載入到半導體致冷器件上,對溫控對象進行加熱或製冷。加熱或製冷取決於致冷器上所加電壓的正負,若溫控對象當前溫度測量值與設定值差值為正,則輸出負電壓信號,致冷器上載入負電壓溫控對象溫度降低;反之,致冷器上載入正向電壓,溫控對象溫度升高。上述過程:溫度采樣-計算溫差-PID調節-信號放大輸出周而復始,最後將溫控對象的溫度控制在設定值附近上下波動,隨著循環次數的增加,波動幅度會逐漸減小到某一很小的量,直至達到控制要求。為了加快控制,在進入PID控制前加入了一段溫差判斷程序。當溫度差值大於設定閾值Δt時,系統進行全功率加熱或製冷,直到溫差小於Δt才進入PID控制環節。圖4為系統工作主程序的軟體流程圖.
3 結論
本文設計的基於單片機數字PID控制的精密溫度控制系統,在實際應用中取得了良好的控制效果,溫度控制精度達到±0.1℃。經48小時連續運行考驗,系統工作穩定,有效地降低了輻亮度標准探測器的溫度系數,使輻亮度標准探測器在溫度變化較大的環境中也能保持其高精度,為實現基於探測器的高精度輻射定標的廣泛應用奠定了基礎。
本文作者創新點:在原來基於PC的PID溫控系統的基礎上,設計了由單片機、數字式溫感測器DS18B20和半導體致冷器組成的精密溫度控制系統。該溫控系統的應用為高精度光輻射測量儀器-輻亮度標准探測器的小型化、智能化提供了有利條件。
I. 單片機溫度控制系統設計方案
#include<reg52.H>
externGetTemp(); //聲明引用外部函數
; //聲明引用外部變數
voiddelay(unsignedinti);
//elseIO
sbitLS138A=P2^2;//管腳定義
sbitLS138B=P2^3;
sbitLS138C=P2^4;
//此表為LED的字模,共陰數碼管0-9-
unsignedcharcodeDisp_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsignedlongLedOut[5],LedNumVal;
voidsystem_Ini()
{
TMOD|=0x11;
TH1=0xD8;//10
TL1=0xF0;
IE=0x8A;
TR1=1;
}
main()
{unsignedchari;
system_Ini();
while(1)
{
GetTemp();
/********以下將讀18b20的數據送到LED數碼管顯示*************/
LedNumVal=Temperature;//把實際溫度送到LedNumVal變數中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10];//個位
for(i=0;i<4;i++)
{
P0=LedOut[i];
switch(i)
{ //138解碼
case0:LS138A=0;LS138B=0;LS138C=0;break;
case1:LS138A=1;LS138B=0;LS138C=0;break;
case2:LS138A=0;LS138B=1;LS138C=0;break;
case3:LS138A=1;LS138B=1;LS138C=0;break;
}
delay(100);
}
P0=0;
}
}
//延時程序
voiddelay(unsignedinti)
{
charj;
for(i;i>0;i--)
for(j=200;j>0;j--);
}
/*************************此部分為18B20的驅動程序*************************************/
#include<reg52.H>
#include<intrins.h>
sbitD18B20=P3^7;
#defineNOP()_nop_()/*定義空指令*/
#define_Nop()_nop_()/*定義空指令*/
voidTempDelay(unsignedcharidataus);
voidInit18b20(void);
voidWriteByte(unsignedcharidatawr);//單位元組寫入
voidread_bytes(unsignedcharidataj);
unsignedcharCRC(unsignedcharj);
voidGemTemp(void);
voidConfig18b20(void);
voidReadID(void);
voidTemperatuerResult(void);
bitflag;
unsignedintidataTemperature;
unsignedcharidatatemp_buff[9];//存儲讀取的位元組,readscratchpad為9位元組,readromID為8位元組
unsignedcharidataid_buff[8];
unsignedcharidata*p,TIM;
unsignedcharidatacrc_data;
unsignedcharcodeCrcTable[256]={
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53};
//
/************************************************************
*Function:延時處理
*parameter:
*Return:
*Modify:
*************************************************************/
voidTempDelay(unsignedcharidataus)
{
while(us--);
}
/************************************************************
*Function:18B20初始化
*parameter:
*Return:
*Modify:
*************************************************************/
voidInit18b20(void)
{
D18B20=1;
_nop_();
D18B20=0;
TempDelay(80);//delay530uS//80
_nop_();
D18B20=1;
TempDelay(14);//delay100uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
flag=1;//detect1820success!
else
flag=0;//detect1820fail!
TempDelay(20);//20
_nop_();
_nop_();
D18B20=1;
}
/************************************************************
*Function:向18B20寫入一個位元組
*parameter:
*Return:
*Modify:
*************************************************************/
voidWriteByte(unsignedcharidatawr)//單位元組寫入
{
unsignedcharidatai;
for(i=0;i<8;i++)
{
D18B20=0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);//delay45uS//5
_nop_();
_nop_();
D18B20=1;
wr>>=1;
}
}
/************************************************************
*Function:讀18B20的一個位元組
*parameter:
*Return:
*Modify:
*************************************************************/
unsignedcharReadByte(void)//讀取單位元組
{
unsignedcharidatai,u=0;
for(i=0;i<8;i++)
{
D18B20=0;
u>>=1;
D18B20=1;
if(D18B20==1)
u|=0x80;
TempDelay(2);
_nop_();
}
return(u);
}
/************************************************************
*Function:讀18B20
*parameter:
*Return:
*Modify:
*************************************************************/
voidread_bytes(unsignedcharidataj)
{
unsignedcharidatai;
for(i=0;i<j;i++)
{
*p=ReadByte();
p++;
}
}
/************************************************************
*Function:CRC校驗
*parameter:
*Return:
*Modify:
*************************************************************/
unsignedcharCRC(unsignedcharj)
{
unsignedcharidatai,crc_data=0;
for(i=0;i<j;i++)//查表校驗
crc_data=CrcTable[crc_data^temp_buff[i]];
return(crc_data);
}
/************************************************************
*Function:讀取溫度
*parameter:
*Return:
*Modify:
*************************************************************/
voidGemTemp(void)
{
read_bytes(9);
if(CRC(9)==0)//校驗正確
{
Temperature=temp_buff[1]*0x100+temp_buff[0];
// Temperature*=0.625;
Temperature/=16;
TempDelay(1);
}
}
/************************************************************
*Function:內部配置
*parameter:
*Return:
*Modify:
*************************************************************/
voidConfig18b20(void)//重新配置報警限定值和解析度
{
Init18b20();
WriteByte(0xcc);//skiprom
WriteByte(0x4e);//writescratchpad
WriteByte(0x19);//上限
WriteByte(0x1a);//下限
WriteByte(0x7f);//set11bit(0.125)
Init18b20();
WriteByte(0xcc);//skiprom
WriteByte(0x48);//保存設定值
Init18b20();
WriteByte(0xcc);//skiprom
WriteByte(0xb8);//回調設定值
}
/************************************************************
*Function:讀18B20ID
*parameter:
*Return:
*Modify:
*************************************************************/
voidReadID(void)//讀取器件id
{
Init18b20();
WriteByte(0x33);//readrom
read_bytes(8);
}
/************************************************************
*Function:18B20ID全處理
*parameter:
*Return:
*Modify:
*************************************************************/
voidTemperatuerResult(void)
{
p=id_buff;
ReadID();
Config18b20();
Init18b20();
WriteByte(0xcc);//skiprom
WriteByte(0x44);//Temperatureconvert
Init18b20();
WriteByte(0xcc);//skiprom
WriteByte(0xbe);//readTemperature
p=temp_buff;
GemTemp();
}
voidGetTemp()
{
if(TIM==100)//每隔1000ms讀取溫度
{TIM=0;
TemperatuerResult();
}
}
/*************************************
[t1(10ms)中斷]中斷
*************************************/
voidT1zd(void)interrupt3
{
TH1=0xD8;//10
TL1=0xF0;
TIM++;
}
/*************************此部分為74HC595的驅動程序使用SPI匯流排連接*************************************/
#include<reg52.h>
#include<intrins.h>
#defineNOP()_nop_()/*定義空指令*/
#define_Nop()_nop_()/*定義空指令*/
voidHC595SendData(unsignedintSendVal);
//SPIIO
sbitMOSIO=P1^5;
sbitR_CLK=P1^6;
sbitS_CLK=P1^7;
sbitIN_PL=P3^4;//74HC165shiftload把數據載入到鎖存器中
sbitIN_Dat=P3^5;//74HC165output數據移出
sbitOE=P3^6;
/*********************************************************************************************************
**函數名稱:HC595SendData
**功能描述:向SPI匯流排發送數據
*********************************************************************************************************/
voidHC595SendData(unsignedintSendVal)
{
unsignedchari;
for(i=0;i<16;i++)
{
if((SendVal<<i)&0x8000)MOSIO=1;//setdatalinehigh
elseMOSIO=0;
S_CLK=0;
NOP();
NOP();
S_CLK=1;
}
R_CLK=0;//setdatalinelow
NOP();
NOP();
R_CLK=1;//片選
OE=0;
}