DS18B20

DS18B20

1.     DS18B20硬件设计

DS18B20供电的范围为3.0V~5.0V,也可以通过数据线供电;其分辨率可以被使用者选择为9~12位,分辨率越高,转换需要时间越长。

根据供电方式不同,DS18B20有两种典型的硬件电路接法,分别为寄生电源模式和外部电源供电模式。寄生电源的控制回路中,当总线为高电平时,电源由单总线通过VDD引脚,部分能量存储在寄生电源储能电容C内,当数据总线处于低电平时释放能量以提供给器件能量。但是,当DS18B20正在执行温度转换或从高速暂存器向EEPROM传送数据时,工作电流可能达到1.5Ma;该电流可能会引起连接单总线的弱上拉电路的不可能接受的压降,这需要更大的电流,而此时储能电容无法提供。为了保存此时DS18B20有足够的供电,当进行温度转换或者拷贝数据到EEPROM操作时,必须给单总线提供一个强上拉。

DS18B20_第1张图片

图1 寄生电源供电模式

DS18B20_第2张图片

图2 外部电源供电模式

每个DS18B20都有一个独特的64为序列号,从而允许多只DS18B20同时链接在一根单线总线上,因此可以用一个微控制器覆盖在一大片区域的DS18B20。

2.      DS18B20时序

DS18B20工作协议流程一般为:初始化àROM操作指令à存储器操作指令à数据传输;其工作时序包括:初始化时序、写时序和读时序。

1)      初始化时序

微控制器首先发出一个480~960us的低电平脉冲,然后释放总线变为高电平,并在随后的480us时间内对总线进行监测,如果有低电平出现说明总线上有器件已经做出应答,如无低电平出现一直都是高电平说明总线上无期间应答。

而作为器件的DS18B20在一上电后就一直在监测总线上是否有480~960us的低电平出现,如果有,在总线转为高电平后等待15~60us将总线点平拉低60~240us做出响应存在脉冲,高度主机本器件已经做好准备,否则就一直检测等待。

DS18B20_第3张图片

图3 复位时序

void DS18B20_Reset(void)

{

       DS18B20_IO_OUT();//输出

       DS18B20_DQ_Low;

       delay_us(480);//延时480微妙   

       DS18B20_DQ_High;

       delay_us(480);//延时480微妙   

}

2)      写时序

写周期最少为60us,最长不超过120us,写周期一开始作为主机先将总线拉低15us表示写周期开始,随后若干主机想写0,则继续拉低低电平最少60us直至写周期结束,然后释放总线为高电平;若主机想写1,在一开始拉低总线点平1us后就释放总线为高电平,一直到写周期结束。

而作为从机的DS18B20则在检测到总线被拉低后等待15us然后从15us到45us开始对总线采样,在采样期间内总线为高电平则为1,若采样期间总线为低电平则为0。

DS18B20_第4张图片

图4 写时序

void DS18B20_Write_Byte(u8 dat)

{

       u8 i=0;

       DS18B20_IO_OUT();//输出

       for(i=0;i<8;i++)

       {

              DS18B20_DQ_Low;       //拉低

              delay_us(15);//延时15微妙

              if((dat&0x01)==1)

              {

                     DS18B20_DQ_High;

              }

              else

              {

                     DS18B20_DQ_Low;

              }

              delay_us(60);//延时60微妙

              DS18B20_DQ_High;

             

              dat>>=1;//准备下一位数据的发送   

       }

}

3)      读时序

对于读数据操作时序也可分为读0和读1时序两个过程,读时序是从主机把单总线拉低之后,在1us之后就得释放单总线为高电平,以让DS18B20将数据传输到单总线上。DS18B20在检测到总线被拉低1us后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束;若是送出1则释放总线为高电平。

主机在一开始拉低总线1us后释放总线,然后在包括前面的拉低总线点平1us在内的15us时间内完成对总线进行采样检测,采样期内为低电平在确认为0,采样期间总线为高电平则确认为1,完成一个读时序,至少需要60us才能完成。

DS18B20_第5张图片

图5 读时序

u8 DS18B20_Read_Byte(void)

{

       u8i=0,TempData=0;

       for(i=0;i<8;i++)

       {

              TempData>>=1;

              DS18B20_IO_OUT();//输出

              DS18B20_DQ_Low;       //拉低

              delay_us(4);//延时4微妙

              DS18B20_DQ_High;

              delay_us(10);//延时10微妙

              DS18B20_IO_IN();

              if(GPIO_ReadInputDataBit(GPIO_DS18B20,IO_DS18B20)==1)

              {

                 TempData|=0x80;//读数据 从低位开始

              }

              delay_us(45);//延时45微妙

       }

       returnTempData;

}

3.      DS18B20的操作方法

DS18B20单线通信功能是通过分时完成的,有严格的时序概念。系统对于DS18B20的各种操作必须按照协议进行,根据DS18B20的协议规定,微控制器控制DS18B20完成温度转换必须要经过如下四个步骤:

1)      每次读写前对DS18B20进行复位初始化;

2)      发送一条ROM指令;

3)      发送存储器指令;

一般程序中对单个DS18B20进行温度转换和温度读取的流程如下:

1)      主机复位;

2)      主机写跳过ROM操作命令(CCH);

3)      主机写转换温度的操作指令,然后释放总线至少1s,让DS18B20完成转换操作。再此,需要注意的是每个命令字节在写的时候都是低字节先写。

4)      主机发送复位操作并接受DS18B20的应答脉冲;

5)      主机写跳过ROM操作命令(CCH);

6)      主机发出读取RAM的命令(BEH),随后依次读取DS18B20发出的从第0到第8共9个字节。如果只想读取温度数据,可以在读取前两个数据后不再理会后面DS18B20发出的数据即可,同样读取的数据也是地位在前。

DS18B20_第6张图片

图6 DS18B20存储器图,上电状态取决于该EEPROM中的参数值

double DS18B20_Get_wd(void)

{

       u8TL=0,TH=0;

       u16temp=0;

       doublewd=0;

 

       DS18B20_Reset();//复位

       DS18B20_Write_Byte(0xCC);//跳过ROM命令

       DS18B20_Write_Byte(0x44);//温度转换命令

       delay_ms(800);//延时800毫秒

       DS18B20_Reset();//复位

       DS18B20_Write_Byte(0xCC);//跳过ROM命令

       DS18B20_Write_Byte(0xBE);//读温度命令

 

       TL=DS18B20_Read_Byte();//LSB

       TH=DS18B20_Read_Byte();//MSB

 

       temp=TH;

       temp=(temp<<8)+TL;

 

       if((temp&0xF800)==0xF800)//负温度判断

       {

              temp=~temp;

              temp=temp+1;

              wd=temp*(-0.0625);

       }

       else

       {

              wd=temp*0.0625;

       }

       return wd;

}

4.      高低温报警和测量精度的读取

void DS18B20_return_TH_TL_CONF( void ) 

    chardata,data_TH,data_TL,CONF; 

    DS18B20_Reset(); 

    DS18B20_write_byte(0xcc);       //忽略rom指令 

    DS18B20_write_byte(0xbe);   //读取温度转换值 

    data = DS18B20_read_byte(); 

    data = DS18B20_read_byte(); 

    data_TH = DS18B20_read_byte(); 

    data_TL = DS18B20_read_byte(); 

    CONF =DS18B20_read_byte(); 

   printf("过温报警的温度为:%d℃\r\n",data_TH); 

   printf("低温报警的温度为:%d℃\r\n",-(data_TL-128)); 

    CONF&=0x60 ; 

    CONF=CONF>>5; 

    switch(CONF) { 

        case0: 

           printf("DS18B20的测量精度为9位,精度为0.5℃\r\n"); 

           break; 

        case1: 

           printf("DS18B20的测量精度为10位,精度为0.25℃\r\n"); 

           break; 

        case2: 

           printf("DS18B20的测量精度为11位,精度为0.125℃\r\n"); 

           break; 

        case3: 

           printf("DS18B20的测量精度为12位,精度为0.0625℃\r\n"); 

           break; 

       default: 

           printf("error!!\r\n"); 

           break; 

    } 

void DS18B20_write_TH_TL_CONF(u8 TH,u8 TL,u8mode) 

    u8 dat; 

    switch(mode){ 

        case0: 

           dat=31; 

           break; 

        case1: 

           dat=63; 

           break; 

        case2: 

           dat=95; 

           break; 

        case3: 

           dat=127; 

           break; 

       default: 

            printf("mode error!!\r\n"); 

           dat=127; 

           break; 

    } 

   TL=TL+128; 

    DS18B20_Reset(); 

    DS18B20_write_byte(0xcc);       //忽略rom指令 

    DS18B20_write_byte(0x4e);   //写入暂存寄存器 ,过温和低温报警值 

    DS18B20_write_byte(TH);//写入20°为过温报警值 

    DS18B20_write_byte(TL);//写入-20°为低温报警值 

    DS18B20_write_byte(dat);    //写入精度 

    DS18B20_Reset(); 

    DS18B20_write_byte(0xcc);       //忽略rom指令 

    DS18B20_write_byte(0x48);   //将写入的暂存寄存器拷入EEPROM 


你可能感兴趣的:(STM32)