温度传感器技术

STM32的DS18B20数字温度传感器设计

DS18B20 温度传感线不锈钢探头套件

DS18B20是数字温度传感器,使用单总线时序与主机通信. 仅有的 1 需要接线才能完成温度数据读取;

DS18B20内置64位产品序列号,方便识别. 可连接多个 DS18B20 传感器 1 金属丝, 并通过64位身份认证, 可分别读取不同传感器采集的温度信息.

DS18B20 温度传感线不锈钢探头套件

DS18B20 温度传感线不锈钢探头套件

DS18B20 温度传感器探头 TPE 包覆成型套件

DS18B20 温度传感器探头 TPE 包覆成型套件

1 线控DS18B20温度传感器

1 线控DS18B20温度传感器

DS18B20简介
2.1 DS18B20的主要特点
1. 全数字温度转换和输出.
2. 先进的单总线数据通信.
3. 高达 12 位分辨率, 精度高达±0.5摄氏度.
4. 12 位分辨率下的最大工作周期为 750 毫秒.
5. 可选择寄生工作模式.
6. 检测温度范围 –55°C ~+125°C (–67°F ~+257°F).
7. 内置EEPROM, 温度超限报警功能.
8. 64-位光刻ROM, 内置产品序列号, 方便多机连接.
9. 多种包装形式, 适应不同的硬件系统.

DS18B20芯片封装结构

DS18B20芯片封装结构

2.2 DS18B20引脚功能
GND 电压地;
DQ单数据总线;
VDD电源电压;
NC空针;

DS18B20芯片RAM和EEPROM结构图

DS18B20芯片RAM和EEPROM结构图

2.3 DS18B20工作原理及应用
DS18B20 温度检测和数字数据输出完全集成在一颗芯片上, 因此具有更强的抗干扰能力. 其一个工作循环可分为两个部分, 即温度检测和数据处理.

18B20具有三种形式的内存资源. 他们是: ROM只读存储器, 用于存储DS18B20ID码; 第一个 8 位是单行系列代码 (DS18B20代码为19H), 下列 48 位是芯片的唯一序列号; 最后一个 8 位是 CRC 码 (冗余校验) 上述的 56 位. 数据在生产时设置,用户无法更改. DS18B20共有 64 ROM 位.

RAM数据寄存器, 用于内部计算和数据访问, 断电后数据丢失, DS18B20共有 9 RAM 字节, 每个字节是 8 位. 第一、二字节为温度转换后的数据值信息; 第三和第四字节是用户EEPROM的镜像 (常用于温度报警值存储). 当电源复位时其值会被刷新. 第五个字节是用户第三个EEPROM的镜像. 第六号, 7th, 第8个字节是计数寄存器, 旨在让用户获得更高的温度分辨率. 它们也是内部温度转换和计算的临时存储单元. 第9个字节是第一个字节的CRC码 8 字节. EEPROM是一种非易失性存储器,用于存储需要长期保存的数据, 上、下温度报警值, 和验证数据. DS18B20共有 3 EEPROM 位, RAM中有镜像,方便用户操作.

DS18B20默认工作在12位分辨率模式. 转换后得到的12位数据存储在DS18B20的两个8位RAM中 (前两个字节). 第一个 5 二进制中的位是符号位. 如果测量的温度大于 0, 这些 5 位是 0. 只需将测量值乘以 0.0625 获取实际温度. 如果温度低于 0, 这些 5 位是 1. 测量值需要取反, 添加者 1, 然后乘以 0.0625 获取实际温度. 或者使用位运算提取温度: 小数点占据较低位 4 位, 高位为整数位 (不考虑负数).

2.4 DS18B20芯片ROM指令表
1. 读取ROM [33H] (十六进制命令字在方括号中).
该命令允许总线控制器读取DS18B20的64位ROM. 该指令仅当总线上只有一个DS18B20时才能使用. 如果连接了多个, 通信过程中会出现数据冲突.

2. 补丁ROM [55H]
该指令后面跟着控制器发出的 64 位序列号. 当总线上有多个DS18B20时, 只有与控制器发出的序列号相同的芯片才能响应, 其他芯片将等待下一次复位. 该指令适用于单片机和多片机连接.

3. 跳过ROM [中西医结合中心]
该指令使芯片不响应ROM代码. 单总线情况下, 该指令可用于节省时间. 如果连接多个芯片时使用该指令, 会发生数据冲突, 导致错误.

4. 搜索ROM [调频]
芯片初始化后, 当多个芯片连接到总线上时,搜索指令允许通过消除来识别所有设备的64位ROM.

5. 报警搜索 [每个]
多芯片情况下, 报警芯片搜索指令只响应满足温度高于TH或低于TL报警条件的芯片. 只要芯片没有断电, 报警状态将一直保持,直到再次测量温度且未达到报警条件为止.

6. 写便签本 [4埃希]
这是将数据写入RAM的指令. 随后写入的两个字节数据将存储在地址 2 (报警RAM的TH) 和地址 3 (报警RAM的TL). 写过程可以通过复位信号终止.

7. 阅读便签本 (从 RAM 中读取数据) [贝赫]
该指令将从 RAM 中读取数据, 从地址开始 0 直至地址 9, 完成整个RAM数据的读取. 芯片允许复位信号终止读取过程, 那是, 可以忽略后续不必要的字节以减少读取时间.

8. 复制便签本 (将 RAM 数据复制到 EEPROM) [48H]
该指令将RAM中的数据存储到EEPROM中,这样断电时数据不会丢失. 由于芯片正忙于 EEPROM 存储处理, 当控制器发送读时隙时, 总线输出 “0”, 当存储工作完成时, 总线将输出 “1”.
寄生工作模式, 该指令发出后必须立即使用强上拉并保持至少10MS以维持芯片运行.

9. 转换 T (温度转换) [44H]
收到此指令后, 芯片将进行温度转换并将转换后的温度值存储在RAM的第1和第2地址中. 由于芯片正忙于温度转换处理, 当控制器发送读时隙时, 总线输出 “0”, 当存储工作完成时, 总线将输出 “1”. 寄生工作模式, 该指令发出后必须立即使用强上拉并保持至少 500MS 以维持芯片运行.

10. 召回EEPROM (将EEPROM中的报警值复制到RAM中) [B8H]
该指令将EEPROM中的报警值复制到RAM中的第3和第4字节. 由于芯片正忙于复制处理, 当控制器发送读时隙时, 总线输出 “0”, 当存储工作完成时, 总线输出 “1”. 此外, 该指令在芯片上电复位时会自动执行. 这样, RAM 中的两个报警字节位始终是 EEPROM 中数据的镜像.

11. 读取电源 (工作模式切换) [B4H]
此指令发出后, 发出读取时间间隙, 芯片将返回其电源状态字. “0” 是寄生功率状态并且 “1” 是外部电源状态.

2.5 DS18B20时序图
2.5.1 DS18B20复位与响应关系图
每次通信之前必须执行重置. 重置时间, 等待时间, 响应时间应严格按照时间安排.
DS18B20读写时间间隙: DS18B20数据读写是通过时间间隙处理位和命令字来交换信息来确认的.

DS18B20复位与响应关系图

DS18B20复位与响应关系图

2.5.2 写入数据 0 和数据 1 至 DS18B20
在写数据时间间隙的前15uS内, 总线需要被控制器拉低, 然后就是芯片对总线数据的采样时间. 采样时间15~60uS. 如果控制器在采样时间内将总线拉高, 这意味着写作 “1”, 如果控制器将总线拉低, 这意味着写作 “0”.
每一位传输应有至少15uS的低电平起始位, 以及后续数据 “0” 或者 “1” 应在45uS内完成.
整个bit的传输时间应保持在60~120uS, 否则无法保证正常通讯.
笔记: DS18B20从低位开始读写数据.

写入数据 0 和数据 1 至 DS18B20

写入数据 0 和数据 1 至 DS18B20

2.5.3 读取数据 0 和数据 1 来自 DS18B20
读取时间间隙期间控件的采样时间应该更准确. 在读取时间间隔期间, 主机还必须产生至少1uS的低电平来指示读取时间的开始. 然后, 总线释放后15uS内, DS18B20将发送内部数据位. 此时, 如果控制器发现总线为高电平, 这意味着阅读 “1”, 如果总线很低, 意思是读取数据 “0”. 读取每一位之前, 控制器添加启动信号.

读取数据 0 和数据 1 来自 DS18B20

读取数据 0 和数据 1 来自 DS18B20

笔记: 数据位必须在读取间隙开始后 15uS 内读取,以确保正确通信.

沟通过程中, 8 的位 “0” 或者 “1” 被用作一个字节, 并且字节的读或写是从低位开始的.

2.5.4 一次读取温度顺序 (总线上只有一个 DS18B20)

1. 发送复位信号
2. 检测响应信号
3. 发送0xCC
4. 发送0x44
5. 发送复位信号
6. 检测响应信号
7. 写入0xcc
8. 写入0xbe
9. 环形 8 读取温度低字节的次数
10. 环形 8 读取温度高字节的次数
11. 合成16位温度数据并处理

3. 驱动程序代码

3.1 DS18B20.c
#包括 “ds18b20.h”
/*
功能: DS18B20初始化
硬件连接: PB15
*/
无效 DS18B20_Init(空白)
{
RCC->APB2ENR|=1<<3; //PB
GPIOB->CRH&=0x0FFFFFFF;
GPIOB->CRH|=0x30000000;
GPIOB->奥德罗|=1<<15; //引体向上
}

/*
功能: 检查DS18B20设备是否存在
返回值: 1 表示设备不存在 0 表示设备正常
*/
u8 DS18B20_CheckDevice(空白) //包含复位脉冲, 检测脉冲
{
DS18B20_输出_模式();//初始化为输出模式
DS18B20_OUT=0; //产生复位脉冲
耽误我们(750); //产生750us低电平
DS18B20_OUT=1; //发布总线
耽误我们(15); //等待DS18B20响应
如果(DS18B20_CleckAck())//检测存在脉冲
{
返回 1;
}
返回 0;
}

/*
功能: 检测DS18B20器件的存在脉冲
返回值: 1 表示错误 0 表示正常
*/
u8 DS18B20_CleckAck(空白)
{
u8 碳纳米管=0;
DS18B20_输入模式();//初始化为输入模式
尽管(DS18B20_IN&&碳纳米管<200) //等待DS18B20响应存在脉冲
{
耽误我们(1);
cnt++;
}
如果(碳纳米管>=200)返回 1; //错误

碳纳米管=0;
尽管((!DS18B20_IN)&&碳纳米管<240) //等待DS18B20释放总线
{
耽误我们(1);
cnt++;
}
如果(碳纳米管>=240)返回 1; //错误
返回 0;
}

/*
功能: 写入一个字节
首先学习如何写一点.
*/
无效 DS18B20_WriteByte(u8命令)
{
u8我;
DS18B20_输出_模式(); //初始化为输出模式
为了(我=0;我<8;我++)
{
DS18B20_OUT=0; //生成写入时间间隙 (写开始)
耽误我们(2);
DS18B20_OUT=cmd&0x01; //发送实际数据位
耽误我们(60); //等待写入完成
DS18B20_OUT=1; //释放总线并准备下一次传输
指令>>=1; //继续发送下一位数据
}
}

/*
功能: 读取一个字节
首先学习如何阅读.
*/
u8 DS18B20_ReadByte(空白)
{
u8我,数据=0;
为了(我=0;我<8;我++)
{
DS18B20_输出_模式(); //初始化为输出模式
DS18B20_OUT=0; //生成读取时间间隙 (读开始)
耽误我们(2);
DS18B20_OUT=1; //发布总线
DS18B20_输入模式(); //初始化为输入模式
耽误我们(8); //等待DS18B20数据输出
数据>>=1; //填充高位 0, 默认是 0
如果(DS18B20_IN) 数据|=0x80;
耽误我们(60);
DS18B20_OUT=1; //发布总线, 等待读取下一位数据
}
返回数据;
}

/*
功能: 读取一次DS18B20的温度数据
返回值: 读取的温度数据
考虑的情况: 总线上只有一个DS18B20
*/
u16 DS18B20_ReadTemp(空白)
{
u16 温度=0;
u8 温度_H,温度_L;
DS18B20_检查设备(); //发送复位脉冲, 检测脉搏
DS18B20_WriteByte(0xCC); //跳过 ROM 序列检测
DS18B20_WriteByte(0x44); //开始温度转换

//等待温度转换完成
尽管(DS18B20_读字节()!=0xFF){}

DS18B20_检查设备(); //发送复位脉冲, 检测脉搏
DS18B20_WriteByte(0xCC); //跳过 ROM 序列检测
DS18B20_WriteByte(0乙醚); //读取温度

temp_L=DS18B20_ReadByte(); //读取低温数据
temp_H=DS18B20_ReadByte(); //读取高温数据
温度=temp_L|(温度_H<<8); //合成温度
返回温度;
}

3.2 DS18B20.h

#ifndef DS18B20_H
#定义DS18B20_H
#包括 “stm32f10x.h”
#包括 “系统文件h”
#包括 “延迟.h”
#包括 “ds18b20.h”
#包括 “usart.h”

/*封装接口*/

//将 DS18B20 初始化为输入模式
#定义DS18B20_INPUT_MODE() {GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x80000000;}

//将 DS18B20 初始化为输出模式
#定义DS18B20_OUTPUT_MODE(){GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x30000000;}

//DS18B20 IO口输出
#定义 DS18B20_OUT PBout(15)

//DS18B20 IO口输入
#定义 DS18B20_IN PBin(15)

//函数声明
u8 DS18B20_CleckAck(空白);
u8 DS18B20_CheckDevice(空白);
无效 DS18B20_Init(空白);
u16 DS18B20_ReadTemp(空白);
u8 DS18B20_ReadByte(空白);
无效 DS18B20_WriteByte(u8命令);
#恩迪夫

poYBAGDYdXCAWkKMAAAK8RNs4s030.png
3.3 延时功能

/*
功能: 我们的延误
*/
无效延迟(国际我们)
{
#ifdef _SYSTICK_IRQ_
整数我,j;
为了(我=0;iVAL=0; //CNT计数器值
系统标记->负载=9*us; //9 表示1us
系统标记->控制键|=1<<0; //启动定时器

{
tmp=SysTick->控制键; //读取状态
}尽管((!(tmp&1<<16))&&(tmp&1<<0));
系统标记->值=0; //CNT计数器值
系统标记->控制键&=~(1<<0); //关闭定时器
#恩迪夫
};我++)>

3.4 main.c 调用DS18B20读取温度并打印到串口

#包括 “stm32f10x.h”

#包括 “ds18b20.h”

u8 DS18B20_ROM[8]; //存储DS18B20的64位ROM代码

整型主(空白)
{
u16 温度;
USARTx_Heat(USART1,72,115200);//串口初始化 1
DS18B20_热(); //DS18B20初始化

/*1. 读取DS18B20的64位ROM代码*/
//发送复位脉冲, 检测存在脉冲
尽管(DS18B20_检查设备())
{
打印函数(“DS18B20设备不存在!\n”);
延迟时间(500);
}
//发送命令读取64位ROM代码
DS18B20_WriteByte(0x33);

//循环读取64位ROM代码
为了(我=0;我<8;我++)
{
DS18B20_ROM[我]= DS18B20_ReadByte();
打印函数(“DS18B20_ROM[%d]=0x%Xn”,我,DS18B20_ROM[我]);
}

尽管(1)
{
/*2. 同时操作总线上所有DS18B20开始转换温度*/
DS18B20_检查设备(); //发送复位脉冲, 检测脉搏
DS18B20_WriteByte(0xCC); //跳过 ROM 序列检测
DS18B20_WriteByte(0x44); //开始温度转换 (让总线上的所有DS18B20转换温度)
延迟时间(500); //等待线上所有DS18B20温度转换完成

/*3. 单次定向读取每个 DS18B20 的温度*/
DS18B20_检查设备(); //发送复位脉冲, 检测脉搏
DS18B20_WriteByte(0x55); //发送命令匹配ROM
为了(我=0;我<8;我++) //发送 64 位代码
{
DS18B20_WriteByte(DS18B20_ROM[我]);
}
DS18B20_WriteByte(0乙醚); //读取温度
临时=DS18B20_ReadByte(); //读取低阶温度数据
温度|=DS18B20_ReadByte()<<8; //读取高阶温度数据
打印函数(“temp1=%d.%dn”,温度>>4,温度&0xF);
打印函数(“温度2=%fn”,温度*0.0625);

延迟时间(500);
}
}