- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
导读
本文围绕 RIOT(The friendly OS for IoT)中 LPSXXX 系列气压传感器驱动的官方手动测试应用展开,完整讲解其构建方式、运行行为,并结合仓库源码深入剖析驱动的初始化、采样率配置、温度与气压读取、SAUL 接口适配及寄存器级实现细节。读完本文,你将掌握如何在不同板卡上以不同驱动型号编译该测试应用,理解 7Hz/25Hz 采样率的来源与背后的 ODR 枚举映射,并能读懂驱动底层 I2C 寄存器操作流程。
测试应用概览
该测试应用位于 tests/drivers/lpsxxx 目录,是一个手动测试应用,用于验证 LPSXXX 系列压力传感器驱动。驱动支持以下型号:LPS331AP、LPS22CH、LPS25HB、LPS22HB 和 LPS22HH。
测试应用的核心行为(见 README.md):
- 以默认采样率初始化压力传感器:LPS331AP 与 LPS25HB 默认7Hz,LPS22HB 与 LPS22HH 默认25Hz;
- 初始化完成后,每250ms读取一次气压与温度值;
- 将读取结果打印到标准输出(STDOUT)。
构建与运行
默认构建(LPS331AP)
测试应用的默认驱动为lps331ap,直接构建即可:
make BOARD=<你的板卡>切换驱动型号
要使用 LPS25HB 驱动,构建时通过DRIVER变量指定:
DRIVER=lps25hb make BOARD=<你的板卡>该机制在 Makefile 中实现:
DRIVER ?= lps331ap USEMODULE += $(DRIVER) USEMODULE += xtimerDRIVER变量直接决定编译进固件的驱动模块(lps331ap、lps25hb、lps22hb、lps22hh、lps22ch均有效),该模块通过条件编译宏(如MODULE_LPS25HB)控制驱动的寄存器定义与采样率枚举。此外测试应用还依赖xtimer模块实现 1 秒延时。
硬件依赖与内存限制
驱动在 Makefile.dep 中声明了硬件特性依赖:
FEATURES_REQUIRED += periph_i2c即使用该驱动必须保证目标板卡提供 I2C 外设。同时在 Makefile.ci 中,atmega8因内存不足(BOARD_INSUFFICIENT_MEMORY)被排除在 CI 测试之外。
预期输出
在 main.c 中,应用启动后先打印传感器名称并调用lpsxxx_init()初始化;初始化失败(返回非LPSXXX_OK)则打印Initialization failed并以退出码 1 终止。成功后进入循环,每轮依次执行lpsxxx_enable()→xtimer_sleep(1)(等待测量完成)→ 读取温度与气压 →lpsxxx_disable(),最后输出:
Pressure value: 1013hPa - Temperature: 25.00°C其中温度值来自驱动返回的厘摄氏度(c°C),main 中将其拆分换算为整数部分与小数部分显示。
驱动的默认参数与采样率解析
默认 I2C 地址
在 lpsxxx.h 中定义默认 I2C 地址:
#ifndef CONFIG_LPSXXX_DEFAULT_ADDRESS #define CONFIG_LPSXXX_DEFAULT_ADDRESS (0x5d) #endif该地址对应SDO/SA0 引脚接 VDD(高电平)时的默认地址;若 SDO/SA0 接地,地址会不同,具体需查阅数据手册的 I2C 操作章节。
输出数据率(ODR)枚举
不同型号的采样率枚举在lpsxxx_rate_t中按编译模块区分:
- LPS331AP:1Hz、7Hz(默认)、12.5Hz、25Hz;
- LPS25HB:7Hz(默认)、12.5Hz、25Hz;
- LPS22HB:10Hz、25Hz(默认)、50Hz、75Hz;
- LPS22HH / LPS22CH:10Hz、25Hz(默认)、50Hz、75Hz、100Hz、200Hz。
默认速率由宏统一指定:
#if MODULE_LPS331AP || MODULE_LPS25HB #define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_7HZ) #else #define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_25HZ) #endif这正是测试应用 README 中"7Hz(LPS22HB/LPS22HH 为 25Hz)"的源码出处。
参数结构体与默认配置
设备参数结构体lpsxxx_params_t包含三项:I2C 总线号(i2c)、总线地址(addr)和采样率(rate)。默认值在 lpsxxx_params.h 中提供:
#define LPSXXX_PARAM_I2C I2C_DEV(0) /* 使用 I2C 设备 0 */ #define LPSXXX_PARAM_ADDR (CONFIG_LPSXXX_DEFAULT_ADDRESS) #define LPSXXX_PARAM_RATE (LPSXXX_DEFAULT_RATE)默认配置数组lpsxxx_params[]与 SAUL 元信息数组lpsxxx_saul_info[]均在该文件中定义,供lpsxxx_init()和 SAUL 注册使用。注意:这些默认值均可用LPSXXX_PARAM_*宏在板级配置中覆盖(例如将传感器接到 I2C 设备 1 时,可重新定义LPSXXX_PARAM_I2C)。
驱动实现深度解析
初始化流程(lpsxxx_init)
初始化逻辑位于 lpsxxx.c,核心步骤如下:
- 保存用户传入的参数到设备描述符
dev->params; i2c_acquire()获取总线独占访问权;- 读取
WHO_AM_I寄存器(0x0F),校验设备身份:- LPS331AP 期望值
0xbb、LPS25HB 为0xbd、LPS22HB 为0xb1、LPS22HH/LPS22CH 为0xb3; - 校验失败返回
-LPSXXX_ERR_NODEV,I2C 读取失败返回-LPSXXX_ERR_I2C;
- LPS331AP 期望值
- 对 LPS22HB 额外操作
CTRL_REG2,清除自动地址递增位(ID_ADD_INC),以符合数据手册 9.6 节建议; - 配置
CTRL_REG1:LPS331AP 设置DBDU | PD | (rate << ODR_POS);LPS25HB 使用BDU;LPS22HB/LPS22HH/LPS22CH 额外启用低通滤波(EN_LPFP,配置为 ODR/9); - 释放总线,返回
LPSXXX_OK。
温度读取(lpsxxx_read_temp)
- 依次读取
TEMP_OUT_L(0x2B)与TEMP_OUT_H(0x2C),拼接为 16 位有符号原始值; - 按型号归一化:LPS331AP/LPS25HB 使用
TEMP_BASE = 4250(即 42.5°C 参考基准)与TEMP_DIVIDER = 480计算;LPS22HB 系列使用TEMP_BASE = 0、TEMP_DIVIDER = 100; - 最终温度以厘摄氏度(c°C)返回,即
TEMP_BASE + round(raw * 100 / TEMP_DIVIDER)。
气压读取(lpsxxx_read_pres)
- 依次读取
PRESS_OUT_XL(0x28)、PRESS_OUT_L(0x29)、PRESS_OUT_H(0x2A)三个寄存器,拼成 24 位原始值; - 最高位为符号位,若为负则做符号扩展;
- 通过
PRES_DIVIDER = 12(即右移 12 位)归一化,得到以hPa为单位的气压值。这正是测试应用打印Pressure value: ...hPa的依据。
使能与禁用
lpsxxx_enable():读回CTRL_REG1,对 LPS331AP/LPS25HB 置位电源使能位PD;对 LPS22HB 系列重新写入低通滤波、BDU与 ODR 位;lpsxxx_disable():对 LPS331AP/LPS25HB 清除PD位进入掉电模式;对 LPS22HB 系列清除 ODR 位段。
返回值约定
lpsxxx.h定义了三个返回码:LPSXXX_OK(成功)、LPSXXX_ERR_NODEV(未找到有效设备)、LPSXXX_ERR_I2C(I2C 总线错误)。驱动内对错误统一返回其负值(如-LPSXXX_ERR_I2C),测试应用仅将 0(LPSXXX_OK)视为成功。
SAUL 接口适配
驱动通过 lpsxxx_saul.c 接入 RIOT 的 SAUL(Sensor Actuator Uber Layer)统一传感器抽象层,注册了两个只读驱动:
- 气压驱动
lpsxxx_saul_pres_driver:类型SAUL_SENSE_PRESS,读取成功后unit = UNIT_PA、scale = 2(即 10² Pa = hPa 量级); - 温度驱动
lpsxxx_saul_temp_driver:类型SAUL_SENSE_TEMP,unit = UNIT_TEMP_C、scale = -2(即厘摄氏度)。
SAUL 注册名由 lpsxxx_params.h 中的LPSXXX_SAUL_NAME按编译模块给出(如"lps331ap"、"lps25hb"),该名称也会被测试应用打印在启动信息中。
硬件寄存器速查
各型号寄存器地址与位域定义集中在 lpsxxx_internal.h,下表为常用寄存器速查:
| 寄存器 | 地址 | 说明 |
|---|---|---|
WHO_AM_I | 0x0F | 设备 ID(各型号期望值见上文) |
CTRL_REG1 | 0x20(LPS331AP/LPS25HB)/ 0x10(LPS22HB 系列) | 电源、ODR、低通滤波等主控制寄存器 |
PRESS_OUT_XL/L/H | 0x28–0x2A | 24 位气压原始数据 |
TEMP_OUT_L/H | 0x2B–0x2C | 16 位温度原始数据 |
CTRL_REG2 | 0x21(LPS331AP/LPS25HB)/ 0x11(LPS22HB 系列) | 含自动地址递增控制位 |
ODR 位段统一位于CTRL_REG1的 bit4–bit6(ODR_POS = 4),不同型号枚举值不同,切换驱动时需注意这一点。
在真实板卡上的实践步骤
- 确认板卡具备 I2C 外设(
FEATURES_REQUIRED += periph_i2c),并按lpsxxx_params.h的默认参数或板级覆盖配置接线; - 进入 tests/drivers/lpsxxx 目录,选择目标驱动编译并烧录,例如使用
native之外的 I2C 板卡:
DRIVER=lps22hh make BOARD=your-board flash- 连接串口查看输出,应每秒(每 250ms 一次采样、经 1 秒延时)打印一条气压与温度数据;
- 若初始化失败,优先检查
WHO_AM_I校验(地址是否匹配 SDO/SA0 接法)、I2C 总线号与接线。
总结
LPSXXX 测试应用虽小,却完整展示了 RIOT 驱动开发的典型范式:Makefile中通过DRIVER变量与USEMODULE选择具体芯片、lpsxxx_params.h提供可覆盖的默认参数、lpsxxx.c基于 I2C 寄存器实现轮询式读写、lpsxxx_saul.c无缝接入 SAUL 抽象层。理解这份测试应用与驱动源码,不仅可以直接上手验证任意 LPSXXX 系列传感器,也为在 RIOT 中集成其他 I2C 传感器驱动提供了清晰的参考模板。
- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
相关推荐
ESP-Drone 传感器驱动全解析:MPU6050 / VL53LXX / PMW3901 从寄存器配置到飞控应用
ESP Drone 传感器驱动全解析:MPU6050 / VL53LXX / PMW3901 从寄存器配置到飞控应用 本指南基于 ESP Drone(ESP32
智能硬件嵌入式物联网Tasmota 中的 SPL06-007 气压传感器库:寄存器配置、数据读取与驱动集成实战
Tasmota 中的 SPL06 007 气压传感器库:寄存器配置、数据读取与驱动集成实战 本篇文章以仓库内 SPL06 007 库 README https:
嵌入式物联网固件智能家居RIOT 中 AMS CCS811 空气质量传感器轮询模式测试应用详解
RIOT 中 AMS CCS811 空气质量传感器轮询模式测试应用详解 导读 本文围绕 RIOT 仓库中的 tests/drivers/ccs811/READM
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考