- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
SHT3x 系列是 Sensirion 出品的 I2C 数字温湿度传感器(SHT30/SHT31/SHT35),支持最高 1 MHz 的 I2C 通信速率。本文以 RIOT OS 仓库中的手动测试应用 tests/drivers/sht3x/README.md 为骨架,结合 sht3x 驱动源码 与 驱动头文件,完整讲解该传感器在 RIOT OS 中的初始化方式、两种测量模式(单次触发 / 周期测量)、可重复性等级、参数覆盖方法、SAUL 集成,以及如何在真实板卡上编译、烧录并验证输出。读完本文,你将能够独立完成 SHT3x 传感器测试应用的移植、参数定制与结果解析。
一、测试应用概述:验证 SHT3x 驱动的最小完整工程
RIOT OS 将每个外设驱动都配套一个手动测试应用(manual test application),位于tests/drivers/目录下。tests/drivers/sht3x正是 SHT3x 驱动的验证入口,其核心任务是:
- 以固定参数初始化传感器(周期测量,每秒 2 次、高可重复性);
- 初始化成功后,每 1 秒读取一次温度与湿度;
- 将结果以人可读格式打印到 STDOUT。
从 tests/drivers/sht3x/README.md 的 Usage 章节可知,该应用不依赖任何交互命令,上电后即自动开始周期性采样输出,非常适合作为驱动可用性的冒烟测试(smoke test)。
测试工程本身极其精简,仅有三个文件:
| 文件 | 作用 |
|---|---|
| main.c | 应用主逻辑:初始化 + 周期读取打印 |
| Makefile | 构建配置,声明USEMODULE += sht3x |
| Makefile.ci | CI 板卡白名单,标注内存不足的板卡 |
其中 Makefile.ci 明确列出了atmega8(仅 1 KB SRAM 级别的老 AVR 芯片)因内存不足而不参与 CI 构建,这说明驱动 + 测试应用对多数主流板卡的内存开销都在可接受范围内。
二、应用主逻辑逐行拆解
测试应用的完整代码位于 tests/drivers/sht3x/main.c,核心流程如下:
#include "ztimer.h" #include "sht3x.h" #include "sht3x_params.h" int main(void) { sht3x_dev_t dev; int res; puts("SHT3X test application\n"); if ((res = sht3x_init(&dev, &sht3x_params[0])) != SHT3X_OK) { puts("Initialization failed\n"); return 1; } while (1) { int16_t temp; int16_t hum; if ((res = sht3x_read(&dev, &temp, &hum)) == SHT3X_OK) { printf("Temperature [°C]: %d.%d\n" "Relative Humidity [%%]: %d.%d\n" "+-------------------------------------+\n", temp / 100, temp % 100, hum / 100, hum % 100); } else { printf("Could not read data from sensor, error %d\n", res); } ztimer_sleep(ZTIMER_MSEC, 1000); } return 0; }1. 初始化:sht3x_init(&dev, &sht3x_params[0])
sht3x_params[0]是驱动默认参数数组的第一个元素。从 sht3x_params.h 可见,其默认值正是 README 中描述的组合:
#define SHT3X_PARAM_I2C_DEV (I2C_DEV(0)) /* I2C 外设 0 */ #define SHT3X_PARAM_I2C_ADDR (SHT3X_I2C_ADDR_2) /* 地址 0x45(ADDR 引脚接 VDD) */ #define SHT3X_PARAM_MODE (SHT3X_PERIODIC_2_MPS) /* 周期测量,2 次/秒 */ #define SHT3X_PARAM_REPEAT (SHT3X_HIGH) /* 高可重复性 */sht3x_init的实现位于 drivers/sht3x/sht3x.c,它依次完成:填充设备结构体 → 发送 BREAK 命令使传感器进入空闲态 → 软复位(SHT3X_CMD_RESET,复位后状态寄存器应为 0)→ 清状态寄存器 → 校验状态。若配置为周期模式,还会立即发送周期测量启动命令。也就是说,初始化过程本身就是一次完整的传感器可用性检查,任何 I2C 错误、CRC 错误或异常状态都会以负错误码返回。
2. 周期读取:sht3x_read(&dev, &temp, &hum)+ztimer_sleep
主循环每次调用sht3x_read获取最新一组测量值,然后睡眠 1000 ms。注意 README 强调的初始化参数是"每秒 2 次测量",而读取频率是每秒 1 次,这正符合驱动文档的要求——读取频率应低于周期测量频率。在 drivers/sht3x/sht3x.c 的_get_raw_data中可以看到,若读取间隔长于测量周期,驱动会通过ztimer_sleep等待下一个周期数据就绪后再返回,避免数据下溢。
3. 数值输出格式:整数 + 百分位
temp与hum的单位是"百分之一":温度为百分之一摄氏度,湿度为百分之一个百分点。因此打印时用temp / 100取整数部分、temp % 100取小数部分,例如25.31表示 25.31 °C。该换算关系在 drivers/sht3x/sht3x.c 的_compute_values中由原始 16 位 ADC 码经过定点运算得到:
- 温度:
S_T × 17500 >> 16 - 4500,输出为百分之一摄氏度; - 湿度:
S_RH × 10000 >> 16,输出为百分之一个百分点。
4. 构建方式
测试应用的 Makefile 十分简单:
include ../Makefile.drivers_common USEMODULE += sht3x include $(RIOTBASE)/Makefile.includeUSEMODULE += sht3x会同时拉入驱动主体与依赖(I2C 外设、ztimer、CRC 校验模块等)。编译烧录命令与其他 RIOT 测试一致:
# 以 native 或任一支持 I2C 的板卡为例 make -C tests/drivers/sht3x BOARD=native flash term # 或将 BOARD 替换为目标板卡,如 make -C tests/drivers/sht3x BOARD=nucleo-f446re flash termflash负责烧录,term打开串口终端观察每秒打印一次的温湿度数据。若传感器未接线或 I2C 地址不符,终端会打印Initialization failed或Could not read data from sensor, error N。
三、驱动 API 与数据类型:测试应用背后的完整接口
测试应用只用到了sht3x_init、sht3x_read两个函数,但理解 drivers/include/sht3x.h 中的数据类型,才能明白参数覆盖与模式选择的边界。
1. 两种 I2C 地址
#define SHT3X_I2C_ADDR_1 (0x44) /* ADDR 引脚接 GND/VSS */ #define SHT3X_I2C_ADDR_2 (0x45) /* ADDR 引脚接 VDD */同一 I2C 总线上最多可挂两颗 SHT3x,通过 ADDR 引脚电平区分地址。默认配置使用SHT3X_I2C_ADDR_2(0x45),若你的板卡将 ADDR 接地,需要覆盖SHT3X_PARAM_I2C_ADDR为SHT3X_I2C_ADDR_1。
2. 测量模式枚举sht3x_mode_t
typedef enum { SHT3X_SINGLE_SHOT = 0, /* 单次触发测量 */ SHT3X_PERIODIC_0_5_MPS, /* 周期测量 0.5 次/秒 */ SHT3X_PERIODIC_1_MPS, /* 周期测量 1 次/秒 */ SHT3X_PERIODIC_2_MPS, /* 周期测量 2 次/秒(测试应用默认) */ SHT3X_PERIODIC_4_MPS, /* 周期测量 4 次/秒 */ SHT3X_PERIODIC_10_MPS /* 周期测量 10 次/秒 */ } sht3x_mode_t;两种模式的行为差异(详见 驱动文档):
- 单次触发模式(Single Shot):每次调用
sht3x_read才发起一次测量,调用线程最多阻塞约 16 ms(取决于可重复性等级)等待结果。测量完成后传感器自动进入休眠,适合测量频率低于 1 次/秒的低功耗场景。 - 周期模式(Periodic):
sht3x_init时就已下发周期测量命令,传感器自动以固定频率产出数据流,应用只需定期调用sht3x_read取走最新数据。测量命令在初始化时启动,因此调用sht3x_read不会产生额外测量延迟。
3. 可重复性等级sht3x_repeat_t与测量耗时
typedef enum { SHT3X_HIGH = 0, /* 高可重复性 */ SHT3X_MEDIUM, /* 中等 */ SHT3X_LOW /* 低 */ } sht3x_repeat_t;可重复性定义为恒定环境条件下多次连续测量标准差的三倍,本质是传感器输出噪声水平的度量。等级越高噪声越低,但测量耗时与功耗越高:
| 可重复性 | 温度典型精度 | 湿度典型精度 | 最大测量时长 |
|---|---|---|---|
| high | 0.04 | 0.08 | 15.5 ms |
| medium | 0.08 | 0.15 | 6.5 ms |
| low | 0.15 | 0.21 | 4.5 ms |
在 drivers/sht3x/sht3x.c 中,驱动以宏定义形式固化了各等级的等待时间(high=16 ms、medium=7 ms、low=5 ms),并在_get_raw_data中依据meas_duration决定是否阻塞等待测量完成。低可重复性测量时传感器平均电流约 800 μA,待机时仅 0.2 μA——这是选择低可重复性等级换取功耗的主要考量。
4. 错误码枚举sht3x_error_codes
驱动所有函数成功返回SHT3X_OK(0),失败返回负错误码:
typedef enum { SHT3X_OK, /* 无错误 */ SHT3X_ERROR_I2C, /* I2C 通信失败 */ SHT3X_ERROR_CRC, /* CRC 校验失败 */ SHT3X_ERROR_STATUS, /* 传感器状态寄存器异常 */ SHT3X_ERROR_MEASURE_CMD_INV, /* 测量命令未被传感器执行 */ } sht3x_error_codes;测试应用打印的error N即这些枚举值的相反数(如 -1 为 I2C 错误)。CRC 校验使用多项式0x31、初值0xff的 CRC-8 算法(见 sht3x.c),分别校验温度原始数据与湿度原始数据。
四、SAUL 集成:把 SHT3x 接入 RIOT 的统一传感器抽象
除了手动测试应用外,SHT3x 驱动还提供 sht3x_saul.c 作为 SAUL(Sensor Actuator Ubiquitous Layer)适配层。启用sht3x_saul模块后,传感器会自动注册进 SAUL 注册表,可通过统一的saulshell 命令枚举和读取:
> saul 2022-01-01 00:00:00 Reading from sensor sht3x1 Temperature: 25.31 °C Relative Humidity: 45.67 %SAUL 相关的元数据默认名称为"sht3x1"(见 sht3x_params.h 中的SHT3X_SAUL_INFO宏)。这使 SHT3x 能与saul_reg、auto_init等系统组件无缝配合,测试应用则保持最小依赖、直接操作驱动 API。
五、参数覆盖:脱离默认配置的三种方式
驱动文档明确指出,默认配置定义在 sht3x_params.h 中,应用可在包含该头文件之前自行覆盖。
方式一:覆盖单个参数宏
在包含sht3x_params.h前定义对应宏即可:
#define SHT3X_PARAM_MODE (SHT3X_SINGLE_SHOT) #define SHT3X_PARAM_REPEAT (SHT3X_MEDIUM) /* ... */ #include "sht3x.h" #include "sht3x_params.h"方式二:覆盖整个参数数组SHT3X_PARAMS
支持同时配置多颗传感器,例如一颗周期高精度(地址 0x44)+ 一颗单次低功耗(地址 0x45):
/* ... */ #include "sht3x.h" #include "sht3x_params.h" /* ... */ #define SHT3X_PARAMS { .i2c_dev = I2C_DEV(0), \ .i2c_addr = SHT3X_I2C_ADDR_1, \ .mode = SHT3X_PERIODIC_2_MPS, \ .repeat = SHT3X_HIGH \ }, \ { .i2c_dev = I2C_DEV(0), \ .i2c_addr = SHT3X_I2C_ADDR_2, \ .mode = SHT3X_SINGLE_SHOT, \ .repeat = SHT3X_LOW \ }, \ /* ... */ sht3x_dev_t dev1; sht3x_dev_t dev2; if ((res = sht3x_init(&dev1, &sht3x_params[0])) != SHT3X_OK) { /* 错误处理 */ } if ((res = sht3x_init(&dev2, &sht3x_params[1])) != SHT3X_OK) { /* 错误处理 */ }方式三:Kconfig 菜单配置
若板卡/应用启用了 Kconfig 配置系统,各参数宏对应的 Kconfig 符号(SHT3X_PARAM_I2C_DEV、SHT3X_PARAM_I2C_ADDR、SHT3X_PARAM_MODE、SHT3X_PARAM_REPEAT)也可通过menuconfig交互式修改,最终同样落到sht3x_params_t结构体。
六、命令序列与底层实现要点
从 drivers/sht3x/sht3x.c 可以看到驱动内部封装的完整 SHT3x 命令集:
| 命令 | 助记符 | 用途 |
|---|---|---|
| 0x3041 | SHT3X_CMD_CLEAR_STATUS | 清状态寄存器 |
| 0x3066 | SHT3X_CMD_HEATER_OFF | 关闭加热器 |
| 0x3093 | SHT3X_CMD_BREAK | 中断当前命令,回到空闲态 |
| 0x30A2 | SHT3X_CMD_RESET | 软复位 |
| 0xE000 | SHT3X_CMD_FETCH_DATA | 周期模式下取回最新数据 |
| 0xF32D | SHT3X_CMD_STATUS | 读状态寄存器 |
测量命令SHT3X_CMD_MEASURE[6][3]是一个 6×3 的二维表,行对应 6 种模式、列对应 high/medium/low 三种可重复性。例如测试应用默认的"周期 2 mps + 高可重复性"对应命令0x2236。初始化时的复位流程值得注意:驱动先发BREAK等待 1 ms 使传感器退出任何挂起状态,再发RESET等待 2 ms(数据手册标称 0.5 ms),随后清状态并读取状态寄存器,校验其必须为 0x0000,否则返回SHT3X_ERROR_STATUS。
所有 I2C 访问都遵循i2c_acquire/i2c_release的临界区模式,保证与其他 I2C 设备共享总线时的互斥安全。
七、从测试到量产:把测试应用改造成产品代码
将测试应用作为起点改造为产品固件时,通常需要:
- 修改测量周期:将
sht3x_read的调用间隔(当前为 1000 ms)与SHT3X_PARAM_MODE对齐。若只需要 1 次/秒,可将模式改为SHT3X_PERIODIC_1_MPS或直接使用SHT3X_SINGLE_SHOT配合ztimer定时触发,后者在低采样率下更省电。 - 按需只读一个量:
sht3x_read(&dev, &temp, NULL)或sht3x_read(&dev, NULL, &hum)均可,NULL参数会被跳过计算。 - 错误恢复:当前测试应用在读取失败时仅打印错误码后继续循环。生产代码建议在连续 N 次
SHT3X_ERROR_I2C后重新调用sht3x_init尝试复位传感器,利用驱动内建的复位与状态校验逻辑自动恢复。 - 接入 SAUL/网络栈:通过启用
sht3x_saul让数据进入统一的传感器注册表,再配合saul上层接口将温湿度上报给网络协议栈(如 CoAP、MQTT-SN),避免在应用层重复造轮子。
八、小结
tests/drivers/sht3x 是一个"小而全"的 RIOT OS 驱动验证工程:仅 60 行主程序就覆盖了 SHT3x 驱动的初始化、周期测量、数值换算与错误处理全链路,而其背后是 drivers/sht3x 中对 I2C 命令表、CRC-8 校验、测量时序管理的完整封装。无论是想快速验证一块带 SHT30/31/35 的开发板,还是以此为模板编写自己的传感器应用,本文所述的主循环结构、参数覆盖方法与源码定位都可供直接复用。
进一步阅读:
- 驱动完整文档:drivers/sht3x/doc.txt
- 驱动公共 API:drivers/include/sht3x.h
- 驱动实现:drivers/sht3x/sht3x.c
- 默认参数:drivers/sht3x/include/sht3x_params.h
- SAUL 适配:drivers/sht3x/sht3x_saul.c
- 测试应用:tests/drivers/sht3x/main.c
- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
相关推荐
RIOT OS 驱动测试指南:SHTCX 温湿度传感器测试应用(SHTC1/SHTC3)的构建与验证
RIOT OS 驱动测试指南:SHTCX 温湿度传感器测试应用(SHTC1/SHTC3)的构建与验证 本篇文章以 tests/drivers/shtcx/REA
物联网嵌入式操作系统实时系统RIOT OS 手动测试应用解析:Adafruit Seesaw Soil 土壤温湿度传感器驱动验证
RIOT OS 手动测试应用解析:Adafruit Seesaw Soil 土壤温湿度传感器驱动验证 本篇技术指南聚焦 RIOT 开源物联网操作系统(The f
物联网嵌入式操作系统实时系统RIOT OS 中 HDC1000 温湿度传感器驱动测试应用:从编译运行到源码原理全解析
RIOT OS 中 HDC1000 温湿度传感器驱动测试应用:从编译运行到源码原理全解析 本篇文章以 tests/drivers/hdc1000/README.
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考