1. ESP32与DS18B20温度传感器的技术背景
在物联网和嵌入式系统开发中,温度监测是最基础也最常用的功能之一。ESP32作为一款高性价比的Wi-Fi/蓝牙双模芯片,配合DS18B20这款单总线数字温度传感器,可以构建出稳定可靠的温度监测系统。这套组合特别适合需要无线传输温度数据的场景,比如智能农业大棚、冷链物流监控或是家庭环境监测。
DS18B20的最大特点是采用单总线(1-Wire)协议进行通信,这意味着只需要一根数据线就能完成供电和数据传输(当然在实际应用中,为了稳定性我们通常会使用外部供电模式)。它的测温范围是-55°C到+125°C,精度可达±0.5°C(在-10°C到+85°C范围内),分辨率为9到12位可调。每个DS18B20都有全球唯一的64位序列号,这使得多个传感器可以挂载在同一条总线上。
ESP-IDF是乐鑫官方为ESP32提供的开发框架,相比Arduino环境,它提供了更底层的硬件控制能力和更丰富的功能模块。使用ESP-IDF驱动DS18B20,我们可以获得更精确的时序控制和更高的系统稳定性,这对于需要长时间运行的监测系统尤为重要。
提示:虽然DS18B20支持寄生供电模式(仅用两根线),但在实际项目中建议使用外部供电(三线制),这样可以避免因总线负载过大导致的通信失败问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境搭建与硬件连接
2.1 ESP-IDF开发环境配置
要使用ESP-IDF开发ESP32应用,首先需要搭建开发环境。目前推荐使用VSCode+ESP-IDF插件的方式,这比纯命令行方式更友好:
- 安装VSCode后,在扩展商店搜索并安装"Espressif IDF"插件
- 打开命令面板(Ctrl+Shift+P),运行"ESP-IDF: Configure ESP-IDF extension"命令
- 选择"Express"安装方式,按照向导完成工具链的下载和配置
- 安装完成后,可以通过"ESP-IDF: New Project"命令创建新项目
验证安装是否成功:
bash复制get-idf
idf.py --version
如果能看到版本信息,说明环境配置正确。
2.2 硬件连接方案
ESP32与DS18B20的标准连接方式如下(使用外部供电模式):
| ESP32引脚 | DS18B20引脚 | 连接说明 |
|---|---|---|
| 3.3V | VDD | 电源正极 |
| GND | GND | 电源地 |
| GPIO4 | DQ | 数据线(需接4.7K上拉电阻) |
注意:虽然理论上任何GPIO都可以用作1-Wire总线,但建议选择不常用的GPIO4或GPIO5,避免与SPI、I2C等常用外设冲突。上拉电阻对通信稳定性至关重要,不可省略。
实物连接示意图:
code复制ESP32 DevKitC
┌──────────────┐
│ │ 4.7KΩ
│ 3V3 ├──────┐
│ │ │
│ GND ├──────┤
│ │ │
│ GPIO4├──────┴─────DQ
└──────────────┘ │
DS18B20
│
GND
3. DS18B20驱动实现详解
3.1 1-Wire协议底层驱动
在ESP-IDF中,我们可以使用内置的"ds18b20"组件,也可以自己实现1-Wire协议。这里我们选择更灵活的自实现方式,首先创建ds18b20.h头文件:
c复制#ifndef __DS18B20_H__
#define __DS18B20_H__
#include "driver/gpio.h"
#define DS18B20_CMD_CONVERTTEMP 0x44
#define DS18B20_CMD_RSCRATCHPAD 0xBE
#define DS18B20_CMD_WSCRATCHPAD 0x4E
#define DS18B20_CMD_CPYSCRATCHPAD 0x48
#define DS18B20_CMD_RECEEPROM 0xB8
#define DS18B20_CMD_RPWRSUPPLY 0xB4
#define DS18B20_CMD_SEARCHROM 0xF0
#define DS18B20_CMD_READROM 0x33
#define DS18B20_CMD_MATCHROM 0x55
#define DS18B20_CMD_SKIPROM 0xCC
typedef struct {
gpio_num_t gpio_num;
uint8_t resolution;
} ds18b20_dev_t;
void ds18b20_init(ds18b20_dev_t *dev, gpio_num_t gpio_num, uint8_t resolution);
float ds18b20_get_temp(ds18b20_dev_t *dev);
#endif
对应的ds18b20.c实现文件包含以下关键函数:
c复制#include "ds18b20.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
static const char *TAG = "DS18B20";
// 微秒级延时函数
static void ds_delay_us(uint32_t us) {
uint32_t start = esp_timer_get_time();
while (esp_timer_get_time() - start < us);
}
// 1-Wire复位脉冲
static bool ds_reset(ds18b20_dev_t *dev) {
gpio_set_direction(dev->gpio_num, GPIO_MODE_OUTPUT);
gpio_set_level(dev->gpio_num, 0);
d
