一起玩儿物联网人工智能小车(ESP32)——28. 用DS18B20进行温度测量

摘要:本文介绍如何使用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的第34字节写上下限温度数据命令,紧跟该命令之后,是传送两字节的数据

复制暂存器

48H

将RAM中第3,4字节的内容复制到EEPROM中

重调EEPROM

0B8H

EEPROM中的内容恢复到RAM中的第34字节

读供电方式

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系列温湿度传感器。

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用STM32进行DS18B20温度测量的示例代码: ```c #include "main.h" #include "ds18b20.h" /* 定义DS18B20引脚 */ #define DS18B20_GPIO GPIOA #define DS18B20_PIN GPIO_PIN_0 /* 延时函数 */ void delay_us(uint32_t us) { uint32_t tickstart = HAL_GetTick(); while ((HAL_GetTick() - tickstart) < us) { } } /* DS18B20初始化 */ void DS18B20_Init(void) { /* 配置引脚为输出模式 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = DS18B20_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DS18B20_GPIO, &GPIO_InitStruct); /* 发送复位脉冲 */ HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_SET); delay_us(60); } /* DS18B20读取温度值 */ float DS18B20_ReadTemperature(void) { uint8_t data[9]; uint8_t crc; float temp; /* 发送启动温度转换命令 */ DS18B20_Init(); HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_SET); delay_us(60); HAL_GPIO_ReadPin(DS18B20_GPIO, DS18B20_PIN); delay_us(10); while (HAL_GPIO_ReadPin(DS18B20_GPIO, DS18B20_PIN) == GPIO_PIN_RESET) { } while (HAL_GPIO_ReadPin(DS18B20_GPIO, DS18B20_PIN) == GPIO_PIN_SET) { } delay_us(10); /* 读取温度值 */ for (uint8_t i = 0; i < 8; i++) { HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(DS18B20_GPIO, DS18B20_PIN, GPIO_PIN_SET); delay_us(8); data[i] = HAL_GPIO_ReadPin(DS18B20_GPIO, DS18B20_PIN); delay_us(50); } /* 计算CRC校验和 */ crc = DS18B20_CRC8(data, 8); /* 计算温度值 */ if (crc == data[8]) { if (data[1] & 0x80) { temp = (float)(0xFF - data[1] + 1) * -0.0625f; } else { temp = (float)data[1] * 0.0625f; } } else { temp = -999; } return temp; } /* CRC8校验和计算 */ uint8_t DS18B20_CRC8(uint8_t *data, uint8_t len) { uint8_t crc = 0; for (uint8_t i = 0; i < len; i++) { uint8_t inbyte = data[i]; for (uint8_t j = 0; j < 8; j++) { uint8_t mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) { crc ^= 0x8C; } inbyte >>= 1; } } return crc; } ``` 使用上述代码,可以通过调用DS18B20_ReadTemperature()函数来读取DS18B20温度值。此函数将返回一个浮点数,表示以摄氏度为单位的温度值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起玩儿科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值