共陽極顯示后應在顯示結束后給予高電平0xFF并保持一定時間,共陰極應給0x00并保持一定時間!
P1=temp>>1; //是將temp右移一位賦給P1,右移并不改變temp的狀態。
P1=temp>>=1;//是先將temp右移一位賦給temp,再講移位后的temp賦值給P1,此操作改變了temp的狀態!
簡述DS18B20 一·DS18B20的概述.DS18B20是美國DALLAS半導體公司推出的第一片支持“一線總線”接口的溫度傳感器,它具有微型化,低功耗,高性能,抗干擾能力強,易配微處理器等優點,可直接將溫度轉化成數字信號處理器處理。測量的溫度范圍是—55~125℃,測溫誤差0.5℃。可編程分辨率9~12位,對應的可分辨溫度分別為0.5℃,0.25℃,0.125℃和0.0625℃。相較熱電偶傳感器而言可實現高精度測溫。 對熱電偶溫度傳感器來說該項目實現的過程為:靠光敏電阻檢測光照的大小,光的改變最終改變電阻的大小,給電阻外加一個電壓,就改變了電壓的大小,再用PCF8951AD轉換器件檢測電壓的變化并轉換為數字信號,再傳到單片機上作一定的處理后去控制相應的數碼管顯示出當時的溫度。而對DS18B20來說過程則簡單的多了,熱電偶電阻傳感器一直到單片機之前的部分都可以用一個DS18B20來代替了,真正的實現了數字化。單片機后面的部分則兩者是一樣的! DS18B20與熱電阻溫度傳感器相比價格上,來說要貴出很多!所以在溫度的測量精度要求不是很高的話可以選擇熱電阻溫度傳感器,實驗者應則情而定。 二.DS18B20的硬件介紹.1.硬件實物圖及硬件原理圖如下. 三腳TO-92實物圖: 硬件原理圖: 八腳soic貼片式DS18B20: 2.兩種管腳排列圖: 3. 型號規格 型號 范圍 螺紋 電纜長度 適用管道 TS-18B20 -55~125 無 1.5 m TS-18B20A -55~125 M10X1 1.5m DN15~25 TS-18B20B -55~125 1/2”G 接線盒 DN40~ 60 4存儲器 DS18B20的存儲器包括高速暫存器RAM和可電擦除RAM,可電擦除RAM又包括溫度觸發器TH和TL,以及一個配置寄存器。存儲器能完整的確定一線端口的通訊,數字開始用寫寄存器的命令寫進寄存器,接著也可以用讀寄存器的命令來確認這些數字。當確認以后就可以用復制寄存器的命令來將這些數字轉移到可電擦除RAM中。當修改過寄存器中的數時,這個過程能確保數字的完整性。 高速暫存器RAM是由8個字節的存儲器組成;。用讀寄存器的命令能讀出第九個字節,這個字節是對前面的八個字節進行校驗 5. 64-位光刻ROM 64位光刻ROM的前8位是DS18B20的自身代碼,接下來的48位為連續的數字代碼,最后的8位是對前56位的CRC校驗。64-位的光刻ROM又包括5個ROM的功能命令:讀ROM,匹配ROM,跳躍ROM,查找ROM和報警查找。 6. DS18B20外部電源的連接方式 DS18B20可以使用外部電源VDD,也可以使用內部的寄生電源。當VDD端口接3.0V—5.5V的電壓時是使用外部電源;當VDD端口接地時使用了內部的寄生電源。無論是內部寄生電源還是外部供電,I/O口線要接5KΩ左右的上拉電阻。 7. DS18B20引腳定義: (1)DQ為數字信號輸入/輸出端; (2)GND為電源地; (3)VDD為外接供電電源輸入端(在寄生電源接線方式時接地)。 8. 內部結構圖:  三.工作過程.DS18B20控制方法(DS18B20有六條控制命令): 溫度轉換 44H 啟動DS18B20進行溫度轉換 讀暫存器 BEH 讀暫存器9位二進制數字 寫暫存器 4EH 將數據寫入暫存器的TH、TL字節 復制暫存器 48H 把暫存器的TH、TL字節寫到E2RAM中 重新調E2RAM B8H 把E2RAM中的TH、TL字節寫到暫存器TH、TL字節 讀電源供電方式 B4H 啟動DS18B20發送電源供電方式的信號給主CPU Void delay_18B20(us) { While(us--); } 1. 初始化 (1) 先將數據線置高電平“1”。 (2) 延時(該時間要求的不是很嚴格,但是盡可能的短一點)
(3) 數據線拉到低電平“0”。
(4) 延時750微秒(該時間的時間范圍可以從480到960微秒)。
(5) 數據線拉到高電平“1”。
(6) 延時等待(如果初始化成功則在15到60微妙時間之內產生一個由DS18B20所返回的低電平“0”。據該狀態可以來確定它的存在,但是應注意不能無限的進行等待,不然會使程序進入死循環,所以要進行超時控制)。 (7) 若CPU讀到了數據線上的低電平“0”后,還要做延時,其延時的時間從發出的高電平算起(第(5)步的時間算起)最少要480微秒。 (8) 將數據線再次拉高到高電平“1”后結束。
void ds1820rset() //ds1820復位
{
DQ = 1; //DQ復位
delay_18B20(4); //延時
DQ = 0; //DQ拉低
delay_18B20(100); //精確延時大于480us
DQ = 1; //拉高
delay_18B20(40);
}
2. 寫數據操作 (1) 數據線先置低電平“0”。 (2) 延時確定的時間為15微秒。
(3) 按從高位到低位的順序發送字節(一次只發送一位)。D7到D0的次序
(4) 延時時間為45微秒。
(5) 將數據線拉到高電平。
(6) 重復上(1)到(6)的操作直到所有的字節全部發送完為止。
(7) 最后將數據線拉高。
void ds1820wrdata(uchar wdata) /*寫數據*/
{
unsigned char I,temp=0x00;
for (i=8;i>0;i--)
{ DQ=0; delay_18B20(15) temp=1<<i-1; DQ=wdata&temp;
delay_18B20(45);
DQ=1;
}
}
3. 讀數據操作 (1)將數據線拉高“1”。
(2)延時2微秒。
(3)將數據線拉低“0”。
(4)延時3微秒。
(5)將數據線拉高“1”。
(6)延時5微秒。
(7)讀數據線的狀態得到1個狀態位,并進行數據處理。
(8)延時60微秒。
讀一位二進制數
bit ds_read_bit(void)
{
bit dat;
DQ=0;
delay_18B20(2);
DQ=1;
delay_18B20(3);
dat=DQ;
delay_18B20(100);
return(dat);
}
讀一個字節,8位二進制數
uchar ds1820readdata() //讀數據
{
unsiged char i,j,value=0;
for(i=0;i<8;i++)
{ j=ds_read_bit(); value |=j<<7-i; } return(value);
}
四.DS18B20的主要特性(1)、適應電壓范圍更寬,電壓范圍:3.0~5.5V,在寄生電源方式下可由數 據線供電
(2)、獨特的單線接口方式,DS18B20在與微處理器連接時僅需要一條口線即可實現微處理器與DS18B20的雙向通訊 (3)、 DS18B20支持多點組網功能,多個DS18B20可以并聯在唯一的三線上,實現組網多點測溫 (4)、DS18B20在使用中不需要任何外圍元件,全部 傳感元件及轉換電路集成在形如一只三極管的集成電路內 (5)、溫范圍-55℃~+125℃,在-10~+85℃時精度為±0.5℃
(6)、可編程 的分辨率為9~12位,對應的可分辨溫度分別為0.5℃、0.25℃、0.125℃和0.0625℃,可實現高精度測溫 (7)、在9位分辨率時最多在 93.75ms內把溫度轉換為數字,12位分辨率時最多在750ms內把溫度值轉換為數字,速度更快 (8)、測量結果直接輸出數字溫度信號,以"一 線總線"串行傳送給CPU,同時可傳送CRC校驗碼,具有極強的抗干擾糾錯能力 (9)、負壓特性:電源極性接反時,芯片不會因發熱而燒毀, 但不能正常工作。
五.工作原理:DS18B20的讀寫時序和測溫原理與DS1820相同,只是得到的溫度值的位數因分辨率不同而不同,且溫度轉換時的延時時間由2s 減為750ms。溫度系數晶振 隨溫度變化其振蕩率明顯改變,所產生的信號作為計數器2的脈沖輸入。計數器1和溫度寄存器被預置在-55℃所對應的一個基數值。計數器1對 低溫度系數晶振產生的脈沖信號進行減法計數,當計數器1的預置值減到0時,溫度寄存器的值將加1,計數器1的預置將重新被裝入,計數器1重 新開始對低溫度系數晶振產生的脈沖信號進行計數,如此循環直到計數器2計數到0時,停止溫度寄存器值的累加,此時溫度寄存器中的數值即 為所測溫度。
六.4個主要的數據部件:(1)光刻ROM中的64位序列號是出廠前被光刻好的,它可以看作是該DS18B20的地址序列碼。64位光刻ROM的排列是:開始8位 (28H)是產品類型標號,接著的48位是該DS18B20自身的序列號,最后8位是前面56位的循環冗余校驗碼(CRC=X8+X5+X4+1)。光刻ROM的作用 是使每一個DS18B20都各不相同,這樣就可以實現一根總線上掛接多個DS18B20的目的。  (2)DS18B20中的溫度傳感器可完成對溫度的測量,以12位轉化為例:用16位符號擴展的二進制補碼讀數形式提供,以 0.0625℃/LSB形式表達,其中S為符號位。 S18B20溫度值格式表: S18B20溫度數據表:  (4)配置寄存器 該字節各位的意義如下: 配置寄存器結構: 低五位一直都是"1",TM是測試模式位,用于設置DS18B20在工作模式還是在測試模式。在DS18B20出廠時該位被設置為0,用 戶不要去改動。R1和R0用來設置分辨率,如下表所示:(DS18B20出廠時被設置為12位) 溫度分辨率設置表: R1 | R0 | 分辨率 | 溫度最大轉換時間 | 0 | 0 | 9位 | 93.75ms | 0 | 1 | 10位 | 187.5ms | 1 | 0 | 11位 | 375ms | 1 | 1 | 12位 | 750ms |
DS18B20暫存寄存器分布: 寄存器內容 | 字節地址 | 溫度值低位 (LS Byte) | 0 | 溫度值高位 (MS Byte) | 1 | 高溫限值(TH) | 2 | 低溫限值(TL) | 3 | 配置寄存器 | 4 | 保留 | 5 | 保留 | 6 | 保留 | 7 | CRC校驗值 | 8 | |
根據DS18B20的通訊協議,主機(單片機)控制DS18B20完成溫度轉換必須經過三個步驟:每一次讀寫之前都要對DS18B20進行 復位操作,復位成功后發送一條ROM指令,最后發送RAM指令,這樣才能對DS18B20進行預定的操作。復位要求主CPU將數據線下拉500微秒,然后 釋放,當DS18B20收到信號后等待16~60微秒左右,后發出60~240微秒的存在低脈沖,主CPU收到此信號表示復位成功。 ROM指令表: 指 令 | 約定代碼 | 功 能 | 讀ROM | 33H | 讀DS1820溫度傳感器ROM中的編碼(即64位地址) | 符合 ROM | 55H | 發出此命令之后,接著發出 64 位 ROM 編碼,訪問單總線上與該編碼相對應的 DS1820 使之作出響應,為下一步對該 DS1820 的讀寫作準備。 | 搜索 ROM | 0FOH | 用于確定掛接在同一總線上 DS1820 的個數和識別 64 位 ROM 地址。為操作各器件作好準備。 | 跳過 ROM | 0CCH | 忽略 64 位 ROM 地址,直接向 DS1820 發溫度變換命令。適用于單片工作。 | 告警搜索命令 | 0ECH | 執行后只有溫度超過設定值上限或下限的片子才做出響應。 |
RAM指令表: 指 令 | 約定代碼 | 功 能 | 溫度變換 | 44H | 啟動DS1820進行溫度轉換,12位轉換時最長為750ms(9位為93.75ms)。結果存入內部9字節RAM中。 | 讀暫存器 | 0BEH | 讀內部RAM中9字節的內容 | 寫暫存器 | 4EH | 發出向內部RAM的3、4字節寫上、下限溫度數據命令,緊跟該命令之后,是傳送兩字節的數據。 | 復制暫存器 | 48H | 將RAM中第3 、4字節的內容復制到EEPROM中。 | 重調 EEPROM | 0B8H | 將EEPROM中內容恢復到RAM中的第3 、4字節。 | 讀供電方式 | 0B4H | 讀DS1820的供電模式。寄生供電時DS1820發送“ 0 ”,外接電源供電 DS1820發送“ 1 ”。 |
DS18B20的外部電源供電方式 在外部電源供電方式下,DS18B20工作電源由VDD引腳接入,此時I/O線不需要強上拉,不存在電源電流不足的問題,可以保證 轉換精度,同時在總線上理論可以掛接任意多個DS18B20傳感器,組成多點測溫系統。注意:在外部供電的方式下,DS18B20的GND引腳不能懸空 ,否則不能轉換溫度,讀取的溫度總是85℃。 


#include <reg51.h> //調用51單片機的頭文件
#include <Intrins.h>
sbit ds18b20=P1^2;
unsigned char TT,temp1;
unsigned char temp2;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};
//---------------------------------------
//名稱:復位DS18B20函數
//---------------------
bit Reset(void)
{
unsigned int i;
bit k;
ds18b20=0; //拉低DQ總線開始復位
i=95; //保持DQ低大約870uS,符合不低于48US的要求
while(i--); //保持DQ低大約870uS,符合不低于48US的要求
//保持DQ低大約870uS,符合不低于48US的要求
ds18b20=1; //拉高準備接收數據
i=9; //大約80uS后
while(i--); //大約80uS后
//大約80uS后
k=ds18b20; //讀出數據并保存
i=55; //維持約490US,符合總讀時隙不低于480US的要求
while(i--); //維持約400US,符合總讀時隙不低于480US的要求
//維持約400US,符合總讀時隙不低于480US的要求
return k; //k=0為復位成功,k=1為復位失敗
}
//---------------------------------------
//名稱:讀一字節函數
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=0;j<8;j++) //接收8次還原一個字節數據
{
buf=buf>>1; //接收前,想將接收緩沖區右移
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規范
_nop_(); //維持2US,符合大于1US小于15US的規范
ds18b20=1; //拉高,為讀數據做準備
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
if(ds18b20==1)
buf|=0x80; //讀出1位數據保存于buf中
i=7; //維持約52US,符合總讀時隙不低于60US的要求
while(i--); //維持約52US,符合總讀時隙不低于60US的要求
//維持約52US,符合總讀時隙不低于60US的要求
}
return buf; //退出的同時將接收緩沖區參數返回
}
//---------------------------------------
//名稱:寫一字節函數
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果寫1
{
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規范
_nop_(); //維持2US,符合大于1US小于15US的規范
ds18b20=1; //拉高
i=7; //維持約63US,符合不低于60US的要求
while(i--); //維持約63US,符合不低于60US的要求
}
else //如果寫0
{
ds18b20=0; //拉低
i=7; //維持約63US,符合不低于60US的要求
while(i--); //維持約63US,符合不低于60US的要求
ds18b20=1; //拉高
_nop_(); //維持2US,符合大于1US的規范
_nop_(); //維持2US,符合大于1US的規范
}
dat=dat>>1; //寫入字節右移1位
}
}
//---------------------------------------
//名稱:DS18B20溫度轉換函數
//---------------------------------------
bit Convert(void)
{
if(Reset()==0) //復位DS18B20成功
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0x44); //寫入溫度轉換命令字 Convert T
return 1; //啟動溫度轉換成功
}
else //失敗
{
return 0; //啟動溫度轉換失敗
}
}
//---------------------------------------
//名稱:轉換結束處理函數
//---------------------------------------
void ReadFlash(void)
{
unsigned char Lsb,Msb;
if(Reset()==0) //復位DS18B20成功
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0xbe); //寫入讀取數據令字 Read Scratchpad
Lsb=ReadByte(); //讀出第一個字節暫存于LSB
Msb=ReadByte(); //讀出第二個字節暫存于MSB
temp1=Lsb; //temp1內裝溫度參數的小數部分
temp2=Msb;//>>4)|(Lsb<<4);//temp2內裝溫度參數的整數部分
}
else
{
temp1=0; //如果復位失敗,溫度參數清零
temp2=0; //如果復位失敗,溫度參數清零
}
}
//---------------------------------------
void main(void) //主函數,單片機開機后就是從這個函數開始運行
{
unsigned char TT;
while(1) //死循環,單片機初始化后,將一直運行這個死循環
{
if(Convert()==1) //啟動轉換
{
ReadFlash(); //讀取溫度
TT=(temp2<<4)|(temp1>>4);
P3=tab[TT/10]; //溫度整數部分個位
P2=tab[TT%10]; //溫度整數部分十位
}
}
}

#include <reg51.h> //調用51單片機的頭文件
#include <Intrins.h>
sbit ds18b20=P1^2;
sbit gw=P1^0;
sbit sw=P1^1;
unsigned char TT,temp1;
unsigned char temp2;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};
//---------------------------------------
//名稱:復位DS18B20函數
//---------------------
void delay(int ms)
{
int i;
while(ms--)
for(i=0;i<120;i++);
}
//---------------------------------------
//名稱:復位DS18B20函數
//---------------------
bit Reset(void)
{
unsigned int i;
bit k;
ds18b20=0; //拉低DQ總線開始復位
i=95; //保持DQ低大約870uS,符合不低于48US的要求
while(i--); //保持DQ低大約870uS,符合不低于48US的要求
//保持DQ低大約870uS,符合不低于48US的要求
ds18b20=1; //拉高準備接收數據
i=9; //大約80uS后
while(i--); //大約80uS后
//大約80uS后
k=ds18b20; //讀出數據并保存
i=55; //維持約490US,符合總讀時隙不低于480US的要求
while(i--); //維持約400US,符合總讀時隙不低于480US的要求
//維持約400US,符合總讀時隙不低于480US的要求
return k; //k=0為復位成功,k=1為復位失敗
}
//---------------------------------------
//名稱:讀一字節函數
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=0;j<8;j++) //接收8次還原一個字節數據
{
buf=buf>>1; //接收前,想將接收緩沖區右移
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規范
_nop_(); //維持2US,符合大于1US小于15US的規范
ds18b20=1; //拉高,為讀數據做準備
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
_nop_(); //維持6US,符合大于1US小于15US的規范
if(ds18b20==1)
buf|=0x80; //讀出1位數據保存于buf中
i=7; //維持約52US,符合總讀時隙不低于60US的要求
while(i--); //維持約52US,符合總讀時隙不低于60US的要求
//維持約52US,符合總讀時隙不低于60US的要求
}
return buf; //退出的同時將接收緩沖區參數返回
}
//---------------------------------------
//名稱:寫一字節函數
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果寫1
{
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規范
_nop_(); //維持2US,符合大于1US小于15US的規范
ds18b20=1; //拉高
i=7; //維持約63US,符合不低于60US的要求
while(i--); //維持約63US,符合不低于60US的要求
}
else //如果寫0
{
ds18b20=0; //拉低
i=7; //維持約63US,符合不低于60US的要求
while(i--); //維持約63US,符合不低于60US的要求
ds18b20=1; //拉高
_nop_(); //維持2US,符合大于1US的規范
_nop_(); //維持2US,符合大于1US的規范
}
dat=dat>>1; //寫入字節右移1位
}
}
//---------------------------------------
//名稱:DS18B20溫度轉換函數
//---------------------------------------
bit Convert(void)
{
if(Reset()==0) //復位DS18B20成功
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0x44); //寫入溫度轉換命令字 Convert T
return 1; //啟動溫度轉換成功
}
else //失敗
{
return 0; //啟動溫度轉換失敗
}
}
//---------------------------------------
//名稱:轉換結束處理函數
//---------------------------------------
void ReadFlash(void)
{
unsigned char Lsb,Msb;
if(Reset()==0) //復位DS18B20成功
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0xbe); //寫入讀取數據令字 Read Scratchpad
Lsb=ReadByte(); //讀出第一個字節暫存于LSB
Msb=ReadByte(); //讀出第二個字節暫存于MSB
temp1=Lsb; //temp1內裝溫度參數的小數部分
temp2=Msb;//>>4)|(Lsb<<4);//temp2內裝溫度參數的整數部分
}
else
{
temp1=0; //如果復位失敗,溫度參數清零
temp2=0; //如果復位失敗,溫度參數清零
}
}
//---------------------------------------
void display(unsigned char ddd)
{
gw=1;
sw=0;
P2=tab[ddd/10];
delay(2);
P2=0x00;
delay(1);
gw=0;
sw=1;
P2=tab[ddd%10];
delay(2);
P2=0x00;
delay(1);
}
void main(void) //主函數,單片機開機后就是從這個函數開始運行
{
unsigned char TT;
while(1) //死循環,單片機初始化后,將一直運行這個死循環
{
if(Convert()==1) //啟動轉換
{
ReadFlash(); //讀取溫度
TT=(temp2<<4)|(temp1>>4);
display(TT);
}
}
}
|