Ds18b20的使用

一、概述:Ds18b20是最常見的數字溫度傳感器,有着諸多優點,比如:體積小;精度高(12位時精度可以達到0.625攝氏度,出廠默認12位);接線簡單,無需外圍短路;封裝形式多樣,能滿足不同應用需求等等。但是,“魚與熊掌不可兼得”,接線簡單的同時,帶來的問題便是傳感器複雜的工作時序。Ds18b20工作時序十分複雜,信號傳輸只在微妙之間,稍有不慎(例如延時函數的使用不夠恰當)就可能導致其整個傳感器的工作時序混亂。因此,在寫Ds18b20的控制程序時一定要弄清工作時序並使用合適的延時函數。

二、引腳圖


從上圖可以看出Ds18b20的接線得卻十分簡單,但需要注意的是,當傳感器與單片機相連時,要加一個4.7K的上拉電阻(事實證明要求沒那麼嚴格,5K左右即可)。

三、工作指令

1.溫度轉換指令:0x44(即44H),啓動Ds18b20啓動轉換溫度

2.讀暫存器指令:0xBE(即BEH),讀取暫存器中的九字節數據

3.寫暫存器置零:0x4E(即4EH),把數據寫入暫存器的TH、TL

4.賦值暫存器:0x48(即48H),把暫存器中的TH、TL寫入EEPROM中

5.讀電源供電方式:0xB4(即B4H):啓動Ds18b20,發送電源供電方式

6.重調EEPROM:0xB8(即B8H):把EEPROM中的TH、TL讀至暫存器

四、通過單總線訪問Ds18b20的時序


五、操作時序

1.復位操作


2.“讀”操作


3.“寫”操作


六、例程(例程均爲自己編寫且通過驗證成功)

/*所用單片機型號爲STC89C52RC,晶振爲11.0592MHz*/

#include<reg52.h>

#include<intrins.h>


sbit Bus=P1^1;//數據單總線


unsigned int Ds_Result();//返回最終結果
bit DS_Init();//初始化子函數
void Ds_Write(unsigned char dat);//“寫”子函數(用於向總線寫命令)
unsigned char Ds_Read();//“讀”子函數(用於從總線讀值)
void Ds_Change();//開始轉換溫度
unsigned int Get_Temp();//獲取溫度子函數
void Delay10us(unsigned int t);//延時10*t微秒

void Delay1ms(unsigned int t);


/*ds18b20 10*t延時函數*/
void Delay10us(unsigned int t)
{
    unsigned int i;
    for(i=t;i>0;i--)
    {
        _nop_();  _nop_();
        _nop_();  _nop_();
        _nop_();  _nop_();
    }
}




/*dsb8b20 1ms延時函數*/
void Delay1ms(unsigned int t)   //誤差 0us
{
    unsigned char a,b,c;
for(t;t>0;t--)
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}
/*ds18b20初始化*/
bit Ds_Init()
{
bit ack;
Bus=0;
Delay10us(60);//最小480,最大960
Bus=1;
Delay10us(6);//15-60us
while(Bus==0);
Bus=1;//讓傳感器釋放總線,避免影響下一步
return ack;//ack爲0則響應成功
}




/*ds18b20寫時序*/
void Ds_Write(unsigned char dat)//一個寫週期爲60-120us,主機在15--45us內對信號採樣
{
unsigned char mask;
for(mask=0x01;mask!=0;mask<<=1)
{


Bus=0;
_nop_();
if((mask&dat)==0)
{
Bus=0;
}
else
{
Bus=1;
}
Delay10us(6);//15-60us採樣
Bus=1;
_nop_();
_nop_();
}
}


/*ds18b20讀時序*/
unsigned char Ds_Read()
{
unsigned char dat=0;
unsigned char mask,fmask;
for(mask=0x01;mask!=0;mask<<=1)//一個週期需要至少60us,但採樣要在15us內完成
{
Bus=0;
_nop_();
Bus=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(Bus==0)//讀0
{
fmask=~mask;
dat=dat&fmask;
}
else
{
dat|=mask;
}
Delay10us(5);
Bus=1;


}
return dat;
}


/*轉換溫度子函數*/
void Ds_Change()
{
Ds_Init();
Delay1ms(1);
Ds_Write(0xCC);//跳過ROM尋址
Ds_Write(0x44);//啓動一次溫度轉換




}


/*ds18b20獲取溫度子函數*/
unsigned int Get_Temp()
{
unsigned int temp=0;
unsigned char LSB,MSB;//用來儲存數據的第八位與高八位
Ds_Init();
Delay1ms(1);
Ds_Write(0xCC);//跳過尋址
Ds_Write(0xBE);//發送讀值命令·
LSB=Ds_Read();
MSB=Ds_Read();
temp=MSB;
temp<<=8;
temp|=LSB;
return temp;
}


/*ds18b20  返回最終結果子函數*/
unsigned int Ds_Result()
{
float tp;
unsigned int temp;
Delay1ms(10);//10ms度過不穩定期
         Ds_Change();//轉換溫度
        Delay1ms(1000);//延時1s等待轉化
        temp=Get_Temp();
        tp=temp;
        temp=tp*0.0625;
        return temp;//最終結果爲temp
}


int main()

{

    unsigned int temp;

    temp=Ds_Result();//該值即爲結果

}



左肩理想,右肩擔當。君子不怨永遠不會停下腳步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章