基于Raspberry Pi Pico C/C++ SDK 的 DS18B20 传感器温度检测项目

项目概述

基于 Raspberry Pi Pico 2 的 DS18B20 温度传感器读取方案,支持多设备 ROM 搜索与地址缓存,温度数据每 2 秒更新一次,同时以摄氏/华氏双单位显示在 LCD1602 屏幕上并通过 USB 串口输出。

硬件连接

所需硬件

树莓派 Pico

LCD 1602 I2C 屏幕

DS18B20 温度传感器

引脚对应

Pico引脚连接设备说明

GPIO 7

DS18B20 DATA (DQ)

-

GPIO 12

LCD1602 SDA

I2C0 数据线

GPIO 13

LCD1602 SCL

I2C0 时钟线
3.3V(OUT)

LCD1602 VCC

屏幕供电

3.3V(OUT)

DS18B20 VDD

传感器供电
GND

DS18B20 GND, LCD1602 GND

共地

软件结构

DS18B20/
├── DS18B20.c              # 主程序
└── lib/
    ├── onewire.h / onewire.c    # 1-Wire 协议驱动
    ├── ds18b20.h / ds18b20.c    # DS18B20 高层 API
    └── lcd1602_i2c.h / lcd1602_i2c.c  # LCD1602 I2C 驱动

库文件功能详解

1. onewire 库 — 1-Wire 底层协议实现

这是整个项目的底层基础,实现了 Maxim 1-Wire 协议的所有时序操作。

核心数据结构:

typedef struct {
    uint pin;                    // GPIO 引脚编号
    uint8_t bitmask;             // 预计算位掩码(快速访问)
    uint8_t ROM_NO[8];           // 当前 ROM 地址
    uint8_t LastDiscrepancy;     // 搜索状态
    uint8_t LastFamilyDiscrepancy;
    uint8_t LastDeviceFlag;
} OneWire;

对外 API:

函数功能
onewire_init(ow, pin)初始化指定 GPIO 引脚上的 1-Wire 总线
onewire_reset(ow)执行总线复位,返回 1 表示检测到设备
onewire_select(ow, rom)通过 8 字节 ROM 地址选中指定设备
onewire_skip(ow)跳过 ROM 选择(广播到所有设备)
onewire_write(ow, v, power)写入一个字节,power=1 时保持总线供电
onewire_write_bytes(ow, buf, count, power)写入多个字节
onewire_read(ow)读取一个字节
onewire_read_bytes(ow, buf, count)读取多个字节
onewire_write_bit(ow, v)写入单个位
onewire_read_bit(ow)读取单个位
onewire_depower(ow)停止强制供电
onewire_reset_search(ow)重置搜索状态

库中通过 ONEWIRE_SEARCH 和 ONEWIRE_CRC 宏控制是否启用 ROM 搜索和 CRC 校验功能,可按需裁剪。

2. ds18b20 库 — 传感器高层 API

基于 OneWire 库构建,封装了 DS18B20、DS18S20 及 DS1822 型号的操作逻辑。

型号与命令定义:

#define DS18S20_MODEL    0x10
#define DS18B20_MODEL    0x28
#define DS1822_MODEL     0x22

#define DS18B20_CMD_CONVERT_TEMP     0x44
#define DS18B20_CMD_READ_SCRATCHPAD  0xBE
#define DS18B20_CMD_WRITE_SCRATCHPAD 0x4E
#define DS18B20_CMD_COPY_SCRATCHPAD  0x48
#define DS18B20_CMD_RECALL_EEPROM    0xB8
#define DS18B20_CMD_READ_POWER_SUPPLY 0xB4
#define DS18B20_CMD_ALARM_SEARCH     0xEC

Scratchpad 寄存器偏移:

#define DS18B20_SP_TEMP_LSB     0
#define DS18B20_SP_TEMP_MSB     1
#define DS18B20_SP_HIGH_ALARM   2
#define DS18B20_SP_LOW_ALARM    3
#define DS18B20_SP_CONFIG       4
#define DS18B20_SP_RESERVED     5
#define DS18B20_SP_COUNT_REMAIN 6
#define DS18B20_SP_COUNT_PER_C  7
#define DS18B20_SP_CRC          8

分辨率配置:

#define DS18B20_RES_9_BIT   0x1F
#define DS18B20_RES_10_BIT  0x3F
#define DS18B20_RES_11_BIT  0x5F
#define DS18B20_RES_12_BIT  0x7F

内部辅助函数(关键逻辑):

  • ds18b20_millis_to_wait_for_conversion(resolution):根据分辨率返回转换等待时间。9 位约 94ms,10 位 188ms,11 位 375ms,12 位 750ms。

  • ds18b20_raw_temperature(sensor, addr, raw):读取 scratchpad 并校验 CRC,成功返回 1。

  • ds18b20_raw_to_celsius(raw):将原始值转换为摄氏度,公式为 raw × 0.0625

对外 API:

函数功能
ds18b20_init(sensor, ow)初始化传感器实例
ds18b20_discover(sensor)搜索总线上的所有DS18B20 设备
ds18b20_get_address(sensor, index)获取第 index 个设备的 ROM 地址
ds18b20_request_temperatures(sensor)向所有设备发出温度转换请求
ds18b20_get_temp_c(sensor, index) 获取指定设备的摄氏温度
ds18b20_get_temp_f(sensor, index) 获取指定设备的华氏温度
ds18b20_read_scratchpad(sensor, addr, sp)读取 scratchpad 数据
ds18b20_write_scratchpad(sensor, addr, th, tl, config)写入 scratchpad
ds18b20_set_resolution(sensor, index, resolution)设置分辨率

主程序流程

DS18B20.c 是程序入口,主要流程如下:

1. 引脚重定义

在包含头文件之前,先覆盖 LCD 的默认引脚配置:

#define LCD1602_SDA_PIN 12
#define LCD1602_SCL_PIN 13
#define LCD1602_I2C_ADDR 0x27
#define LCD1602_I2C_BAUD 100000

2. 初始化

  • 初始化 stdio(USB 串口)

  • 初始化 LCD1602 I2C 屏幕

  • 初始化 OneWire 总线(GPIO 7)

  • 初始化 DS18B20 传感器实例

  • 执行 ds18b20_discover() 搜索总线上的设备

3. 主循环(每 2 秒)

  • 调用 ds18b20_request_temperatures() 发起温度转换

  • 等待转换完成(根据当前分辨率计算等待时间)

  • 调用 ds18b20_get_temp_c() 和 ds18b20_get_temp_f() 读取温度

  • 更新 LCD 显示(第一行显示摄氏温度,第二行显示华氏温度)

  • 通过 printf() 输出到 USB 串口

构建方式

前提条件:

构建步骤:

cd DS18B20
mkdir build && cd build
cmake -G Ninja ..
ninja

最好使用VScode + Raspberry Pi Pico Project 创建、编辑、编译工程,这样非常方便

项目地址

项目地址https://github.com/Jasonobama/pico-ds18b20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值