老師布置了一個課程設計題目:采用51單片機控制的DS18B20溫度檢測系統。大概花了我一個禮拜的時間,幸好我的C語言學得還可以,最後還是讓我搞出來了,真是高興,我是采用STC-52單片機和DS18B20數字溫度傳感器做的一個溫度檢測系統:實現的主要功能是:能夠通過按鍵設置報警溫度,報警溫度分為上限溫度和下限溫度,就是說當溫度超過上限溫度和下限溫度時蜂鳴器就會報警,同時流水燈開始流動。並且由於溫度的上下限是寫入到DS18B20的ROM中,所以斷電之後還是可以保存上次設定的溫度上下限值,系統缺陷是開機時由於溫度檢測裝置還未開始工作,會顯示85度(默認值),之後就會顯示正確的溫度,整個程序采用中斷顯示溫度和按鍵掃描中斷程序,檢測溫度是否超過報警上下限值的函數也放在中斷顯示溫度服務程序中。
緒 論
單片機是一種集成電路芯片,是采用超大規模集成電路技術把具有數據處理能力的中央處理器CPU隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計時器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊硅片上構成的一個小而完善的微型計算機系統,在工業控制領域的廣泛應用。DS18B20封裝式,型號多種多樣,有LTM8877,LTM8874等等。主要根據應用場合的不同而改變其外觀。封裝後的DS18B20可用於電纜溝測溫,高爐水循環測溫,鍋爐測溫,機房測溫,農業大棚測溫,潔淨室測溫,彈藥庫測溫等各種非極限溫度場合。耐磨耐碰,體積小,使用方便,封裝形式多樣,適用於各種狹小空間設備數字測溫和控制領域。
1.設計題目
基於DS18B20數字溫度傳感器的溫度測量.
2.課程設計目的
通過基於STC-51系列單片機和DS18B20溫度傳感器檢測溫度,熟悉芯片的使用、溫度傳感器的功能,數碼顯示管的使用,單片機C語言的程序設計,並且把我們這一年所學的數字和模擬電子技術、檢測技術、單片機應用等知識,通過理論聯系實際,從題目分析、電路設計調試、程序編制調試到傳感器的選定等這一完整的實驗過程,培養了學生正確的設計思想,使學生充分發揮主觀能動性,去獨立解決實際問題,以達到提升學生的綜合能力、動手能力、文獻資料查閱能力的作用,為畢業設計和以後工作打下一個良好的基礎。
3.設計任務和要求
3-1: 以STC-51單片機為核心部件,組成一個數字溫度計,采用數字溫度傳感器DS18B20為檢測器件,進行單點溫度檢測,檢測精度為0.5℃。溫度顯示采用4位LED數碼管顯示,兩位整數,一位小數。具有鍵盤輸入上下限功能,超過上下限溫度時,進行聲音報警。
3-2: 能夠設置上限溫度和下限溫度值,當被測量溫度在上限溫度和下限溫度值之間時綠色LED亮,當被測量溫度在上限溫度和下限溫度值之外時紅色LED亮,並蜂鳴器報警;設置的上限溫度和下限溫度值能夠斷電後保存(EEPROM)。實現上述功能要求人機界面盡量簡單。
4.實驗原理
4-1: 原理簡述-數字溫度傳感器DS1820把溫度信息轉換為數字格式;通過“1-線協議”,單片機獲取指定傳感器的數字溫度信息,並顯示到顯示設備上。通過鍵盤,單片機可根據程序指令實現更靈活的功能,如單點檢測、輪轉檢測、越限檢測等。基於DS1820數字溫度傳感器的溫度檢測及顯示的系統原理圖如下圖所示:
完整的程序下載:
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2013年資料/9月/11日/單片機C語言實現的采用DS18B20的溫度檢測裝置
下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm
部分程序如下:
/*****************************************************************************/
模塊名:基於DS18B20的數字溫度計
創建人: lecco
VERSION:rick 1.0.1 beta
功能描述:本模塊采用DALLS公司的單線數字溫度傳感器DS18B20,抗干擾能力強,便於遠距離測量,因而得到了廣泛應用。
功能要求:采用按鍵設置上下限溫度報警值,按確認鍵生效當溫度超過預警值就會發出蜂鳴聲,用STC89C51控制DS18B20,讀取數據,並對DS18B20轉換後的數據管顯示,最高位為符號位,如果溫度值為正,不顯示,如果溫度為負,則顯示 。
溫度支持范圍: -50℃ ~ 125℃
/*****************************************************************************/
#include <reg51.h>
#include <helloDemo.h>
#include <intrins.h>
unsigned char tx[10]={0};
unsigned char code table1[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x90};
/*****************************************************************************/
void Delay(int num)//延時函數
{
while(num--) ;
}
/*****************************************************************************/
void Delaynms(unsigned int di) //延時
{
unsigned int da,db;
for(da=0;da<di;da++)
for(db=0;db<100;db++);
}
/*****************************************************************************/
void Init_DS18B20(void)//初始化ds18b20
{
unsigned char x=0;
DQ = 1; //DQ復位
Delay(8); //稍做延時
DQ = 0; //單片機將DQ拉低
Delay(80); //精確延時 大於 480us
DQ = 1; //拉高總線
Delay(14);
x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗
Delay(20);
}
/*****************************************************************************/
unsigned char ReadOneChar(void)//讀一個字節
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
Delay(4);
}
return(dat);
}
/*****************************************************************************/
void WriteOneChar(unsigned char dat)//寫一個字節
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay(2);
DQ = 1;
dat>>=1;
}
}
/*****************************************************************************/
void ReadTemperature(void)//讀取溫度和報警溫度上下限TH、TL值
{
unsigned char a=0;
unsigned char b=0;
unsigned char Data_L=0; //用來存放小數部分的溫度值
unsigned char num=0;
unsigned int temp=0; //臨時存放負數溫度值
Init_DS18B20();
Delay(20);
WriteOneChar(0xCC); // 跳過讀序號列號的操作
Delay(20);
WriteOneChar(0x44); // 啟動溫度轉換
Delay(20);
Init_DS18B20();
Delay(20);
WriteOneChar(0xCC); //跳過讀序號列號的操作
Delay(20);
WriteOneChar(0xBE); //讀取溫度寄存器
Delay(20);
a = ReadOneChar(); //讀低8位
b = ReadOneChar(); //讀高8位
Delay(20);
tx[4]= ReadOneChar(); //報警溫度TH
tx[5]= ReadOneChar(); //報警溫度TL
temp = b*256+a;
temp = temp * 0.625 + 0.5; //0.0625擴大10倍顯示1位小數,若顯示兩位小數則擴大100倍為6.25
tx[2]= temp /1000; //溫度的百位
tx[1]=temp %1000/100 ; //溫度的十位
tx[0]=temp %100/10; //溫度的個位
//讀取溫度正負值
if((b&0xf8)!=0x00){
tx[6]=1; //溫度值是負數的標志位
//temp為補碼,需要減一求反得原碼
temp = ( b * 256 ) + a;
temp = ~temp + 1;
tx[1] = temp % 1000 / 100; //溫度的十位
tx[0] = temp % 100 / 10; //溫度的個位
}
tx[6]=0;
Data_L=a&0X0F;
tx[3]=table1[Data_L];
}
/*****************************************************************************/
void Display_SMG(void)
{
unsigned char a;
for(a=0;a<=50;a++)
{ //如果得到的溫度是負數就顯示符號
if(tx[6]==1){
P0=0xbf;
led1 = 0;
Delaynms(4);
led1 = 1; }
if(tx[2]>0){
P0=table[tx[2]];
led1 = 0;
Delaynms(4);
led1 = 1; }
P0=table[tx[1]];
led2 = 0;
Delaynms(4);
led2 = 1;
P0=(table[tx[0]])&0x7f;
led3 = 0;
Delaynms(4);
led3 = 1;
P0=table[tx[3]];
led4 = 0;
Delaynms(4);
led4 = 1;
}
}
/*****************************************************************************/
void beep()
{
unsigned char i=0;
if(((tx[1]*10+tx[0])>(tx[4])||(((tx[1]*10+tx[0])==(tx[4]))&&(tx[3]>tx[7]-1)))&&(tx[9]==5))
{
P1=_cror_(P1,1);
WAV=~WAV;
Delaynms(35); } if((tx[6]==1)&&((((tx[1]*10+tx[0])>(tx[5]))||(((tx[1]*10+tx[0])==(tx[5]))&&(tx[3]>tx[8]-1)))&&(tx[9]==5)))
{ P1=_crol_(P1,1); WAV=~WAV;Delaynms(35); } }
/*****************************************************************************/
void main(void)
{
TMOD=0x11; //T1,T0均工作於方式一
EA=1; //開總中斷
ET0=1; //開定時器T0中斷
ET1=1; //開定時器T1中斷
TH1=(65536-20000)/256; //顯示溫度
TL1=(65536-20000)%256;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR1=1; //啟動定時器T1
TR0=1; //禁止定時器T0
P1=0x7f;
while(1)
{ WAV=1; }
}