DS18B20数字温度传感器

DS18B20是一种数字温度传感器,由美国达拉斯半导体公司生产。

具有以下特征:

1. 单线传输:DS18B20使用单线传输协议(1-Wire)进行通信,只需要一个数据线就可以实现数据传输和电源供应。

2. 高精度:DS18B20可以测量范围为-55°C至+125°C的温度,精度为±0.5°C(在-10°C至+85°C范围内)。

3. 数字输出:DS18B20输出数字温度值,可以直接与数字系统集成,不需要进行模拟信号转换。

4. 多点测量:通过1-Wire总线,可以连接多个DS18B20传感器,实现多点温度测量。

5. 低功耗:DS18B20具有低功耗特性,工作时只需要极低的能量,可以通过1-Wire总线实现供电。

6. 内部存储:DS18B20具有内部存储器,可以存储自身序列号和温度校准系数等信息,方便管理和配置。

管脚描述

VDD 引脚。当采用“寄生电源”供 电时,VDD 必须连接到地VDD
数据输入/输出。1-Wire 漏极开路接口引脚。当采用“寄生电源”供电方式时,同时向设备提供电源。DQ
GND

内部结构框图

寄生电源电路控制寄生电源供电或者VDD供电
64位Bit ROM作为器件地址,用于总线通信的地址
内存控制逻辑单元控制Read or Write
暂存器用于总线的数据交互(RAM)

供电方式


单总线电路规范

  • 设备的DQ均要配置成开漏输出模式
  • DQ添加一个4.7KΩ的上拉电阻
  • 若总线的从机采取寄生供电,则主机还应该配置一个强上拉输出

DS18B20操作流程

  1. 初始化:从机复位,主机判断从机是否相应
  2. ROM操作:ROM指令+本指令需要的读写操作
  3. 功能操作:功能指令+本指令需要的读写操作

ROM指令

搜索ROM[F0h]匹配ROM[55h]
读取ROM[33h]跳过ROM[CCh]
警报搜索[ECh]

 

 

功能指令

温度转换[44h]写入暂存寄存器[4Eh]
读取暂存寄存器[BEh]拷贝暂存寄存器[48h]
召回 EEPROM[B8h]读取供电模式[B4h]

 

单总线时序结构

初始化

在初始化序列期间,总线上的主设备通过拉低 1-Wire 总线超过 480us 来发送(TX)复位脉冲。 之后主设备释放总线而进入接收模式(RX)。当总线释放后,5kΩ左右的上拉电阻将 1-Wire 总线 拉至高电平。当 DS18B20 检测到该上升边沿信号后,其等待 15us 至 60us 后通过将 1-Wire 总线拉 低 60us 至 240us 来实现发送一个存在脉冲。

 

写入一位

写时段有两种情况:“写 1”时段和“写 0”时段。
为了形成写 1 时段,在将 1-Wire 总线拉低后,主设备必须在 15us 之内释放总线。当总线释放后,5kΩ的上拉电阻将总线拉至高。
为了形成写 0 时段,在将 1-Wire 总线拉低后,在整个时段 期间主设备必须一直拉低总线(至少 60us)
在主设备初始化写时段后,DS18B20 将会在 15us 至 60us 的时间窗口内对总线进行采样。如果总线在采样窗口期间是高电平,则逻辑 1 被写入 DS18B20;若总线是低电平,则逻辑 0 被写入 DS18B20。

 

 

读出一位

主设备在执行完读暂存寄存器[BEh] 或读取供电模式[B4h]后,必须及时地生成读时段,这样 DS18B20 才能提供所需的数据。
每个读时段最小必须有 60us 的持续时间且独立的写时段间至少有 1us 的恢复时间。
读时段通 过主设备将总线拉低超过 1us 再释放总线来实现初始化。当主设备初始化完读时段后, DS18B20 将会向总线发送 0 或者 1。
从 DS18B20 中输出的数据在初始化读时序后仅有 15us 的有效时间。因此,主设备 在开始读时段后的 15us 之内必须释放总线,并且对总线进行采样。

 

写入一个字节

写入一位×8

读出一个字节

读出一位×8

温度存储格式

温度是以一个Byte的LSB和MSB共同存储。
其中MSBtye的前5位是符号位,都为0则为正,都为1则为负;LSByte的后四位为小数位。
所以要读取到完整的温度,先将LSByte和MSByte合并(MSB左移八位, | 上LSByte存储到int类型的变量中),但又因为LSB后四位为小数位,和正常的八位二进制相对比,等于将2的零次方向左移动了四位,扩大了16倍,所以要将int类型的变量除以16,但为保持精度(小数位),应除以16.0.

代码(不同模块)
使用STC89C52RC

/*
    读写一位和一个字节模块
*/

#include <REGX52.H>

sbit OneWire_DQ = P3^7;

/**
  * @brief 初始化
  * @param 无
  * @retval AckBit 1为从机不存在 0为从机存在(发送了一个存在脉冲)
  */
unsigned char OneWire_Init(void)
{	
	unsigned char i;
	unsigned char AckBit;
	OneWire_DQ = 1;
	OneWire_DQ = 0;

	//Delay 500us
	i = 247;while (--i);
	
	OneWire_DQ = 1;

	//Delay 70us
	i = 32;while (--i);
	
	AckBit = OneWire_DQ;

	//Delay 500us
	i = 247;while (--i);
	
	return AckBit;
}

/**
  * @brief 写入一位数据
  * @param Bit 要写入的一位数据
  * @retval 无
  */
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ = 0;
	
	i = 4;while (--i);	 //Delay 10us
	
	OneWire_DQ = Bit;
	
	i = 24;while (--i);	 //Delay 50us
	
	OneWire_DQ = 1;
}

/**
  * @brief 接收一位数据
  * @param 无
  * @retval Bit 接收的一位数据
  */
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i;	
	unsigned char Bit;
	OneWire_DQ = 0;
	i = 2;while (--i);	 //Delay 5us
	OneWire_DQ = 1;
	i = 2;while (--i);	 //Delay 5us
	Bit = OneWire_DQ;
	i = 24;while (--i);	 //Delay 50us	
	return Bit;
}

/**
  * @brief 发送一个字节的数据
  * @param 要发送的一个字节的数据
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0; i<8; i++)
	{
		//低位在前
		OneWire_SendBit(Byte & (0x01 << i));
	}
	
}

/**
  * @brief 接收一个字节的数据
  * @param 无
  * @retval Byte 接收的一个字节的数据
  */
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte = 0x00;
	for(i=0; i<8; i++)
	{
		if(OneWire_ReceiveBit())
		{
			//低位在前
			Byte |= 0x01 << i;
		}	
	}
	return Byte;
}
/*
    DS18B20温度变换与温度读取
*/

#include <REGX52.H>
#include "OneWire.h"

#define DS18B02_SKIP_ROM          0xCC
#define DS18B02_CONVERT_T         0x44
#define DS18B02_READ_SCRATCHPAD   0xBE

/**
  * @brief 温度转换
  * @param 无
  * @retval 无
  */
void DS18B20_ConvertT(void)
{
	OneWire_Init();
	OneWire_SendByte(DS18B02_SKIP_ROM);
	OneWire_SendByte(DS18B02_CONVERT_T);
}

/**
  * @brief 读出暂存寄存器
  * @param 无
  * @retval T 温度寄存器中的数据
  */
float DS18B20_ReadT(void)
{
	unsigned char TLSB, TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B02_SKIP_ROM);
	OneWire_SendByte(DS18B02_READ_SCRATCHPAD);
	TLSB = OneWire_ReceiveByte();
	TMSB = OneWire_ReceiveByte();
	Temp = (TMSB << 8) | TLSB;
	T = Temp / 16.0;
	return T;
}
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "OneWire.h"
#include "DS18B20.h"

float T;

void main()
{
	DS18B20_ConvertT();
	Delay(1000);
	LCD_Init();
	while(1)
	{
		KeyNum = Key();
		DS18B20_ConvertT();
		T = DS18B20_ReadT();
		if(T<0)
		{
			LCD_ShowChar(2,1,'-');
			T = -T;
		}
		else
		{
			LCD_ShowChar(2,1,'+');
		}
		LCD_ShowNum(2,2,T,3);
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(TShow*10000)%10000,4);//取出小数点后四位
	}
}

使用DS18B20的核心就是掌握时序的Delay以实现不同功能。

菜鸡扩展:如果1-Write上有多个DS18B20,则不能直接跳过ROM,要先搜索ROM(使得主设备确定总线上所有的从设备(好像要用到二叉搜索树算法)),再通过ROM编码去匹配ROM匹配不同的从机(发送64位的ROM编码,去匹配特定的从机),使得能让特定的从机执行特定的功能。
该文只是基于一个DS18B20,所以可以直接跳过ROM,或者能去直接读取ROM。

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值