C51單片機12(溫度傳感器)_第1頁
C51單片機12(溫度傳感器)_第2頁
C51單片機12(溫度傳感器)_第3頁
C51單片機12(溫度傳感器)_第4頁
C51單片機12(溫度傳感器)_第5頁
已閱讀5頁,還剩47頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第12講溫度傳感器溫度傳感器概述溫度傳感器DS1820Dallas公司生產(chǎn)的數(shù)字溫度傳感器單總線接口方式,只需要與MCU的一個端口連接即可實現(xiàn)雙向通信可以直接將溫度轉(zhuǎn)化成串行數(shù)字信號只有三個引腳(VDD、GND、DQ)同一總線上可以掛接多個溫度傳感器芯片適用于遠距離多點溫度檢測+5V供電,也可以在信號線上高電平時為內(nèi)部電容充電,供低電平時消耗電源極性接反時,芯片發(fā)燙,但不會燒壞主要性能指標(biāo)溫度測量范圍:-55℃~+125℃溫度測量精度:±0.5℃(-10℃~+85℃)溫度數(shù)字量轉(zhuǎn)換時間:200ms(典型值)DS18B20的外觀與引腳DALLASDS18B20123GNDDQVDDOOO123仰視圖正視圖DS1820內(nèi)部結(jié)構(gòu)框圖64位ROM和單線端口電源檢測VDD存儲器和控制邏輯溫度傳感器上限觸發(fā)TH下限觸發(fā)TL8位CRC產(chǎn)生器暫存器內(nèi)部VDD工作過程內(nèi)部低溫度系統(tǒng)振蕩器振蕩頻率隨溫度變化很小,為計數(shù)器1提供一個頻率穩(wěn)定的計數(shù)脈沖內(nèi)部高溫度系統(tǒng)振蕩器振蕩頻率對溫度很敏感,為計數(shù)器2提供一個頻率隨溫度變化的計數(shù)脈沖溫度測量原理低溫度系數(shù)振蕩器高溫度系數(shù)振蕩器計數(shù)器1計數(shù)器2溫度寄存器斜坡累加器比較預(yù)置=0?=0?預(yù)置增加停止溫度測量過程初始時溫度寄存器被預(yù)置成-55℃計數(shù)器1被預(yù)置成與-55℃相對應(yīng)的一個量計數(shù)器1從預(yù)置數(shù)開始減計數(shù)到0時,溫度寄存器中的溫度值增加1℃斜率累加器為計數(shù)器1提供新的計數(shù)值計數(shù)器1開始新的減計數(shù),這個過程重復(fù)進行,直到計數(shù)器2計數(shù)到0為止除初始值以外,計數(shù)器1每一個循環(huán)的預(yù)置數(shù)都由斜率累加器提供為了補償振蕩器溫度特性的非線性,斜率累加器提供的預(yù)置數(shù)將隨溫度而相應(yīng)變化(也就是說,在不同溫度范圍時,使溫度寄存器值增加1℃所需要的計數(shù)個數(shù)是不同的)DS18B20芯片的地址編碼當(dāng)單一總線上掛接多個DS18B20芯片時,使用64位光刻ROM地址來區(qū)別不同芯片64位地址碼是產(chǎn)品出廠前光刻好的產(chǎn)品類型標(biāo)號(說明是溫度傳感器)序列號(與網(wǎng)卡MAC地址相似)CRC碼(CRC=X8+X5+X4+1,用于校驗)8位CRC碼48位序列號8位產(chǎn)品類型標(biāo)號DS18B20的操作指令0x33——讀取ROM。讀傳感器ROM中的64位編碼0x55——匹配ROM。發(fā)出此命令后,接著發(fā)出64位編碼,訪問單一總線上相應(yīng)的DS18B20,并使之做出響應(yīng),為讀寫做準(zhǔn)備0xF0——搜索ROM。用于確定掛接在同一總線上的DS18B20芯片數(shù),識別64位地址,為操作各器件做準(zhǔn)備0xCC——跳過ROM。當(dāng)總線上只有一個溫度傳感器芯片時,忽略64位地址,直接向DS18B20發(fā)出命令0xEC——告警搜索。執(zhí)行后,只有溫度超過預(yù)設(shè)上、下限的芯片才做出響應(yīng)DS18B20的操作指令44H——溫度轉(zhuǎn)換。啟動DS18B20進行溫度轉(zhuǎn)換,結(jié)果存入內(nèi)部RAMBEH——讀暫存器。讀內(nèi)部RAM中的溫度數(shù)據(jù)4EH——寫暫存器。發(fā)出向內(nèi)部RAM第2、3字節(jié)寫上、下限值的命令,緊接著傳送2字節(jié)數(shù)據(jù)48H——復(fù)制暫存器。將內(nèi)部RAM第2、3字節(jié)內(nèi)容復(fù)制到EEPROMB8H——重調(diào)EEPROM。將EEPROM中內(nèi)容恢復(fù)到內(nèi)部RAM第2、3字節(jié)B4H——讀供電方式。讀得0,DS18B20采用寄生供電;讀得1,DS18B20利用外接電源供電DS18B20內(nèi)部RAM地址安排9字節(jié)存儲器內(nèi)容字節(jié)地址溫度值低位0溫度值高位1溫度上限值2溫度下限值3配置寄存器4保留5保留6保留7CRC校驗值8DS18B20的溫度數(shù)據(jù)存儲格式位7位6位5位4位3位2位1位0232221202-12-22-32-4位15位14位13位12位11位10位9位8SSSSS262524DS18B20的溫度數(shù)據(jù)存儲格式字節(jié)0字節(jié)1位7位6位5位4位3位2位1位0232221202-12-22-32-4位15位14位13位12位11位10位9位8SSSSS262524符號位(1:負值0:正值)測得數(shù)據(jù)×0.0625=實際溫度值單個DS1820芯片與單片機的連接在有條件的情況下,最好每個溫度傳感器都使用獨立電源接MCU初始化數(shù)據(jù)線置“1”延時(時間要求不嚴(yán)格,但盡量短一點)數(shù)據(jù)線置“0”延時750us(480~960us)數(shù)據(jù)線置“1”(15~60us)延時等待芯片返回的低電平若讀到數(shù)據(jù)線上低電平0,再延時(從5開始至少480us)數(shù)據(jù)線再次置“1”,結(jié)束VccGND主控制器發(fā)出的480~960us芯片應(yīng)答的60~240us15~60us初始化的子過程voiddsreset(void)//18B20復(fù)位,初始化函數(shù){ //加電時已有一個初始高電平

uinti;

ds=0; //數(shù)據(jù)線上輸出低電位并延時750us i=103;

while(i>0)i--;

ds=1; //數(shù)據(jù)線上輸出高電位并延時30us i=4;

while(i>0)i--;}寫數(shù)據(jù)數(shù)據(jù)線置“0”延時15us按從低到高的順序,逐位發(fā)送數(shù)據(jù)延時45us數(shù)據(jù)線置“1”重復(fù)1~5步驟,直到發(fā)送完整個數(shù)據(jù)字節(jié)數(shù)據(jù)線再次置“1”,結(jié)束VccGND15us15us15us15us30us30usmintypmaxmintypmax主控制器寫“0”時隙主控制器寫“1”時隙寫數(shù)據(jù)字節(jié)的子過程(方法一)voidtempwritebyte(uchar

dat)//向18B20寫一個字節(jié)數(shù)據(jù){

uinti;

ucharj; bittestb;

for(j=1;j<=8;j++) {

testb=dat&0x01; //判斷寫數(shù)據(jù)最低位

if(testb) //寫"1" {

ds=0; //數(shù)據(jù)線輸出低電平

i++;i++; //延時15us

ds=1; //數(shù)據(jù)線輸出高電平(寫"1")

i=8;while(i>0)i--; //延時>45us } else //寫"0" {

ds=0; //數(shù)據(jù)線輸出低電平

i=8;while(i>0)i--; //延時>45us

ds=1; //數(shù)據(jù)線輸出高電平

i++;i++; //延時15us }

dat=dat>>1; //右移一位,準(zhǔn)備下次寫操作

}}寫數(shù)據(jù)字節(jié)的子過程(方法二)voidds1820writebyte(ucharwdata) //ds1820寫數(shù)據(jù)字節(jié){

uchari=0;for(i=8;i>0;i--) //按從低到高的順序,逐位輸出數(shù)據(jù)字節(jié)

{ DQ=0; //數(shù)據(jù)線輸出0 DQ=wdata&0x01; //準(zhǔn)備寫數(shù)據(jù)位(同時延時15us)

ds1820delay(10); //延時45us DQ=1; //數(shù)據(jù)線輸出1

wdata>>=1; //右移一位,準(zhǔn)備下次發(fā)送

}}DS18B20啟動子過程voidtempchange(void) //{

dsreset(); //溫度傳感器復(fù)位

delay(1); //延時

tempwritebyte(0xcc); //寫跳過讀ROM指令

//(因為只有一個溫度傳感器) tempwritebyte(0x44); //寫溫度轉(zhuǎn)換指令

//啟動溫度轉(zhuǎn)換開始}讀數(shù)據(jù)數(shù)據(jù)線置“1”延時2us數(shù)據(jù)線置“0”延時2us數(shù)據(jù)線置“1”延時4us讀數(shù)據(jù)線,得到一個狀態(tài)位,并進行數(shù)據(jù)處理延時30us重復(fù)1~7步驟,直到讀完一個字節(jié)讀數(shù)據(jù)字節(jié)的子過程(方法一)bittempreadbit(void) //讀1個數(shù)據(jù)位{

uinti; bitdat;

ds=0;i++; //數(shù)據(jù)線拉低到0,延時2us

ds=1;i++;i++; //數(shù)據(jù)線拉高到1,延時4us

dat=ds; //讀數(shù)據(jù)線,得到1個數(shù)據(jù)位

i=8;while(i>0)i--; //延時15us return(dat); //返回數(shù)據(jù)位}uchar

tempreadbyte(void) //讀1個數(shù)據(jù)字節(jié){

uchari,j,dat;

dat=0; //清除存儲單元,準(zhǔn)備接收數(shù)據(jù)

for(i=1;i<=8;i++) { j=tempreadbit(); //讀取1個數(shù)據(jù)位

dat=(j<<7)|(dat>>1); //讀出數(shù)據(jù)低位在前

}

return(dat);}讀數(shù)據(jù)字節(jié)的子過程(方法二)uchards1820readbyte() //ds1820讀數(shù)據(jù)字節(jié){

uchari=0;

uchar

dat=0; for(i=8;i>0;i--) //逐位讀取溫度傳器提供的數(shù)據(jù)

{ DQ=0; //數(shù)據(jù)線輸出0

dat>>=1; //右移1位,準(zhǔn)備用當(dāng)前最高位存放讀得的數(shù)據(jù)位

DQ=1; //數(shù)據(jù)線輸出1,執(zhí)行下面的語句相當(dāng)于延時4us

if(DQ) //讀數(shù)據(jù)線狀態(tài),得到一個數(shù)據(jù)位

dat|=0x80; //若讀得狀態(tài)位為1,保存到dat的當(dāng)前最高位上

ds1820delay(10); //延時30us }

return(dat);}舉例說明讀數(shù)據(jù)字節(jié)的過程(1)設(shè)tempreadbit()第一次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00000000dat=(j<<7)|(dat>>1); //dat=10000000舉例說明讀數(shù)據(jù)字節(jié)的過程(2)設(shè)tempreadbit()第二次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=01000000dat=(j<<7)|(dat>>1); //dat=11000000舉例說明讀數(shù)據(jù)字節(jié)的過程(3)設(shè)tempreadbit()第三次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01100000dat=(j<<7)|(dat>>1); //dat=01100000舉例說明讀數(shù)據(jù)字節(jié)的過程(4)設(shè)tempreadbit()第四次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00110000dat=(j<<7)|(dat>>1); //dat=10110000舉例說明讀數(shù)據(jù)字節(jié)的過程(5)設(shè)tempreadbit()第五次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01011000dat=(j<<7)|(dat>>1); //dat=01011000舉例說明讀數(shù)據(jù)字節(jié)的過程(6)設(shè)tempreadbit()第六次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=00101100dat=(j<<7)|(dat>>1); //dat=00101100舉例說明讀數(shù)據(jù)字節(jié)的過程(7)設(shè)tempreadbit()第七次返回“1”j=tempreadbit(); //j=00000001j=j<<7; //j=10000000dat=dat>>1; //dat=00010110dat=(j<<7)|(dat>>1); //dat=10010110舉例說明讀數(shù)據(jù)字節(jié)的過程(8)設(shè)tempreadbit()第八次返回“0”j=tempreadbit(); //j=00000000j=j<<7; //j=00000000dat=dat>>1; //dat=01001011dat=(j<<7)|(dat>>1); //dat=01001011讀取傳感器中存儲的溫度數(shù)據(jù)uint

get_temp() //讀取傳感器中存儲的溫度數(shù)據(jù){

uchar

a,b;

dsreset(); //溫度傳感器復(fù)位

delay(1); tempwritebyte(0xcc); //寫跳過讀ROM指令(因為只有一個溫度傳感器) tempwritebyte(0xbe); //讀內(nèi)部RAM的命令

a=tempreadbyte();//第一次讀到的是低8位,地址自動修正

b=tempreadbyte();//第二次讀到的是高8位

temp=b; //先保存高8位到temp temp<<=8; //左移8位,低8位以0填充

temp=temp|a; //兩個字節(jié)組合為1個字

f_temp=temp*0.0625; //溫度在寄存器中為12位分辨率位0.0625° temp=f_temp*10+0.5; //乘以10表示小數(shù)點后面只取1位,加0.5是四舍五入

f_temp=f_temp+0.05; returntemp; //temp是整型}temp和f_temp都是在程序開頭定義的變量,在各過程中都有效溫度值在LED數(shù)碼管上顯示voiddisp_temp(uintreal) //溫度值轉(zhuǎn)換成便于輸出顯示的形式{ LED[7]=0; LED[6]=real%10; //溫度值小數(shù)點后第1位 LED[5]=(real/10)%10;

//溫度值個位數(shù) LED[4]=real/100; //溫度值十位數(shù)}voiddisplay() //數(shù)碼管顯示{ P2=0; P0=table[LED[0]];delay(2); //表示第0號傳感器

P2=4; P0=table[LED[4]];delay(2); //溫度值十位數(shù)

P2=5; P0=table[LED[5]]|0x80;delay(2); //溫度值個位數(shù),包含小數(shù)點

P2=6; P0=table[LED[6]];delay(2); //溫度值1/10位

P2=7; P0=table[LED[7]];delay(2); //溫度值1/100位(實際上總為0)}數(shù)據(jù)定義#include<reg52.h>#include<stdio.h>#defineucharunsignedchar#defineuintunsignedintsbit

ds=P2^3;//溫度傳感器信號線uint

temp,realtemp;floatf_temp;ucharcodetable[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //0123456789ucharLED[8]={0,10,10,10,0,0,0,0};voiddelay(uintz) //延時函數(shù){

uint

x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);}主控程序main()voidmain(){ while(1) { display();

tempchange(); display();

realtemp=get_temp(); display();

disp_temp(realtemp); }}由于一次溫度采集的過程很長(超過2ms),故不便于利用中斷方式控制LED數(shù)碼管顯示過程多點溫度采集需要解決的問題:系統(tǒng)中共包含多少個溫度傳感器?怎樣區(qū)分不同的溫度傳感器?怎樣對指定的溫度傳感器執(zhí)行操作?執(zhí)行操作的時間有多長?溫度數(shù)據(jù)傳輸?shù)淖畲缶嚯x有多遠?溫度傳感器的供電問題怎樣解決?多點測溫網(wǎng)絡(luò)的構(gòu)建方法多個DS18B20掛接在同一條總線上在硬件系統(tǒng)搭建時,先讀取DS18B20的ROM序列號,并將它們固化在程序中(如數(shù)組),單片機向總線發(fā)送匹配ROM命令之后,緊跟發(fā)送一個序列號,接下來讀取的溫度數(shù)據(jù)就來自與ROM序列號匹配的那個DS18B20每一個I/O口掛接一個DS18B20利用SEARCHROM指令動態(tài)搜索64位ROM碼(二叉樹遍歷)二叉樹遍歷SEARCHROM指令:發(fā)出searchrom

指令后,ds18b20將所有的第一位0,0,0放到總線上,單片機讀到的是相與的結(jié)果為0。接著ds18b20將所有器件的第一位的補碼1,1,1放到總線上,單片機讀到的數(shù)據(jù)是相與的結(jié)果為1.等待主機響應(yīng)之后,繼續(xù)將下一位及其反碼,發(fā)送到總線上。

每次讀ds18b20發(fā)出的兩位會得到00,01,10,11的結(jié)果其含義如下:00:掛在總線上的ds18b20在這一位上有沖突,即有的在這一位上為0,有的在這一位上為101:所有DS18B20此位數(shù)據(jù)均為010:所有DS18B20此位數(shù)據(jù)均為111:沒有DS18B20二叉樹遍歷ROM搜索過程是簡單三步過程的重復(fù)(1)讀一位(2)讀核位的補碼(3)寫所需的那一位的值:發(fā)0,則選中這一位為0的ds18b20,在此后的過程中,僅這一位為0的ds18b20參與向總線收發(fā)數(shù)據(jù)發(fā)1,則選中這一位為1的ds18b20,在此后的過程中,僅這一位為1的ds18b20參與向總線收發(fā)數(shù)據(jù)總線主機在ROM的每一位上完成這三步過程。全部過程完成之后,總線主機便知道一個器件中ROM的內(nèi)容讀取傳感器序列號并上傳到串口助手#include<reg52.h>#defineucharunsignedchar#defineuintunsignedintsbitDQ=P2^3; //溫度傳感器信號線ucharfCode[8];voidds1820delay(uinti) //延時1微秒{

while(i--);}復(fù)位voidds1820reset() //ds1820復(fù)位{ DQ=1; //數(shù)據(jù)線輸出高電平

ds1820delay(4); //延時

DQ=0; //數(shù)據(jù)線輸出低電平

ds1820delay(100); //延時480~960us DQ=1; //數(shù)據(jù)線輸出高電平

ds1820delay(40); //延時15~60us}讀數(shù)據(jù)字節(jié)uchards1820readbyte() //ds1820讀數(shù)據(jù)字節(jié){

uchari=0;

uchar

dat=0; for(i=8;i>0;i--) //逐位讀取溫度傳器提供的數(shù)據(jù)

{ DQ=0; //數(shù)據(jù)線輸出0

dat>>=1; //右移一位,準(zhǔn)備用存放讀得的數(shù)據(jù)位

DQ=1; //數(shù)據(jù)線輸出1,執(zhí)行下面語句延時4us

if(DQ) //讀數(shù)據(jù)線狀態(tài),得到一個數(shù)據(jù)位

dat|=0x80; //若讀得1,保存到dat的當(dāng)前最高位上

ds1820delay(10); //延時30us }

return(dat);}寫數(shù)據(jù)字節(jié)voidds1820writebyte(ucharwdata) //ds1820寫數(shù)據(jù)字節(jié){

uchari=0;for(i=8;i>0;i--) //按從低到高順序,逐位輸出數(shù)據(jù)字節(jié)

{ DQ=0; //數(shù)據(jù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論