ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RIOT OS 中 JC42 兼容温度传感器驱动测试:从配置参数到源码级原理

RIOT OS 中 JC42 兼容温度传感器驱动测试:从配置参数到源码级原理 物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载导读本文围绕 RIOT OS 仓库中的 JC42 驱动测试应用 展开讲解如何在 RIOT 上验证 JEDEC JC42.4 标准兼容温度传感器如 mcp9804、MAX6604的工作状态。你将掌握测试应用的三个核心配置参数TEST_I2C、TEST_I2C_ADDR、TEST_I2C_SPEED的含义与覆盖方式、预期输出格式以及驱动底层寄存器读写与温度换算的实现原理并了解该测试在哪些板上无法运行。JC42 测试应用概述RIOT 为每个传感器驱动都配有对应的驱动测试driver test应用tests/drivers/jc42就是专门用于验证 JC42 兼容温度传感器是否正常工作的测试工程。官方 README 对该测试的定位非常明确验证 jc42 兼容温度传感器是否正常工作。从驱动头文件可知jc42 驱动所面向的是与 JEDEC JC42.4 规范兼容的一类温度传感器常见的型号包括 Microchip 的 mcp9804 和 Maxim 的 MAX6604。MCU 与这类传感器之间通过 I2C 接口通信驱动只负责读取温度值虽然传感器本身还支持报警线alarm wire等特性但该驱动并未实现这一点在头文件的描述中也有明确说明。测试应用的文件结构非常精简一共只有四个文件tests/drivers/jc42/main.c测试主程序tests/drivers/jc42/Makefile构建与参数配置入口tests/drivers/jc42/Makefile.ciCI 板卡排除列表tests/drivers/jc42/README.md测试说明文档三个核心配置参数根据 README测试应用需要通过编译宏注入三个参数宏含义说明TEST_I2C使用的 I2C 外设编号指定传感器挂接在哪个 I2C 控制器上TEST_I2C_ADDR传感器 I2C 从机地址通常为0x18TEST_I2C_SPEEDI2C 总线速率通常为I2C_SPEED_NORMAL注意README 原文将TEST_I2C_SPEED的说明误写为 The sensor address实际含义是 I2C 总线速率这一点可从 main.c 的宏检查与 Makefile 的默认值定义得到确认。这三个参数在 main.c 中是以强制要求的形式出现的——如果编译时没有定义任何一个宏编译器会直接报错终止构建#ifndef TEST_I2C #error TEST_I2C not defined #endif #ifndef TEST_I2C_ADDR #error TEST_I2C_ADDR not defined #endif #ifndef TEST_I2C_SPEED #error TEST_I2C_SPEED not defined #endifMakefile 中的默认值与注入机制尽管 main.c 强制要求宏存在tests/drivers/jc42/Makefile 还是通过?提供了安全默认值确保直接编译也能通过USEMODULE jc42 USEMODULE xtimer # set default device parameters in case they are undefined TEST_I2C ? 0 TEST_I2C_ADDR ? 0x18 TEST_I2C_SPEED ? I2C_SPEED_NORMAL # export parameters CFLAGS -DTEST_I2C$(TEST_I2C) CFLAGS -DTEST_I2C_ADDR$(TEST_I2C_ADDR) CFLAGS -DTEST_I2C_SPEED$(TEST_I2C_SPEED)这里的机制值得注意?意味着只有在命令行或环境中未定义对应变量时才采用默认值。如果你在构建时通过make TEST_I2C_ADDR0x1A指定了地址那么TEST_I2C_ADDR就会保持你传入的值随后这三个变量被转换为-D编译选项以宏的形式注入到 main.c 的编译单元中。该 Makefile 同时引用了jc42驱动模块和xtimer模块——前者提供传感器读写能力后者为测试循环的 1 秒定时提供支持。与驱动默认参数的差异值得留意的细节是测试应用的默认速率为I2C_SPEED_NORMAL而驱动自身的默认配置jc42_params.h使用的却是I2C_SPEED_FAST#ifndef JC42_PARAM_I2C_DEV #define JC42_PARAM_I2C_DEV I2C_DEV(0) #endif #ifndef JC42_PARAM_ADDR #define JC42_PARAM_ADDR (0x18) #endif #ifndef JC42_PARAM_SPEED #define JC42_PARAM_SPEED I2C_SPEED_FAST #endif也就是说在普通产品代码中驱动默认以 fast 模式400 kHz 档工作而测试应用为了兼容性考虑默认回退到 normal 模式。JC42.4 规范本身同时支持两种速率因此这两种选择都是合规的。实际接线时请以你手上板子的 I2C 引脚分配和传感器的上拉电阻配置为准来决定采用哪种速率。测试流程初始化、轮询与结果输出main.c 的主函数逻辑非常清晰分为三个阶段1. 构造参数并初始化jc42_t dev; jc42_params_t params { .i2c TEST_I2C, .addr TEST_I2C_ADDR, .speed TEST_I2C_SPEED, }; puts(JC42 temperature sensor test application\n); /* initialize the sensor */ printf(Initializing sensor...); if (jc42_init(dev, params) 0) { puts([OK]); } else { puts([Failed]); return 1; }jc42_params_t结构体由i2cI2C 设备、speed总线速率、addr从机地址三个字段组成定义见 drivers/include/jc42.h。初始化失败时测试程序直接以返回码 1 退出。2. 每秒读取一次温度int16_t temperature; while (1) { printf(Testing sensor communication...); if (jc42_get_temperature(dev, temperature) 0) { puts([OK]); } else { puts([Failed]); return 1; } ... xtimer_msleep(1000); }测试采用无限循环方式每次先打印Testing sensor communication...调用jc42_get_temperature读取一次温度成功后输出[OK]与温度值然后通过xtimer_msleep(1000)休眠 1 秒。3. 以两位小数格式打印温度驱动返回的温度单位是百分之一摄氏度centi-degree即2500表示25.00 °C。main.c 先处理符号再拆分整数部分和小数部分输出bool negative (temperature 0); if (negative) { temperature -temperature; } /* display results */ printf(temperature: %c%d.%02d C\n, (negative) ? - : , temperature / 100, temperature % 100);预期输出README 对预期结果的描述是传感器应持续每 1 秒输出温度精度为两位小数。一次正常运行的串口输出形如JC42 temperature sensor test application Initializing sensor...[OK] Testing sensor communication...[OK] temperature: 25.31 C Testing sensor communication...[OK] temperature: 25.37 C ...驱动源码级原理寄存器与温度换算测试应用只是表面真正支撑它的是 drivers/jc42/jc42.c 这个驱动实现。理解其内部机制有助于排查为什么测试失败之类的问题。寄存器地图JC42 内部头文件定义了 JC42 规范的寄存器地址寄存器地址用途JC42_REG_CAP0x00能力寄存器JC42_REG_CONFIG0x01配置寄存器JC42_REG_TEMP_UPPER0x02上限温度报警阈值JC42_REG_TEMP_LOWER0x03下限温度报警阈值JC42_REG_TEMP_CRITICAL0x04临界温度报警阈值JC42_REG_TEMP0x05温度读数核心数据JC42_REG_MANID0x06厂商 IDJC42_REG_DEVICEID0x07器件 ID其中 0x00 和 0x01 是 JC42.4 规范要求的兼容地址capability 与 config 必须对所有器件可见这也是驱动能够通过读取 config 寄存器来探测设备是否存在的依据。初始化即探测jc42_init并不做复杂的配置写操作而是通过读取配置寄存器来轮询设备是否存在int jc42_init(jc42_t* dev, const jc42_params_t* params) { uint16_t config; dev-i2c params-i2c; dev-addr params-addr; /* Poll the device, fail if unavailable */ if (jc42_get_config(dev, config) ! 0) { return JC42_NODEV; } return JC42_OK; }这意味着只要传感器在线且 I2C 通信正常初始化就会成功如果地址写错、接线断开或 I2C 外设号配错jc42_get_config会返回非零值测试程序便会打印[Failed]并以状态码 1 退出。这与测试中Initializing sensor...环节直接对应。温度换算公式jc42_get_temperature是测试循环每次都要调用的核心函数int jc42_get_temperature(const jc42_t* dev, int16_t* temperature) { struct { signed int x:12;} s; uint16_t tmp; /* Read temperature */ if (jc42_get_register(dev, JC42_REG_TEMP, tmp) ! 0) { return JC42_NODEV; } tmp ntohs(tmp); /* Convert fixed point to uint16_t */ *temperature ((s.x tmp)*100)4; return JC42_OK; }其换算逻辑可以拆解为从 0x05 寄存器读取 16 位原始值用ntohs做字节序转换I2C 上是 big-endian本地可能为 little-endian利用一个 12 位有符号位域把高 12 位解析为带符号定点数符号位 11 位整数/小数LSB 代表 1/16 °C×100 4等价于× (100/16)即把 1/16 °C 的 LSB 换算为百分之一摄氏度。例如原始值0x018812 位定点数 24.5经换算后得到2450即 24.50 °C。负温度如 -10.25 °C由 12 位有符号位域处理为负数再由 main.c 的符号逻辑在打印时恢复-号。这也解释了为什么测试输出能做到稳定的两位小数精度。底层 I2C 访问驱动通过i2c_acquire/i2c_release保护总线访问并调用 RIOT 外设层的i2c_read_regs/i2c_write_regs完成寄存器读写任何一步失败都会返回JC42_NODEV-2。错误码体系定义在 drivers/include/jc42.hJC42_OK 0成功JC42_NOI2C -1I2C 错误JC42_NODEV -2设备不存在或通信失败SAUL 集成不止测试还能接入传感器抽象层该驱动还提供了 SAULSensor Actuator Ubiquitous Layer适配见 jc42_saul.c。它把温度读取包装为SAUL_SENSE_TEMP类型的端点单位UNIT_TEMP_C、scale -2与百分之一摄氏度一一对应通过jc42_temperature_saul_driver导出。这意味着同一颗传感器不仅能跑本文的测试还能通过 SAUL 统一接口被saul_reg、shell 命令乃至上层应用统一读取。构建与运行前置条件测试需要一块支持 I2C 且内存足够的板子。测试的 CI 排除列表 Makefile.ci 明确列出了atmega8因内存不足BOARD_INSUFFICIENT_MEMORY而无法运行此测试——这是该测试对硬件资源的最低要求信号选板时建议参考。编译命令在 RIOT 根目录下直接对测试应用执行标准构建流程# 使用默认参数构建TEST_I2C0, TEST_I2C_ADDR0x18, TEST_I2C_SPEEDI2C_SPEED_NORMAL make -C tests/drivers/jc42 BOARDnucleo-f401re flash term # 覆盖 I2C 设备号与从机地址 make -C tests/drivers/jc42 BOARDnucleo-f401re TEST_I2C1 TEST_I2C_ADDR0x1A flash term命令行传入的变量会优先于 Makefile 中的默认值最终以-D宏的形式进入编译。flash负责烧录term打开串口终端以便观察每秒一次的温度输出。快速验证要点初始化打印[OK]说明传感器在线、地址正确循环中打印[OK]且温度值稳定在物理合理范围内说明读数链路正常若出现[Failed]按JC42_NODEV语义依次检查I2C 外设编号是否与板卡接线一致、从机地址默认 0x18常见型号可通过引脚配置改为 0x19~0x1F是否匹配、I2C 速率是否超出传感器支持范围。小结tests/drivers/jc42虽然只是一个体积小巧的驱动测试应用却完整覆盖了 JC42 传感器验证的全部关键环节通过三个编译宏完成 I2C 设备、地址与速率的灵活配置初始化时以读配置寄存器方式探测设备随后以 1 秒周期读取温度并以两位小数输出。结合 jc42.c 的 12 位有符号定点数换算与 jc42_internal.h 的寄存器地图开发者既能快速验证硬件也能在出现异常时定位到通信层或换算层的问题。对于需要把该传感器接入 SAUL 体系的场景jc42_saul.c 还提供了开箱即用的温度端点实现从裸驱动测试到统一传感层的无缝衔接。赞分享物联网嵌入式操作系统实时系统【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址https://gitcode.com/GitHub_Trending/riot/RIOT点击查看免费下载相关推荐Binci完全指南如何用Docker容器化你的开发工作流告别环境配置烦恼Binci完全指南如何用Docker容器化你的开发工作流告别环境配置烦恼 Binci是一款强大的开发工作流容器化工具它能够帮助开发者将开发环境和任务流程通物联网嵌入式操作系统实时系统RIOT OS 中 HIH6130 温湿度传感器驱动测试从编译参数到数据读取的完整指南RIOT OS 中 HIH6130 温湿度传感器驱动测试从编译参数到数据读取的完整指南 导读 HIH6130 是 Honeywell HumidIcon 系列物联网嵌入式操作系统实时系统RIOT 中 SCD30 CO2/温湿度传感器驱动测试应用深度解析从编译运行到源码原理RIOT 中 SCD30 CO2/温湿度传感器驱动测试应用深度解析从编译运行到源码原理 导读 本文围绕 RIOT 仓库中 tests/drivers/scd3物联网嵌入式操作系统实时系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表