【蓝桥杯】单片机学习笔记十三:DS18B20温度传感器应用详解
一、温度传感器-DS18B20介绍
DS18B20是单总线数字化温度传感器,测量温度范围是-55℃~+125℃,在-10℃~+85℃范围内,精度为±0.5℃。支持3V~5.5V的供电电压范围。DS18B20可以程序设定9~12位的分辨率,精度为±0.5℃。
1.DS18B20内部结构
DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20引脚配置如下所示:
DQ为数字信号输入/输出端,GND为电源地,VDD为外接供电电源输入端(在寄生电源接线方式时接地)。
(1)光刻ROM
光刻ROM中的64位序列号在出厂前已经被光刻好,可以看做是这个DS18B20的地址序列码。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20。
(2)温度传感器
DS18B20中的温度传感器可以完成对温度的测量,以12位转化为例:
用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。
12位转化后得到的数据存储在DS18B20的两个8bit的RAM中,二进制中的前5位是符号位,若温度大于0即温度为正,前五位全为0;若温度小于0即温度为负,则前五位全为1。若测量的温度为正,则该补码值乘上0.0625就是所测实际温度值;若测量温度为负,则该补码取反加1所得值乘上.0625才是实际温度值。
(3)存储器
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的E2RAM,后者存放高温度或低温度触发器TH、TL和机构寄存器。
高速暂存存储器包含了8个连续字节,前两个字节是测量的温度信息,第一个字节的内容是温度的低八位,第二个字节的内容是温度的高八位。第三个和第四个字节是TH、TL的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。第六、七、八个字节用于内部计算,第九个字节是冗余检验字节。
2.DS18B20使用中注意事项
DS18B20虽然具有测温系统简单、测温精度高、连接方便、占用口线少等优点,但实际应用汇总需要注意:
(1)较小的硬件开销需要相对复杂的软件进行补偿,DS18B20与微处理器之间是采用串行数据传送,在对DS18B20进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。
(2)实际应用中,单总线上所挂DS18B20的数量并非是任意个。当单总线上所挂DS18B20超过8个时,就需要解决微处理的总线驱动问题,这一点再进行多点测温系统设计中要加以注意。
(3)在DS18B20测温程序设计中,向DS18B20发出温度转换命令后,程序总要等待DS18B20的返回信号,一旦,某个DS18B20接触不好或断线,当程序读该DS18B20时,没有返回信号,程序进入死循环。这一点在进行DS18B20硬件连接和软件设计时要予以重视。
二、DS18B20程序设计流程
1. DS18B20复位。(复位是一个操作的开始,也是一个操作的结束)
2. 写入字节0xcc,跳过ROM指令。(DS18B20中有一个64位的ROM空间,该空间用于存放设备地址即设备ID号,如今只有一个DS18B20挂接在总线上,所以不需要去匹配设备ID,直接跳过设备匹配这一环节,直接进行温度转换)
3. 写入字节0x44,开始温度转换。
4. 延时700~900ms。(温度转换需要时间,等待温度转换完成再去读取温度,若没有延时,去读到的温度可能是上一时刻的温度值,会出现温度读取错误的情况)
5. DS18B20复位。
6. 写入字节0xcc,跳过ROM指令。
7. 写入0xbe,读取高速暂存器。(温度数据转换完成后存放在高速暂存器的第0字节和第1字节)
8. 读取高速暂存器的第0字节,即读取温度数据的低8位。
9. 读取高速暂存器的第1字节,即读取温度数据的高8位。
10. DS18B20复位。
11. 将低8位和高8位整合成一个16位数据。
12. 判断读取温度的符号,进行正负温度的数据处理。
三、程序
//**********************读取温度***************************/
uint temp = 0;
void read_DS18B20_temp()
{
uchar LSB,MSB; //LSB低八位,MSB高八位
//温度转换
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0x44); //开始温度转换
Delay_OneWire(200); //等待温度转换完成
//读温度
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0xbe); //开始读温度
//读温度
LSB = Read_DS18B20(); //读取低八位数据
MSB = Read_DS18B20(); //读取高八位数据
temp = MSB;
temp <<= 8; //高八位右移8位
temp = temp | LSB; //将独立的高、低8位合并为16位
if((temp & 0xf800) == 0x0000) //判断temp的高五位来判断温度的正负,高5位全为0表示为正,全为1表示负
{
temp >>= 4;
temp = temp * 10; //temp先右移四位在乘上10相当于整数部分乘以0.625倍
temp = temp + (LSB & 0x0f) * 0.625; //整数部分 * 0.625 + 小数部分 *0.625
}
}