拓冰建站拓冰建站
首页 / 资讯中心 / 正文

RIOT 中 LIS3DH 加速度计驱动的手动测试应用:参数初始化、FIFO 读取与中断回调全解析

物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载本指南围绕 RIOT 仓库中的 LIS3DH 加速度计驱动手动测试应用展开该应用位于 tests/drivers/lis3dh用于验证 LIS3DH 传感器在 SPI 总线上的初始化、三轴加速度读取、辅助 ADC含温度传感器、FIFO 流模式以及 INT1 中断回调等核心功能。读完本文你将掌握该测试应用的工作原理、驱动 API 的调用顺序与参数语义以及如何在自己的 RIOT 工程中复用它验证传感器硬件。测试应用概览它是做什么的tests/drivers/lis3dh/README.md明确指出这是一个manual test application手动测试应用也就是说它不依赖自动化断言框架而是将传感器数据持续打印到标准输出由开发者在真机上观察结果是否符合预期。测试应用在初始化阶段将传感器配置为采样率Sampling Rate100Hz量程Scale4G温度传感器Temperature sensor启用初始化完成后应用每 100ms 读取一次加速度值并打印到 STDOUT。不过从实际源码看它的行为比 README 描述得更丰富除了定时打印还驱动了 FIFO 流模式、FIFO 水位watermark中断以及 INT1 引脚的中断计数与电平读取用于验证中断链路是否打通。测试应用的整体流程分为两段初始化阶段依次调用驱动的各个配置 API每步都在 STDOUT 打印[OK]或[Failed]任何一步失败立即return 1退出主循环阶段读取 FIFO 当前积压的采样数逐条读出三轴数据与温度同时打印 INT1 中断累计次数与当前引脚电平。构建与运行前提测试应用的构建配置在 tests/drivers/lis3dh/Makefile 中include ../Makefile.drivers_common FEATURES_REQUIRED periph_gpio_irq USEMODULE lis3dh USEMODULE xtimer include $(RIOTBASE)/Makefile.include几点值得注意FEATURES_REQUIRED periph_gpio_irq声明该测试必须运行在支持 GPIO 中断的平台上因为测试代码里使用了gpio_init_int()注册 INT1 上升沿中断回调USEMODULE lis3dh引入 LIS3DH 驱动模块USEMODULE xtimer提供xtimer_usleep()定时能力测试的 CI 门禁在 tests/drivers/lis3dh/Makefile.ci 中其中atmega8因内存过小被列为BOARD_INSUFFICIENT_MEMORY即该板卡不参与本测试的自动构建。编译与烧录方式与其他 RIOT 测试应用一致在测试目录内执行# 编译以 native 或具体板卡为例 make BOARDnative # 或烧录到目标板 make BOARDyour-board flash # 观察串口输出 make BOARDyour-board term传感器参数默认值来自哪里测试代码通过lis3dh_params[0]拿到设备配置该数组定义在驱动自带的默认参数文件 drivers/lis3dh/include/lis3dh_params.h 中。它采用 RIOT 驱动的经典模式——所有参数均可由板级board.h或应用通过CFLAGS覆盖参数宏默认值说明LIS3DH_PARAM_SPISPI_DEV(0)传感器挂接的 SPI 外设LIS3DH_PARAM_CSGPIO_PIN(0, 0)片选引脚LIS3DH_PARAM_CLKSPI_CLK_5MHZSPI 时钟速率LIS3DH_PARAM_INT1GPIO_PIN(0, 1)INT1 中断引脚LIS3DH_PARAM_INT2GPIO_PIN(0, 2)INT2DRDY引脚LIS3DH_PARAM_SCALE4默认量程单位 G可取 2/4/8/16LIS3DH_PARAM_ODRLIS3DH_ODR_100Hz默认输出数据率这些默认值恰好与 README 中声明的“100Hz、4G”一致说明测试应用直接复用了驱动的默认参数。真实板卡通常会覆盖这些宏例如 Mulle 板在 boards/mulle/include/board.h 中把 INT1/INT2 接到 PORT_C 的具体引脚、片选改为硬件 CSSPI_HWCS(0)并保持SPI_CLK_5MHZ。如果你的板卡手册给出了不同的接线只需在板级或应用层重定义对应的LIS3DH_PARAM_*宏即可无需修改驱动源码。lis3dh_params_t与lis3dh_t的结构定义在 drivers/include/lis3dh.hlis3dh_params_t描述硬件连接与默认行为spi、clk、cs、int1、int2、scale、odrlis3dh_t在参数之外额外保存scale内部量程用于把原始 ADC 值换算成 milli-G。初始化调用链逐行解析测试的main()位于 tests/drivers/lis3dh/main.c初始化阶段严格遵循驱动的使用顺序1. 设备初始化lis3dh_init()lis3dh_t dev; lis3dh_data_t acc_data; puts(Initializing LIS3DH sensor... ); if (lis3dh_init(dev, lis3dh_params[0]) 0) { puts([OK]); }从 drivers/lis3dh/lis3dh.c 的实现看lis3dh_init()完成以下工作保存参数副本到设备描述符用spi_init_cs()初始化片选线读取WHO_AM_I寄存器地址0x0F并与LIS3DH_WHO_AM_I_RESPONSE0x33比对验证芯片是否真实存在且接线正确不匹配即返回 -1复位各控制寄存器CTRL_REG1 只使能 XYZ 轴、CTRL_REG2 关闭高通滤波、CTRL_REG3 清空 INT1 中断源、CTRL_REG4 设置 BDU块数据更新 小端 高分辨率模式、CTRL_REG5/CTRL_REG6 复位 FIFO 与 INT2最后调用lis3dh_set_scale()应用默认量程。lis3dh_init()内部使用SPI Mode 3SPI_MODE_3这是 LIS3DH 数据手册要求的 SPI 工作模式。值得留意的是初始化阶段只配置了量程并没有设置 ODR 和轴使能之外的采样行为因此测试紧接着显式调用lis3dh_set_odr()。2. 输出数据率lis3dh_set_odr()puts(Set ODR... ); if (lis3dh_set_odr(dev, lis3dh_params[0].odr) 0) { puts([OK]); }lis3dh_params[0].odr即LIS3DH_ODR_100Hz。驱动头文件中定义了完整的 ODR 档位宏drivers/include/lis3dh.h宏数值说明LIS3DH_ODR_POWERDOWN0x00掉电模式LIS3DH_ODR_1Hz0x011 HzLIS3DH_ODR_10Hz0x0210 HzLIS3DH_ODR_25Hz0x0325 HzLIS3DH_ODR_50Hz0x0450 HzLIS3DH_ODR_100Hz0x05100 Hz测试默认LIS3DH_ODR_200Hz0x06200 HzLIS3DH_ODR_400Hz0x07400 HzLIS3DH_ODR_LP1600Hz0x08低功耗 1600 HzLIS3DH_ODR_NP1250Hz/LIS3DH_ODR_LP5000HZ0x09普通模式 1250 Hz 与低功耗 5000 Hz 共用同一寄存器值ODR 的比特位写进CTRL_REG1的高 4 位LIS3DH_CTRL_REG1_ODR_SHIFT为 4同时写 ODR 的过程会顺带打开加速计主 ADC——头文件注释明确指出“accelerometer ADC is turned on by lis3dh_set_odr()”。3. 量程lis3dh_set_scale()puts(Set scale... ); if (lis3dh_set_scale(dev, lis3dh_params[0].scale) 0) { puts([OK]); }合法量程为2、4、8、16单位 G对应CTRL_REG4的 FS 位组合宏量程LIS3DH_CTRL_REG4_SCALE_2G±2GLIS3DH_CTRL_REG4_SCALE_4G±4G测试默认LIS3DH_CTRL_REG4_SCALE_8G±8GLIS3DH_CTRL_REG4_SCALE_16G±16G量程还参与数据换算lis3dh_read_xyz()在读出 6 字节原始数据后把每个 16 位原始值乘以内部dev-scale再除以 32768输出单位为 milli-G见 drivers/lis3dh/lis3dh.c。这也是lis3dh_data_t中acc_x/acc_y/acc_z字段被注释为 “milli-G” 的原因。4. 轴使能lis3dh_set_axes()puts(Set axes XYZ... ); if (lis3dh_set_axes(dev, LIS3DH_AXES_XYZ) 0) { puts([OK]); }LIS3DH_AXES_XYZ是同时使能 X、Y、Z 三个轴的快捷宏等价于LIS3DH_AXES_X | LIS3DH_AXES_Y | LIS3DH_AXES_Z对应CTRL_REG1的低三位。也可按需只使能部分轴以降低功耗或减少总线流量。5. FIFO 流模式与水位lis3dh_set_fifo()#define WATERMARK_LEVEL 16 puts(Enable streaming FIFO mode... ); if (lis3dh_set_fifo(dev, LIS3DH_FIFO_MODE_STREAM, WATERMARK_LEVEL) 0) { puts([OK]); }测试把 FIFO 配置为Stream 模式并把watermark水位设为 16。驱动头文件定义了四种 FIFO 模式drivers/include/lis3dh.h宏含义LIS3DH_FIFO_MODE_BYPASS旁路模式FIFO 不启用LIS3DH_FIFO_MODE_FIFOFIFO 模式攒满即停LIS3DH_FIFO_MODE_STREAM流模式持续采样满则覆盖最旧数据LIS3DH_FIFO_MODE_STREAM_TO_FIFO先流式、触发后转 FIFO在 Stream 模式下传感器以 ODR 持续填充 32 级深度的 FIFO当 FIFO 内采样数达到 watermark16时硬件会在 INT1 引脚上产生一次中断配合后续的LIS3DH_CTRL_REG3_I1_WTM_MASK使能。这样应用无需以 ODR 频率逐次轮询而是攒够一批数据再批量读取降低 CPU 与 SPI 总线开销——这正是测试主循环“一次读出 N 条采样”的数据来源。6. 温度传感器与辅助 ADClis3dh_set_aux_adc()puts(Enable temperature reading... ); if (lis3dh_set_aux_adc(dev, 1, 1) 0) { puts([OK]); }lis3dh_set_aux_adc(dev, enable, temperature)两个参数分别为辅助 ADC 的电源开关与温度通道选择。测试传入(1, 1)即打开辅助 ADC 电源TEMP_CFG_REG的ADC_PD位设置 ADC 多路开关使内部温度传感器输出接到OUT_3_L/OUT_3_HTEMP_EN位。随后调用lis3dh_read_aux_adc3()即可读到温度原始值——驱动头文件明确注明当TEMP_EN置位时内部温度传感器连接到辅助 ADC 的第三通道drivers/include/lis3dh.h。辅助 ADC 的 1/2 通道则留给外部 ADC 引脚使用。7. INT1 中断源与回调注册puts(Set INT1 watermark function... ); if (lis3dh_set_int1(dev, LIS3DH_CTRL_REG3_I1_WTM_MASK) 0) { puts([OK]); } puts(Set INT1 callback); if (gpio_init_int(lis3dh_params[0].int1, GPIO_IN, GPIO_RISING, test_int1, (void*)int1_count) 0) { puts([OK]); }这两步协同完成中断链路lis3dh_set_int1()写入CTRL_REG3把FIFO 水位WTM中断源路由到 INT1 引脚LIS3DH_CTRL_REG3_I1_WTM_MASK。CTRL_REG3中还定义了 CLICK、AOI1/AOI2、DRDY1/DRDY2、OVERRUN 等其他可路由到 INT1 的中断源位gpio_init_int()是 RIOT 的 GPIO 中断 API把 INT1 引脚配置为输入、上升沿触发中断服务里执行test_int1回调对int1_count累加计数。测试因此能同时从两个维度验证中断int1_count反映中断触发次数主循环里gpio_read()则读取中断引脚当前电平。主循环FIFO 批量读取与打印初始化完成后进入无限循环tests/drivers/lis3dh/main.cwhile (1) { int fifo_level; fifo_level lis3dh_get_fifo_level(dev); printf(int1_count %d\n, int1_count); printf(Reading %d measurements\n, fifo_level); while (fifo_level 0) { int16_t temperature; int int1; if (lis3dh_read_xyz(dev, acc_data) ! 0) { puts(Reading acceleration data... ); puts([Failed]\n); } if (lis3dh_read_aux_adc3(dev, temperature) ! 0) { puts(Reading temperature data... ); puts([Failed]\n); return 1; } int1 gpio_read(lis3dh_params[0].int1); printf(X: %6d Y: %6d Z: %6d Temp: %6d, INT1: %08x\n, acc_data.acc_x, acc_data.acc_y, acc_data.acc_z, temperature, int1); --fifo_level; } xtimer_usleep(SLEEP_USEC); }关键行为解读lis3dh_get_fifo_level()读取FIFO_SRC_REG中的 FSS 位段5 位031返回当前 FIFO 内积压的采样条数循环按 FIFO 积压数逐条读取每条先lis3dh_read_xyz()读出三轴lis3dh_read_xyz通过一次多字节 SPI 事务从OUT_X_L起连续读 6 字节再lis3dh_read_aux_adc3()读出温度原始值打印格式X: %6d Y: %6d Z: %6d Temp: %6d, INT1: %08x中X/Y/Z 为 milli-G 单位Temp 为 ADC 原始码值INT1 打印的是引脚电平低位为当前电平便于观察中断引脚状态外层xtimer_usleep(100 * 1000U)即SLEEP_USEC 100ms与 README 中“每 100ms 读取一次”的表述对应同时也给 FIFO 在 100Hz ODR 下积累约 10 条新数据的时间静态变量int1_count由中断回调在中断上下文自增主循环读取——这是嵌入式场景中“中断里只做计数、主循环做耗时处理”的典型写法。需要注意每次主循环读取fifo_level后循环体内按该数量读取而 FIFO 在 Stream 模式下仍在持续填充因此打印的条数与实际 FIFO 深度可能存在时序差异这是该测试刻意展示的“按当前水位批量消费”语义。从源码确认的关键实现细节SPI 总线访问是线程安全的lis3dh_read_xyz()在事务前后调用spi_acquire()/spi_release()保证与其他 SPI 设备共享总线时不互相干扰drivers/lis3dh/lis3dh.c多字节读必须置 MULTI 位读地址由LIS3DH_REG_OUT_X_L | LIS3DH_SPI_READ_MASK | LIS3DH_SPI_MULTI_MASK构成驱动头文件中对LIS3DH_SPI_READ_MASK读标志与LIS3DH_SPI_MULTI_MASK多字节标志有明确说明BDU 与高分辨率默认开启lis3dh_init()在CTRL_REG4中写入 BDU 使能防止读高低字节时数据被更新导致错位、小端序和高分辨率模式SAUL 集成该驱动同时属于drivers_saul组drivers/lis3dh/lis3dh_saul.c 提供了 SAUL 注册实现lis3dh_params.h中也预留了LIS3DH_SAUL_INFO元信息。不过本测试应用走的是直接 API 调用路径未使用 SAUL 层适合验证驱动底层行为。总结tests/drivers/lis3dh是一个麻雀虽小五脏俱全的手动测试应用它把 LIS3DH 驱动的全部核心 API——初始化、ODR、量程、轴使能、FIFO 流模式与水位、温度通道、INT1 中断路由与 GPIO 回调、FIFO 水位查询、批量读取——按真实使用顺序串联起来并以“每步打印[OK]/[Failed] 主循环持续打印数据”的方式给出直观的硬件验证反馈。对开发者而言这份测试既是验证 LIS3DH 硬件接线的快速手段也是学习如何在 RIOT 中正确组织传感器驱动调用链的参考模板先lis3dh_init验证 WHO_AM_I 并复位寄存器再按需配置 ODR/scale/axes/FIFO/中断最后在循环中批量消费 FIFO 数据并利用中断计数确认事件链路通畅。若需在自己的工程中集成 LIS3DH可直接参考本测试的 main.c 调用顺序配合 lis3dh_params.h 覆盖默认参数即可快速落地。赞分享物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载相关推荐Union Voyager Gno State Module在 Gno.land 上查询 ibc-union IBC 状态的实现解析Union Voyager Gno State Module在 Gno.land 上查询 ibc union IBC 状态的实现解析 Union Voyage物联网嵌入式操作系统实时系统爱心对话框LovelyDialog 使用指南爱心对话框LovelyDialog 使用指南 1. 目录结构及介绍 plaintext LovelyDialog │ ├── app/ │ └── ... 应物联网嵌入式操作系统实时系统RIOT OS 中 HIH6130 温湿度传感器驱动测试从编译参数到数据读取的完整指南RIOT OS 中 HIH6130 温湿度传感器驱动测试从编译参数到数据读取的完整指南 导读 HIH6130 是 Honeywell HumidIcon 系列物联网嵌入式操作系统实时系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门