温度传感器DS18B20工作原理详解
tencentUser 2024-01-30

今天讲的是温度传感器DS18B20,主要分为以下几个方面:

一、DS18B20简介

二、DS18B20参数

三、DS18B20引脚及原理图

四、DS18B20工作步骤

五、STM32例程

六、总结


一、DS18B20简介

DS18B20是一款常用的高精度的单总线数字温度测量芯片,具有体积小,硬件开销低,抗干扰能力强,精度高的特点,其控制命令和数据都是以数字信号的方式输入输出的。

DS18B20实物图

图 1 DS18B20实物图

二、DS18B20特性及主要参数

测温范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±0.4°

• 返回16位二进制温度数值

• 主机和从机通信使用单总线,即使用单线进行数据的发送和接收

• 在使用中不需要任何外围元件,独立芯片即可完成工作。

• 掉电保护功能 DS18B20 内部含有 EEPROM ,通过配置寄存器可以设定数字转换精度和报警温度,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

• 每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值

• 宽电压供电,电压2.5V~5.5V

DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。


三、DS18B20引脚及原理图

DS18B20引脚图

图 2 DS18B20引脚图

【引脚1】GND:电源地线

【引脚2】DQ:数字信号输入/输出端

【引脚3】VDD:外接供电电源输入端

DS18B20原理图

图 3 DS18B20原理图

单个DS18B20接线方式: VDD接到电源,DQ接单片机引脚,同时外加上拉电阻,GND接地。注意这个上拉电阻是必须的,就是DQ引脚必须要一个上拉电阻。

关于DS18B20上拉电阻:

首先我们要知道什么是漏极开路:

首先看一下场效应管(MOSFET)

MOSFET

场效应管是电压控制型元器件,只要对栅极施加一定电压,DS就会导通。


漏极开路:MOS管的栅极G和输入连接,源极S接公共端,漏极D悬空(开路)什么也没有接,直接输出,这时只能输出低电平和高阻态,不能输出高电平。

那么这个时候会出现三种情况:

图a为正常输出(内有上拉电阻):场效应管导通时,输出低电位输出低电位,截止时输出高电位。

图b为漏极开路输出,外接上拉电阻:场效应管导通时,驱动电流是从外部的VCC流经电阻通过MOSFET到GND,输出低电位,截止时输出高电位。

图c为漏极开路输出,无外接上拉电阻:场效应管导通时输出低电位,截止呈高阻态(断开)。

漏极开路

总结:

开漏输出只能输出低电平,不能输出高电平。漏极开路输出高电平时必须在输出端与正电源(VCC)间外接一个上拉电阻。否则只能输出高阻态。

DS18B20 是单线通信,即接收和发送都是这个通信脚进行的。 其接收数据时为高电阻输入,其发送数据时是开漏输出,本身不具有输出高电平的能力,即输出0时通过MOS下拉为低电平,而输出1时,则为高阻,需要外接上拉电阻将其拉为高电平。 因此,需要外接上拉电阻,否则无法输出1。

外接上拉电阻阻值:

DS18B20的工作电流约为1mA,VCC一般为5V,则电阻R=5V/1mA=5KΩ,

所以正常选择4.7K电阻,或者相近的电阻值。


四、DS18B20工作步骤

DS18B20的工作步骤可以分为三步:

1.初始化DS18B20

2.执行ROM指令

3.执行DS18B20功能指令

其中第二步执行ROM指令,也就是访问每个DS18B20,搜索64位序列号,读取匹配的序列号值,然后匹配对应的DS18B20,如果我们仅仅使用单个DS18B20,可以直接跳过ROM指令。而跳过ROM指令的字节是0xCC。

(1)初始化DS18B20

任何器件想要使用,首先就是需要初始化,对于DS18B20单总线设备,首先初始化单总线为高电平,然后总线开始也需要检测这条总线上是否存在DS18B20这个器件。如果这条总线上存在DS18B20,总线会根据时序要求返回一个低电平脉冲,如果不存在的话,也就不会返回脉冲,即总线保持为高电平。

初始化具体时序步骤如下:

1.单片机拉低总线至少480us,产生复位脉冲,然后释放总线(拉高电平)。

2.这时DS8B20检测到请求之后,会拉低信号,大约60~240us表示应答。

3.DS8B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示初始化成功

4.DS18B20拉低电平60~240us之后,会释放总线。

时序图

(2)写时序

总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。每次只传输1位数据。

单片机想要给DS18B20写入一个0时,需要将单片机引脚拉低,保持低电平时间要在60~120us之间,然后释放总线;

单片机想要给DS18B20写入一个1时,需要将单片机引脚拉低,拉低时间需要大于1us,然后在15us内拉高总线。

在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0。

注意:2次写周期之间至少间隔1us


DS18B20写入的功能命令:

ROM指令:

采用多个DS18B20时,需要写ROM指令来控制总线上的某个DS18B20

如果是单个DS18B20,直接写跳过ROM指令0xCC即可。

指令功能

RAM指令,DS18B20的一些功能指令,常用的是:

温度转换 0x44:开启温度读取转换,读取好的温度会存储在高速暂存器的第0个和第一个字节中;

读取温度 0xBE:读取高速暂存器存储的数据。

指令功能

读时序:

读时隙由主机拉低总线电平至少1μs然后再释放总线,读取DS18B20发送过来的1或者0

DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。

时序图

注意:所有读时隙必须至少需要60us,且在两次独立的时隙之间至少需要1ps的恢复时间。


同时注意:主机只有在发送读暂存器命令(0xBE)或读电源类型命令(0xB4)后,立即生成读时隙指令,DS18B20才能向主机传送数据。 也就是先发读取指令,再发送读时隙。


最后一点: 写时序注意是先写命令的低字节,比如写入跳过ROM指令0xCC(11001100),写的顺序是“零、零、壹、壹、零、零、壹、壹”。


读时序时是先读低字节,在读高字节,也就是先读取高速暂存器的第0个字节(温度的低8位),在读取高速暂存器的第1个字节(温度的高8位) 我们正常使用DS18B20读取温度读取两个温度字节即可。


五、STM32例程

(1)DS18B20.C

#include "ds18b20.h"

#include "delay.h"


//复位DS18B20

void DS18B20_Rst(void)

{

DS18B20_IO_OUT();  //SET PG11 OUTPUT

DS18B20_DQ_OUT=0;  //拉低DQ

delay_us(750);     //拉低750us

DS18B20_DQ_OUT=1;  //DQ=1

delay_us(15);      //15US

}

//等待DS18B20的回应

//返回1:未检测到DS18B20的存在

//返回0:存在

u8 DS18B20_Check(void)

{

u8 retry=0;

DS18B20_IO_IN(); //SET PG11 INPUT

while (DS18B20_DQ_IN&&retry<200)

{

retry++;

delay_us(1);

};

if(retry>=200)return 1;

else retry=0;

while (!DS18B20_DQ_IN&&retry<240)

{

retry++;

delay_us(1);

};

if(retry>=240)return 1;

return 0;

}

//从DS18B20读取一个位

//返回值:1/0

u8 DS18B20_Read_Bit(void)

{

u8 data;

DS18B20_IO_OUT(); //SET PG11 OUTPUT

DS18B20_DQ_OUT=0;

delay_us(2);

DS18B20_DQ_OUT=1;

DS18B20_IO_IN(); //SET PG11 INPUT

delay_us(12);

if(DS18B20_DQ_IN)data=1;

else data=0;

delay_us(50);

return data;

}

//从DS18B20读取一个字节

//返回值:读到的数据

u8 DS18B20_Read_Byte(void)

{

u8 i,j,dat;

dat=0;

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

{

j=DS18B20_Read_Bit();

dat=(j<<7)|(dat>>1);

}

return dat;

}

//写一个字节到DS18B20

//dat:要写入的字节

void DS18B20_Write_Byte(u8 dat)

{

u8 j;

u8 testb;

DS18B20_IO_OUT(); //SET PG11 OUTPUT;

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

{

testb=dat&0x01;

dat=dat>>1;

if (testb)

{

DS18B20_DQ_OUT=0; // Write 1

delay_us(2);

DS18B20_DQ_OUT=1;

delay_us(60);

}

else

{

DS18B20_DQ_OUT=0; // Write 0

delay_us(60);

DS18B20_DQ_OUT=1;

delay_us(2);

}

}

}

//开始温度转换

void DS18B20_Start(void)

{

DS18B20_Rst();

DS18B20_Check();

DS18B20_Write_Byte(0xcc); // skip rom

DS18B20_Write_Byte(0x44); // convert

}


//初始化DS18B20的IO口 DQ 同时检测DS的存在

//返回1:不存在

//返回0:存在

u8 DS18B20_Init(void)

{

GPIO_InitTypeDef  GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);  //使能PORTG口时钟


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;    //PORTG.11 推挽输出

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOG, &GPIO_InitStructure);


GPIO_SetBits(GPIOG,GPIO_Pin_11);    //输出1


DS18B20_Rst();


return DS18B20_Check();

}

//从ds18b20得到温度值

//精度:0.1C

//返回值:温度值 (-550~1250)

short DS18B20_Get_Temp(void)

{

u8 temp;

u8 TL,TH;

short tem;

DS18B20_Start ();     // ds1820 start convert

DS18B20_Rst();

DS18B20_Check();

DS18B20_Write_Byte(0xcc); // skip rom

DS18B20_Write_Byte(0xbe); // convert

TL=DS18B20_Read_Byte();  // LSB

TH=DS18B20_Read_Byte();  // MSB


if(TH>7)

{

TH=~TH;

TL=~TL;

temp=0;     //温度为负

}else temp=1;    //温度为正

tem=TH;      //获得高八位

tem<<=8;

tem+=TL;     //获得底八位

tem=(float)tem*0.625;  //转换

if(temp)return tem;   //返回温度值

else return -tem;

}

(2)DS18B20.H

#ifndef __DS18B20_H

#define __DS18B20_H

#include "sys.h"


//IO方向设置

#define DS18B20_IO_IN()  {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}

#define DS18B20_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}

IO操作函数

#define DS18B20_DQ_OUT PGout(11) //数据端口 PA0

#define DS18B20_DQ_IN  PGin(11)  //数据端口 PA0


u8 DS18B20_Init(void);//初始化DS18B20

short DS18B20_Get_Temp(void);//获取温度

void DS18B20_Start(void);//开始温度转换

void DS18B20_Write_Byte(u8 dat);//写入一个字节

u8 DS18B20_Read_Byte(void);//读出一个字节

u8 DS18B20_Read_Bit(void);//读出一个位

u8 DS18B20_Check(void);//检测是否存在DS18B20

void DS18B20_Rst(void);//复位DS18B20

#endif


六、总结

DS18B20作为常用的数字温度传感器,其体积小,硬件开销低,抗干扰能力强,精度高的特点,可用于电缆沟测温、锅炉测温、机房测温、农业大棚测温等各种非极限温度场合,适用于各种狭小空间设备数字测温和控制领域。

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • 元器件
  • 电阻
  • 电容
  • 电感
下载排行榜
更多
评测报告
更多
广告