【嵌入式模块】DS18B20 数字温度传感器

【嵌入式模块】DS18B20 数字温度传感器,第1张

【嵌入式模块】DS18B20 数字温度传感器

文章目录

参考链接DS18B20 主要特性DS18B20 引脚及内部结构【重要!】

引脚电路连接总体结构

1. 64位ROM2. 高低温报警寄存器TH,TL3. 高速缓冲存储器&温度寄存器4. 配置寄存器 DS18B20 工作时序

初始化(复位)写入字节读出字节 DS18B20 指令汇总

ROM指令RAM指令 例程

51单片机

参考链接

51黑电子论坛
CSDN
bilibili

DS18B20 主要特性

适应电压范围宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条线即可实现微处理器与DS18B20的双向通讯DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内测温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度快测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。 DS18B20 引脚及内部结构【重要!】 引脚

  其引脚如下图所示:

  这个传感器具有三个引脚,一个电源,一个地,一个信号传输引脚。

一般来说,这样的三个引脚的器件要么是输出0,1数字量,要么是输出一个模拟量,但DS18B20这个传感器输出的处理好的数字量,可见这个传感器的特殊之处。

电路连接

  DS18B20有两种电路连接方式:独立电源和寄生电源。独立电源即VDD引脚连接5V电源,这是最推荐的方式,也是最稳妥的方式。
  另一种连接方式是VDD也接地,器件电源的来源靠信号引脚DQ为高电平时给内部电容充电,因此这种连接方式要求DQ有强上拉。使用较少。

总体结构

  首先来看看两个版本的内部结构图,对比来看,内部结构更加清晰。


  从图中我们可以看出DS18B20共有五个主要模块:64位ROM高速缓冲存储器温度传感器高低温报警寄存器配置寄存器,下面将分别介绍。

可以发现,后面几个寄存器都属于EEPROM,即掉电不会消失,意味着配置后的传感器可以不用再配置(但保险起见,每次使用还是配置一下比较安心)

1. 64位ROM

  64位ROM中的64位序列号是出厂前被光刻好的,不能改变。它可以看作是该DS18B20的地址序列码。64位ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。

2. 高低温报警寄存器TH,TL

  高低温报警寄存器的结构如下图所示:

  TH和TL寄存器存储温度报警触发值,符号位S表示值是正还是负,对于正数,S=0,对于负数,S=1。 若被测温度低于或等于TL值,或高于或等于TH值,则器件内的一个报警标志位就会置位。当主设备发出报警搜索指令[EC]时,DS18B20就会对报警标志做出响应。这两个寄存器用户可以通过特定的指令修改。【见后面指令表】

3. 高速缓冲存储器&温度寄存器

  DS18B20的高速缓冲存储器由9个字节组成,其结构如下图所示。

  从低到高9个字节分别为:温度寄存器低8位,温度寄存器高8位,高温寄存器TH,低温寄存器TL,配置寄存器,3个保留寄存器,CRC校验寄存器。另外,值得一提的是,高速缓冲存储器属于RAM,掉电信息会消失,但一上电EEPROM中的数据会自动加载到高速RAM中。

  其中,两个温度寄存器用来存储温度传感器测量得到的温度,其结构如下图所示。

  其中S为符号位(正数S=0,负数S=1)。温度传感器的分辨率可由用户配置为9、10、11或12位,分别对应0.5℃、0.25 ℃、0.125℃和0.0625℃的增量。开机时的默认分辨率是12位。如果DS18B20配置为12位分辨率,那么温度寄存器中的所有位都将包含有效数据。对于11位分辨率,0位没有定义。对于10位分辨率,位1和0没有定义,对于9位分辨率,位2、位1和位0没有定义。
  注意:这张图很容易误导使用者,以为前面的只是符号位而已,从而会采用按位读取然后乘以权值的方式再加上符号来得到最后的温度值,但实际上这两个字节得到的是此时温度的补码!需要按照补码的计算方式来计算(除符号位外按位取反再加1)!另外,一般是直接读出寄存器的数值然后乘以0.0625来实现最后的移位 *** 作。且实际的温度值单位为摄氏度。

4. 配置寄存器

  配置寄存器的格式如下图所示

  其中,我们可以通过R1,R0两位来配置分辨率,如下表所示。

  器件上电默认状态为(R1, R0)=(1, 1),即12位分辨率。

DS18B20 工作时序

  根据DS18B20的通信协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位 *** 作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的 *** 作。

注意:是每一次 *** 作都需要先初始化(复位),再写入ROM指令,写入RAM指令。

初始化(复位)

  初始化时,要先将数据线拉低500us左右,然后释放,当DS18B20收到信号后等待15~60微秒左右,后发出60~240微秒的存响应负脉冲,即拉低总线。主CPU收到此信号表示复位成功。时序图如下图所示。

写入字节

  ROM指令和RAM指令都是靠单总线来写入一个字节的。因此写入字节时,要按照严格的时序要求来写入。

  写周期最少为60微秒,最长不超过120微秒。若主机想写0,则把总线拉低电平最少60微秒直至写周期结束。若主机想写1,则一开始主机先把总线拉低1微秒表示写周期开始,1微秒后就释放总线为高电平,一直到写周期结束。
  从DS18B20的角度来看,它在检测到总线被拉底后等待15微秒然后从15us到45us开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为0。

读出字节


  对于读数据 *** 作时序也分为读0时序和读1时序两个过程。读时序是从主机把单总线拉低之后,在1微秒之后就得释放单总线为高电平,以让DS18B20把数据传输到单总线上。
  DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。
  主机在一开始拉低总线1微秒后释放总线,然后在包括前面的拉低总线电平1微秒在内的15微秒时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为1。完成一个读时序过程,至少需要60us才能完成。

DS18B20 指令汇总 ROM指令 指 令约定代码功 能读ROM33H读DS1820温度传感器ROM中的编码(即64位地址)符合 ROM55H发出此命令之后,接着发出 64 位 ROM 编码,访问单总线上与该编码相对应的 DS1820 使之作出响应,为下一步对该 DS1820 的读写作准备。搜索 ROM0FOH用于确定挂接在同一总线上 DS1820 的个数和识别 64 位 ROM 地址。为 *** 作各器件作好准备。跳过 ROM0CCH忽略 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中。重调 EEPROM0B8H将EEPROM中内容恢复到RAM中的第3 、4字节。读供电方式0B4H读DS1820的供电模式。寄生供电时DS1820发送“ 0 ”,外接电源供电 DS1820发送“ 1 ”。 例程 51单片机
#include "reg52.h"
#define uint unsigned int
#define uchar unsigned char

sbit DSPORT = P3^7;   //DS18B20的DQ引脚


void Delay1ms(uint y)  //晶振为11.0592MHz
{
	uint x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}
void Delay1us(uint y)  //一个机器周期差不多1us
{
	while(y--);
}


uchar DS18B20_Init()
{
	DSPORT = 0;			
	Delay1us(500);  //将总线拉低500us   
	DSPORT = 1;	
	Delay1us(15); //然后拉高总线15us
	while(DSPORT)	//等待DS18B20拉低总线
	{
		Delay1ms(1);
		i++;
		if(i>5)//等待>5MS
		{
			return 0;//初始化失败
		}
	}
	return 1;//初始化成功
}


void DS18B20_WriteByte(uchar dat)
{
	uint i, j;
	for(j=0; j<8; j++)
	{
		DSPORT = 0;	     	  //每写入一位数据之前先把总线拉低1us
		i++;
		DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
		i=6;
		while(i--); //延时68us,持续时间最少60us
		DSPORT = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	}
}


uchar DS18B20_ReadByte()
{
	uchar byte, bi;
	uint i, j;	
	for(j=8; j>0; j--)
	{
		DSPORT = 0;//先将总线拉低1us
		i++;
		DSPORT = 1;//然后释放总线
		i++;
		i++;//延时6us等待数据稳定
		bi = DSPORT;	 //读取数据,从最低位开始读取
		
		byte = (byte >> 1) | (bi << 7);						  
		i = 4;		//读取完之后等待48us再接着读取下一个数
		while(i--);
	}				
	return byte;
}


void  DS18B20_Transform()
{
	DS18B20_Init();
	Delay1ms(1);
	DS18B20_WriteByte(0xcc);		//跳过ROM操作命令		 
	DS18B20_WriteByte(0x44);	    //温度转换命令
	//Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
}


void  DS18B20_ReadTempCom()
{
	DS18B20_Init()();
	Delay1ms(1);
	DS18B20_WriteByte(0xcc);	 //跳过ROM操作命令
	DS18B20_WriteByte(0xbe);	 //发送读取温度命令
}


int DS18B20_ReadTemp()
{
	int temp = 0;
	uchar tmh, tml;
	DS18B20_Transform();	    	//先写入转换命令
	DS18B20_ReadTempCom();			//然后等待转换完后发送读取温度命令
	tml = DS18B20_ReadByte();		//读取温度值共16位,先读低字节
	tmh = DS18B20_ReadByte();		//再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}

  注意:如果通过CPU延时,是不够准确的,但可以通过Keil的软件调试功能来相对精确地得到延时函数执行时间。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5710412.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存