锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

【STM32】【HAL库】DS18B20温度传感器单器件使用详解

时间:2022-12-23 00:30:00 0550传感器

DS18B20介绍

DS18B20是一种常用的数字温度传感器,具有体积小、硬件成本低、抗干扰能力强、精度高等特点。DS18B20数字温度传感器接线方便,包装后可应用于管道、螺纹、磁铁吸附、不锈钢包装、各种型号LTM8877,LTM8874等。外观主要根据不同的应用场合而变化。
封装后的DS18B20可用于各种非极限温度场合,如电缆沟测温、高炉水循环测温、锅炉测温、机房测温、农业温室测温、洁净室测温、弹药库测温等。耐磨耐碰,体积小,使用方便,包装形式多样,适用于各种狭小空间设备的数字测温和控制。

特点

DS18B20 单线数字温度传感器,即一线器件”,其具有独特的优点:

( 1 )采用单总线接口法 微处理器微处理器连接时,只需一条口线即可实现 DS18B20 双向通信。单总线具有经济性好、抗干扰能力强、现场温度测量适合恶劣环境、使用方便等优点,使用户能够轻松构建传感器网络,为测量系统的构建引入新的概念。

( 2 )测量温度范围宽,测量精度高 DS18B20 测量范围为 -55 ℃ ~ 125 ℃ ; 在 -10~ 85°C精度在范围内 ± 0.5°C 。可编程的分辨率为9~12位,对应的可分辨温度为0.5℃、0.25℃、0.125℃和0.0625℃(默认出厂12位)

( 3 )使用中不需要任何外围元件。

( 4 )持有多点组网功能 多个 DS18B20 可并联在唯一的单线上,实现多点测温。

( 5 )灵活的供电方式 DS18B20 通过内部寄生电路从数据线上获取电源。因此,当数据线上的时间顺序满足一定要求时,可以不连接外部电源,使系统结构更简单、更可靠。

( 6 )可配置测量参数 DS18B20 通过程序设置测量分辨率 9~12 位。

( 7 )当负压特性电源极性反转时,温度计不会因发热而燃烧,但不能正常工作。

( 8 )掉电保护功能 DS18B20 内部含有 EEPROM ,系统断电后,仍能保存分辨率和报警温度的设定值。

内部结构图 ??? 内部结构图


DS18B20管脚排列:

1. GND为电源地;

2. DQ输入/输出数字信号;

3. VDD外部供电电源输入端(寄生电源接接地)

内部构成

??DS18B20温度传感器的存储器DS18B20温度传感器的内部存储器包括一个高速暂存RAM非易失性可电擦除EEPRAM,后者储存高温和低温触发器TH、TL并配置寄存器。

高速临时存储器它由9个字节组成。当温度转换命令发布时,转换获得的温度值以二字节补码的形式存储在高速临时存储器的第0和第1个字节中。单片机可以通过单线接口读取数据。读取时,相应的温度计算:当符号位置时S=0时,二进制位直接转换为十进制;当S=一、先将补码变成原码,再计算十进制值。

温度低位 温度高位 TH TL 配置 保留 保留 保留 8位CRC

LSB???MSB

共9个字节,从左到右0-1-2-3-4-5-6-7-8。
0位----------->低温八位数据
1位----------->温度的高八位数据
2位----------->高温阀值
3位----------->低温阀值
4位----------->配置寄存器
5位----------->保留
6位----------->保留
7位----------->保留
8位----------->CRC

  • 温度寄存器
    S是符号位。


以12位转换为例:
12位转换后获得的12位数据存储在18位B20两个8比特RAM二进制前五位是符号位,

  • 如果温度大于0,?这5位为0,只要将测到的数值乘于0.0625可获得实际温度;
  • 如果温度小于0,则5位为1,测量值需要取反加1乘以0.0625可获得实际温度。

例如 125℃07的数字输出D0H, 25.0625℃0191H,-25.0625℃数字输出为FF6FH,-55℃数字输出为FC90H?。

温度/℃ 数字输出(二进制) 数字量输出(Hex)
125 0000 0111 1101 0000 0x07D0
85 0000 0101 0101 0000 0x0550
25.0625 0000 0001 1001 0001 0x0191
10.125 0000 0000 1010 0010 0x00A2
0.5 0000 0000 0000 1000 0x0008
0 0000 0000 0000 0000 0x0000
-0.5 1111 1111 1111 1000 0xFFF8
-10.125 1111 1111 0101 1110 0xFF5E
-25.0625 1111 1110 0110 1111 0xFE6F
-55 1111 1100 1001 0000 0xFC90

打开时,温度寄存器的默认值为 85℃

  • TH和TL寄存器

配置寄存器,字节的意义如下

TM R1 R0 1 1 1 1 1

低五位一直都是"1",TM用于设置测试模式位DS18B工作模式还是测试模式。DS18B20出厂时,该位置设置为0,用户不得更改。R1和R0用于设置分辨率,如下表所示:(DS18B20出厂时设置为12位。

table> R1 R0 分辨率 温度最大转换时间 0 0 9位 93.75ms 0 1 10位 187.5ms 1 0 11位 375ms 1 1 12位 750ms

与主机通信

根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:

  1. 每一次读写之前都要对DS18B20进行复位操作
  2. 复位成功后发送一条ROM指令
  3. 最后发送RAM指令

复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

ROM指令表

指令 约定代码 功能
读ROM 33H 读DS18B20温度传感器ROM中的编码(即64位地址)
符合ROM 55H 发出此命后,接着发出64位ROM编码,访问单总线上与该编码相对应的DS18B20使之作出响应,为下一步对该DS18B20的读写做好准备
搜索ROM 0F0H 用于确认挂接在同一总线上的DS18B20的个数和识别64位ROM地址。为操作各器件做好准备
跳过ROM 0CCH 忽略64位ROM地址,直接向DS18B20发出温度变换指令。适用于单片工作
告警搜索命令 0ECH 执行后只有温度超过设定上限或下限的片子才做出响应

这些都不怎么能用到,是用来组网控制的指令,重要的是接下来的
ROM指令表

指令 约定代码 功能
温度变换 44H 启动DS18B20进行温度转换,结果存入内部9字节RAM中
读暂存器 BEH 读内部RAM中9字节的内容
写暂存器 48H 发出向内部RAM的3.4字节写上、下限温度数据命令,紧跟该命令后,是传送两字节的数据
复制暂存器 48H 将RAM中第3、4字节的内容复制到EEPROM中
重调EEPROM B8H 将EEPROM中的内容恢复到RAM中的3、4字节
读供电方式 B4H 读DS18B20的供电模式。寄生电源时返回0,外接电源供电返回1
  • 1.上电初始化时序图

DS18B20的复位时序如下:
1.单片机拉低引脚480-950us,然后再释放总线
2.上拉电阻拉高,等待15-60us后,DS18B20会拉低信号维持60-240us,表示应答
3.DS18B20拉低电平的60-240us之间,单片机读取总线的电平,如果是低电平,那么代表复位成功
4.DS18B20拉低电平的60-240us之后,会释放总线

IO配置

//IO操作 
#define DS18B20_Port GPIO_PIN_8 //数据端口PE8

//GPIO mode 选择
#define DS18B20_IO_IN() {GPIOE->MODER&=~(3<<(9*2));GPIOE->MODER|=0<<9*2;} //PE8模拟输入
#define DS18B20_IO_OUT() {GPIOE->MODER&=~(3<<(9*2));GPIOE->MODER|=1<<9*2;} //PE8通常输出模式


延时us函数

void delay_us(uint32_t nus)
{ 
        
 uint32_t temp;
	SysTick->LOAD = 9*nus;
	SysTick->VAL=0X00;//清空计数器
	SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
	do
	{ 
        
		temp=SysTick->CTRL;//读取当前倒计数值
	}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
	SysTick->CTRL=0x00; //关闭计数器
	SysTick->VAL =0X00; //清空计数器
}

复位脉冲

void DS18B20_Rst()      //复位DS18B20
{ 
                            
	DS18B20_IO_OUT(); //设置为输出模式 
	HAL_GPIO_WritePin(GPIOE, DS18B20_Port, GPIO_PIN_RESET);
	//拉低DQ 
	delay_us(750);    //拉低750us(至少480us) 
	HAL_GPIO_WritePin(GPIOE, DS18B20_Port, GPIO_PIN_SET);	
	//DQ=1拉高释放总线 
	delay_us(15);     //15US 
	//进入接受模式,等待应答信号。
}

应答信号

//等待DS18B20的回应

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

uint8_t DS18B20_Check()       
{ 
              
	uint8_t retry=0;    
	DS18B20_IO_IN();//SET PE8 INPUT 
	while (HAL_GPIO_ReadPin(GPIOE,DS18B20_Port)&&retry<200)    
	{ 
                    
		retry++;          
		delay_us(1);    
	};        
	if(retry>=200)return 1;    
	else retry=0;    

	while (!HAL_GPIO_ReadPin(GPIOE,DS18B20_Port)&&retry<240)    
	{ 
                    
		retry++;            
		delay_us(1);    
	};    
	if(retry>=240)return 1;            
	return 0;
}
  • 2.读操作时序图


  单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。 所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。

  典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

从DS18B20读取一个位

//返回值:1/0

u8 DS18B20_Read_Bit(void)              // read one bit

{ 
        
	u8 data;    
	DS18B20_IO_OUT();//设置为输出 
	DS18B20_DQ_OUT=0; //输出低电平2us 
	delay_us(2);    
	DS18B20_DQ_OUT=1; //拉高释放总线 
	DS18B20_IO_IN();//设置为输入 
	delay_us(12);//延时12us 
	if(DS18B20_DQ_IN)data=1;//读取总线数据 
	else data=0;        
	delay_us(50);  //延时50us 
	return data;
}

读取一个字节数据

//从DS18B20读取一个字节 //返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
{ 
                    
	u8 i,j,dat;    
	dat=0;  
	for (i=1;i<=8;i++)  
	{ 
                
		j=DS18B20_Read_Bit();        
		dat=(j<<7)|(dat>>1);    
	}                                
	return dat;
}
  • 3.写操作时序图

      写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。 写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。

写一个字节到DS18B20

void DS18B20_Write_Byte(u8 dat)    
{ 
                        
u8 j;
u8 testb;    
DS18B20_IO_OUT();//设置PA0为输出 
for (j=1;j<=8;j++)    
{ 
                
	testb=dat&0x01;        
	dat=dat>>1;        
	if (testb) //输出高 
	{ 
                  
		DS18B20_DQ_OUT=0;// 主机输出低电平 
		delay_us(2);                  //延时2us 
		DS18B20_DQ_OUT=1;//释放总线 
		delay_us(60); //延时60us 
	}        
	else //输出低 
	{ 
                    
		DS18B20_DQ_OUT=0;//主机输出低电平 
		delay_us(60);               //延时60us 
		DS18B20_DQ_OUT=1;//释放总线 
		delay_us(2);                  //延时2us 
	}    
}
}

典型DS18B20温度读取过程

  1. 复位
  2. 发送SKIP ROM命令 0xCC
  3. 发开始转换命令 0x44
  4. 复位
  5. 发送SKIP ROM指令 0xCC
  6. 发读取存储器命令 0xBE
  7. 连续读出两个字节数据
  8. 结束
//开始温度转换
void DS18B20_Start()
{ 
        
	DS18B20_Rst();
	DS18B20_Check();
	DS18B20_Write_Byte(0xcc);// skip rom
	DS18B20_Write_Byte(0x44);// convert
}

//初始化 DS18B20 的 IO 口 DQ 同时检测 DS 的存在
//返回 1:不存在
//返回 0:存在
uint8_t DS18B20_Init()
{ 
        
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = DS18B20_Port;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;//普通输出模式
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;//50MHz
	GPIO_InitStructure.Pull = GPIO_PULLUP;//上拉
	HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化
	DS18B20_Rst();
	return DS18B20_Check();
}

//从 ds18b20 得到温度值
//精度: 0.1C
//返回值:温度值 ( -550~1250)
short DS18B20_Get_Temp()
{ 
        
	uint8_t temp;
	uint8_t 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=(double)tem*0.625;//转换*10倍
	if(temp)
	{ 
        
		return tem; //返回温度值
	}
	else 
	{ 
        
		return -tem;
	}
}

DS18B20的温度通过 DS18B20_Get_Temp 函数读取,该函数的返回值为带符号的短整型数据,返回值的范围为-550~1250,其实就是温度值扩大了 10 倍。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章