摘要:本文介绍如何使用DS18B20进行温度测量
测量温度是硬件开发中经常要遇到的一个功能需求,最早的时候,都是使用热敏电阻,给它通一个已知的电流,然后测量其两端的电压,这样就可以反算出热敏电阻的阻值,然后在根据拟合的公式或者直接查表就可以得到需要测量的温度了。这个方法是相当复杂的,而且易受外界环境的影响,从而造成准确度下降。现在的温度测量已经没有那么复杂了,有现成的集成芯片或者模块可以使用,一般都是数字接口,只要按照协议,就能方便的得到被测的温度值了。
对于ESP32来说,有些型号的芯片是内置温度测量功能的,但这个温度测量只是测量集成电路的核心温度,实用性不强,几乎不可能拿来实现外部环境温度的测量。所以,最新的大部分ESP32芯片,已经取消了这个功能。
现在可以用来测量温度的芯片有很多,在本文介绍DS18B20芯片的用法,接下来还会介绍DHT11的用法,其中DHT11还有测量湿度的功能。
DS18B20是一款数字温度传感器,它采用了独特的单线接口,也就是只利用一根数据线,就可以完成指令和数据的传递工作。这就使得连接更加简单和方便。该传感器能够在-55℃至+125℃的温度范围内进行测量,其体积小、硬件开销低、抗干扰能力强、高精度和高可靠性。通过数字信号输出,可以方便地与微处理器进行连接,实现温度的实时监测和控制。DS18B20适合于各种温度测量和控制的应用场景,如空调系统、冰箱、热水器、智能家居等。
DS18B20有三种封装形式,分别是:TO-92封装、标准SOIC 8引脚封装和TSSOP封装,最经常用到的是TO-92封装,像普通的三极管一样,如下图所示:
DS18B20一共有三个引脚,分别是:
GND:电源地线
DQ:数字信号输入/输出端。
VDD:外接供电电源输入端。
在设计和使用DS18B20的时候,要注意DQ端为漏极开路输出,直接与单片机GPIO引脚相连接后,只能输出低电平,不能输出高电平,因此一定要有上拉电阻才行。
DS18B20的另一个特点是不需要在外部供电下即可工作。芯片的数字信号线加上拉电阻后,当总线高电平时可经过DQ引脚获得芯片所需要的能量。同时还会给一个内部电容充电,当总线变为低电平时,则由此电容提供能量,保证芯片可以正常运行。这种供电方法被称为“寄生电源”。这样,最少只需要2根导线,DS18B20就可以正常工作了。当然,有条件的,通过电源线VDD供电会更好。
DS18B20采用了宽电压供电,适用的电压范围在2.5V~5.5V之间。温度的测量范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±0.4℃。DS18B20是一款数字测温芯片,每次可以获得16位二进制数表示的温度值。这16位二进制数的高五位表示温度的正负,如果全为1,则测量的温度为正,如果全为0,则测量的温度为负。其测量温度的分辨率可以在9、10、11和12之间选择,默认为12位分辨率。
DS18B20在出厂的时候,为每一个芯片内部设置了一个64位独有的序列号,任何两个芯片的序列号均不相同,这个序列号就是这个芯片的唯一标识。这个序列号通常也被看作地址序列码,这样就实现了一根总线可以挂接多个DS18B20的目的,以满足需要多点测量的情况。
DS18B20的工作步骤可以分为三步:
1.初始化DS18B20
DS18B20的单总线在平时是高电平的,单片机首先要发出一个复位脉冲,也就是将总线拉低至低电平,并保持480us以上。这时,连接到总线的DS18B20在检测到复位脉冲后,也会发出一个低电平脉冲,这个脉冲的宽度在60us~240us之间,表示有DS18B20设备存在。
2.执行ROM指令
在上面的初始化中,如果单片机收到了DS18B20返回的低电平脉冲,那么就确认了有DS18B20挂接在总线上,这时就可以执行ROM命令了。可以执行的ROM命令如下所示:
指令名称 | 指令代码 | 指令功能 |
读ROM | 33H | 读取DS18B20 ROM中的编码(即读64位地址) |
ROM匹配(符合ROM) | 55H | 发出此命令之后,接着发出64位ROM编码,访问单总线上与编码相对应DS18B20使之作出响应,为下一步对该DS18B20的读写作准备 |
搜索ROM | 0F0H | 用于确定挂接在同一总线上DS18B20的个数和识别64位ROM地址,为操作各器件作好准备 |
跳过ROM | 0CCH | 忽略64位ROM地址,直接向DS18B20发温度变换命令,适用于单片机工作 |
警报搜索 | 0ECH | 该指令执行后,只有温度超过设定值上限或下限的芯片才做出响应 |
当总线上有多个DS18B20时,需要ROM匹配指令来控制总线上的某个DS18B20响应下一步的指令。如果总线上只有一个DS18B20,可以直接使用跳过ROM指令来进入下一步。
3.执行DS18B20功能指令
接下来就可以执行具体的DS18B20指令了,常用的指令如下所示:
指令名称 | 指令代码 | 指令功能 |
温度变换 | 44H | 启动DS18B20进行温度转换,转换时间最长为500ms(典型为200ms),结果存入内部9字节RAM中 |
读暂存器 | OBEH | 读内部RAM中9字节的内容 |
写暂存器 | 4EH | 发出向内部RAM的第3、4字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据 |
复制暂存器 | 48H | 将RAM中第3,4字节的内容复制到EEPROM中 |
重调EEPROM | 0B8H | EEPROM中的内容恢复到RAM中的第3、4字节 |
读供电方式 | 0B4H | 读DS18B20的供电模式,寄生供电时DS18B20发送“0”,外接电源供电DS18B20发送“1” |
虽然DS18B20芯片在使用中不需要任何外围元件,独立芯片即可完成工作。但为了使用方便,还是选用了DS18B20的测温模块,这个模块除了DS18B20外,还有一个上拉电阻和一个电源指示的LED,如下图所示:
DS18B20模块的VCC接电源正极(+5V),DQ接ESP32的GPIO引脚,GND接到开发板的地就可以了。
下面就来打开Mixly开发软件,选择“Arduino ESP32”开发板,DS18B20在传感器功能模块中,只需要指定DQ连接的管脚就可以了。在这里,直接将测量的结果输出到了COM口,具体如下所示:
然后,编译、上传程序,在COM口就可以看到当前环境下的温度数据了,如下图所示:
接着,再来看一下源代码。如下所示:
#include <OneWire.h> #include <DallasTemperature.h> OneWire oneWire_32(32); DallasTemperature sensors_32(&oneWire_32); DeviceAddress insideThermometer; float ds18b20_32_getTemp(int w) { sensors_32.requestTemperatures(); if(w==0) { return sensors_32.getTempC(insideThermometer); } else { return sensors_32.getTempF(insideThermometer); } } void setup(){ Serial.begin(115200); sensors_32.getAddress(insideThermometer, 0); sensors_32.setResolution(insideThermometer, 9); } void loop(){ Serial.print("18b20:"); Serial.println(ds18b20_32_getTemp(0)); delay(1000); } |
其中的OneWire是对底层一线制通讯协议的封装。DallasTemperature对象则为DS18B20的功能封装,提供了对DS18B20操作的所有方法。在这里调用了以下几个方法:
getAddress():用来获得DS18B20的地址。也就是64位的唯一标识。
setResolution():用来设置DS18B20的分辨率。
requestTemperatures():通知DS18B20进行温度测量工作,并将结果保存到其内部寄存器中。
getTempC()和getTempF():用来获得摄氏度或者华氏度的测量结果。
好了,DS18B20的基本情况就介绍到这里了,接下来介绍DHT11系列温湿度传感器。