使用DS18B20温度传感器的说明
DS18B20 – 温湿度监测模块
芯片介绍
基础介绍\引脚介绍
DS18B20是单总线协议的典型代表,同时也是单总线协议最广泛的应用场景,是常用的数字温度传感器,其输出的是数字信号。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合。
DS18B20 的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。在讲解其工作流程之前我们有必要了解 18B20 的内部存储器资源。 18B20 共有三种形态的存储器资源,它们分别是:ROM 只读存储器,用于存放 DS18B20ID 编码,其前 8 位是单线 系列编码(DS18B20 的编码是 19H),后面 48 位是芯片唯一的序列号,最后 8 位是以上 56 的位的 CRC 码 (冗余校验)。数据在出产时设置不由用户更改。
DS18B20 共 64 位 ROM。RAM 数据暂存器,用于内部计算和数据存取,数据在掉电后丢失,DS18B20 共9 个字节 RAM,每个字节为 8 位:
第 1、 2 个字节是温度转换后的数据值信息,
第 3、 4 个字节是用户 EEPROM(常用于温度报警值储存)的镜像。在上电复位时其值将被刷新。
第 5 个字节则是用户第 3 个 EEPROM的镜像。
第 6、 7、 8 个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也 是内部温度转换、计算的暂存单元。
第 9 个字节为前 8 个字节的 CRC 码。
RAM内容如下图,最常用为前两个字节数据,其余数据由于操作方式没有直接在控制端操控方便,一般很少使用。
EEPROM 非易失性记忆体,用于 存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20 共 3 位 EEPROM,并在 RAM 都存在镜像,以方便用户操作。
其引脚图如下:
DS18B20仅有三根引脚,其中一根接电源,一根接地,即其仅使用一根引脚用于数据命令等的传输,由于没有时钟线,其为异步传输,对传输时序要求极高。
DQ:DS18B20传输线,采用单总线,详见协议使用笔记单总线章节
操作控制流程
每次通信必须经过如下步骤,且对时序有较高要求,延时部分需使用滴答定时器等进行精准延时。
1.复位:单片机拉低DQ线至少480us,DS18B20接收到信号后会在15 – 60us内发送存在脉冲。
2.存在脉冲:复位信号结束后,应将DQ线拉高以接收存在脉冲,该脉冲为一个60 – 240us的低电平
3.发送ROM指令:共有五条指令可供发送,每条指令为8位数据,每个周期仅可发送一条。五条指令如下:
若不需要对ROM进行操作,则可使用跳跃ROM指令跳过该阶段。
4.发送存储器操作指令:共有六条指令可供发送,每条指令为8位数据,每个周期仅可发送一条。指令如下:
5.执行或数据读写:在此将会进行数据的读写或指令执行,由以上命令确定。若执行转换指令,则需要等待500us左右的转换时间,若执行读写指令,则需要根据DS18B20时序要求进行读写。
时序介绍
复位应答时序
写时间隙时序
写时间隙由控制端将总线拉低15us左右,后在其低电平状态下进行控制,若要发送1则在拉低后将总线拉高15 – 45us
若要发送0则保持该低电平15 – 45us,尔后将总线重新拉高。
注意:单bit的发送时间应在60 – 120us内,否则将不能进行通信。
读时间隙时序
读时间隙需要先由控制端拉低总线1us左右,并释放总线,在释放后的15us中,从机接管总线并发送数据,此时高电平表示1,低电平表示0,每一个bit的读取都需要先由总线拉低总线1us。
注意:字节的读写由低位开始,由高位结束。
读取数据
读取一次温度信息的步骤:
发送复位信号 –> 检测回应信号 –> 发送0xCC –> 发送0x44 –> 发送复位信号 –> 检测回应信号 –> 写0xCC –> 写0xBE –> 循环 8 次读取温度低字节 –> 循环 8 次读取温度高字节
其它操作与此类似,不做过多介绍。
代码示例
变量介绍
DS18B20_OUTPUT() //设置为输出模式
DS18B20_DQ_OUT //DQ线输出
DS18B20_INPUT() //设置为输入模式
DS18B20_DQ_IN //DQ线输入
读数据(从DS18B20读)
u8 DS18B20_Read_Byte(void)
{
u8 i, rxData = 0;
DS18B20_DQ_OUT = 1; //DQ输出为高
for(i=0; i<8; i++)
{
DS18B20_OUTPUT(); //设置为输出模式
DS18B20_DQ_OUT = 0; //拉低总线(释放总线)
delayUs(5); //等待1us以上
DS18B20_INPUT(); //切换为输入模式
delayUs(10);
if(DS18B20_DQ_IN) rxData |= 1<<i; //此时总线电平已改变,判断电平
delayUs(40);
DS18B20_DQ_OUT = 1; //接管总线,等待下一次释放
delayUs(5);
}
return rxData;
}
写数据(从DS18B20写)
void DS18B20_Write_Byte(u8 txData)
{
u8 i;
DS18B20_OUTPUT(); //设置为输出模式
for(i=0; i<8; i++)
{
if(txData & 0x01) //低位先发
{
DS18B20_DQ_OUT = 0; //拉低总线
delayUs(5);
DS18B20_DQ_OUT = 1; //该位为高,拉高总线,延时
delayUs(55);
}
else
{
DS18B20_DQ_OUT = 0; //拉低总线
delayUs(5);
delayUs(55); //该位为低,保持总线低,延时
DS18B20_DQ_OUT = 1; //重新拉高,等待下一次
}
txData >>= 1;
}
}