ARTICLE DETAIL

资讯详情

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

RIOT 平台 SRF08 超声波测距传感器驱动手动测试应用全解析

RIOT 平台 SRF08 超声波测距传感器驱动手动测试应用全解析 RIOT 平台 SRF08 超声波测距传感器驱动手动测试应用全解析【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT导读本文围绕 RIOT 操作系统中 SRF08 超声波测距传感器ultrasonic ranger驱动的手动测试应用展开以 tests/drivers/srf08/README.md 为骨架结合驱动源码、参数配置与构建脚本完整还原该测试应用从初始化、周期测距到串口输出的全过程。读完本文你将掌握如何在任意支持periph_i2c的 RIOT 开发板上编译运行 SRF08 测试程序、如何解读三个回波echo的打印结果、如何通过调整反射物距离验证测量值以及驱动底层 I2C 寄存器操作的实现细节。测试应用定位为什么需要手动测试RIOT 的tests/目录下每个驱动都配套对应的测试程序其中一部分属于手动测试manual test——它们不依赖自动断言而是要求开发者把程序烧录到真实硬件上通过观察串口输出、移动传感器或改变被测对象来人工判断驱动是否工作正常。SRF08 的测试应用即属于此类程序启动后周期性读取传感器数据并打印到标准输出STDOUT开发者需要把传感器对准某个反射面通过改变距离来确认第一个回波值随距离变化从而验证驱动链路I2C 通信、寄存器读写、距离换算是否真实有效。该测试的核心工程文件如下tests/drivers/srf08/main.c测试主程序负责初始化与周期采样tests/drivers/srf08/Makefile构建配置声明依赖模块tests/drivers/srf08/Makefile.ciCI 编译覆盖时的板卡排除列表tests/drivers/srf08/README.md使用说明本文主体依据。编译与运行最小构建配置测试应用的Makefile非常精简include ../Makefile.drivers_common USEMODULE xtimer USEMODULE srf08 include $(RIOTBASE)/Makefile.include其中两个USEMODULE声明了测试所需的全部功能模块srf08SRF08 驱动模块其依赖关系定义在 drivers/srf08/Makefile.dep 中——FEATURES_REQUIRED periph_i2c声明该驱动强制要求板卡提供 I2C 外设能力USEMODULE xtimer声明需要高精度软件定时器用于测量等待xtimer驱动与测试程序共用的延时/定时基础设施。Makefile.ci仅排除了一块内存不足的板卡atmega8意味着除atmega8外所有支持periph_i2c的板卡如native、samr21-xpro、nucleo-f401re等都在 CI 编译覆盖范围内。在任意支持 I2C 的板卡上编译运行的标准流程为在tests/drivers/srf08目录下make BOARDboard-name flash term例如使用native平台做语法级验证make BOARDnative测试主程序逐段解析main.c完整实现了 README 描述的流程代码结构清晰可以拆成四个环节。1. 编译期可配置的测试参数#ifndef TEST_MODE #define TEST_MODE (SRF08_MODE_CM) #endif #ifndef TEST_NUM_ECHOS #define TEST_NUM_ECHOS (3U) #endif #define SLEEP_USEC (1000 * US_PER_MS)TEST_MODE默认取SRF08_MODE_CM即以厘米为单位输出测距结果TEST_NUM_ECHOS默认取3U即每次测距最多读取并打印3 个回波对应 README 中 three echos are stored 的说法SLEEP_USEC为 1000ms控制两次测量之间的打印节奏。这三个宏均可在编译时通过CFLAGS覆盖例如想以英寸为单位、每次读取 5 个回波可执行make BOARDboard-name CFLAGS-DTEST_MODESRF08_MODE_INCH -DTEST_NUM_ECHOS52. 传感器初始化与失败处理res srf08_init(srf08_0, srf08_params[0]); if (res 0) { printf([Failed]); return 1; } else { puts([Ok]\n); ... }初始化参数直接取自驱动自带的默认参数表srf08_params[0]。程序启动时会打印当前使用的 I2C 外设编号I2C_%i若初始化失败返回值小于 0则打印[Failed]并以退出码 1 结束成功则打印[Ok]后进入主循环。3. 周期测距与回波打印while (1) { uint16_t range_array[TEST_NUM_ECHOS]; int echo_number srf08_get_distances(srf08_0, range_array, TEST_NUM_ECHOS, TEST_MODE); if (echo_number 0) { for (int i 0; i echo_number; i) { printf(stored distance %i cm , echo%i\n, range_array[i], i 1); } puts(--------------------------------------------); } else { puts(An error occurred); } xtimer_usleep(SLEEP_USEC); }主循环每 1000ms 执行一次调用srf08_get_distances()触发一次测距最多取TEST_NUM_ECHOS3个回波存入range_array若返回值大于 0按顺序打印每个回波的距离值格式为stored distance XX cm , echoN并用一行分隔线----区分不同周期若返回值为负测距出错打印An error occurred。README 中三个回波被存储three echos are stored描述的正是srf08_get_distances内部会依次读取 3 个 echo 缓冲区这一行为。值得说明的是SRF08 最多可检测17 个目标SRF08_MAX_ECHO_NUMBER这里只取了前 3 个回波编号echo1、echo2、echo3依次对应从近到远的不同反射目标。4. 验证方法改变反射距离观察 echo1README 给出了最核心的验证手段To verify the seen values you can focus the sensor against any reflecting object and vary the distance to see especially the first measured value changing.即把传感器对准任意一个反射面墙壁、纸板等来回改变传感器与反射面的距离此时应能观察到第一个回波值echo1随距离明显变化。echo1 是距离最近的反射目标对距离变化最敏感而后面的回波可能来自更远处、更弱的多次反射变化可能不那么直观。驱动层原理I2C 寄存器读写如何支撑测试测试程序之所以能周期性读到距离底层依赖 drivers/srf08/srf08.c 的驱动实现。SRF08 与 MCU 之间通过I2C 接口通信地址默认为0x70即器件手册中的 0xE0 右移一位见 drivers/srf08/include/srf08_params.h。寄存器布局drivers/include/srf08.h 定义了驱动使用的关键寄存器寄存器偏移用途SRF08_COMMAND_REG0x0写入测距命令ranging modeSRF08_GAIN_REG0x1写入最大增益max gainSRF08_RANGE_REG0x2写入最大量程max rangeSRF08_RANGE_HIGH_BYTE/SRF08_RANGE_LOW_BYTE0x2 / 0x3读取第一个回波的高、低字节SRF08_MAX_REGISTER_NUMBER35可读寄存器的最高编号限制一次最多读 17 个回波srf08_init初始化即完成两项关键配置int srf08_init(srf08_t *dev, const srf08_params_t *params) { dev-params *params; /* set the maximum range */ if (srf08_set_max_range(dev, SRF08_MAX_RANGE_6M) 0) { return -3; } /* set the maximum gain */ if (srf08_set_max_gain(dev, SRF08_MAX_GAIN) 0) { return -4; } return 0; }初始化时驱动会默认写入两项寄存器配置srf08_set_max_range()将量程寄存器写为SRF08_MAX_RANGE_6M0x8C对应6 米硬件量程上限。根据头文件注释实际量程按公式max_range (max_range × 43mm) 43mm计算srf08_set_max_gain()将增益寄存器写为SRF08_MAX_GAIN0x1F对应增益 1025。头文件特别说明该值只是模拟放大级的上限而非实际增益测量过程中增益会从最小值开始、大约每 75µs 递增一次直至达到该上限。两个写寄存器操作均通过i2c_acquire()/i2c_release()包裹以保证多线程环境下对 I2C 总线的独占访问。若量程设置失败返回 -3增益设置失败返回 -4——这也解释了main.c中res 0即判失败的判断依据。srf08_get_distances一次完整测距的时序int srf08_get_distances(const srf08_t *dev, uint16_t *range_array, int num_echos, srf08_mode_t ranging_mode) { ... char max_reg_no_read (num_echos * sizeof(range_bytes)) 1; i2c_acquire(SRF08_DEV_I2C); /* set ranging mode */ status i2c_write_reg(SRF08_DEV_I2C, SRF08_DEV_ADDR, SRF08_COMMAND_REG, ranging_mode, 0); i2c_release(SRF08_DEV_I2C); ... xtimer_usleep(70000); /* read all echo buffers */ for (register_location 2; register_location max_reg_no_read; register_location sizeof(range_bytes)) { ... status i2c_read_regs(SRF08_DEV_I2C, SRF08_DEV_ADDR, register_location, range_bytes, sizeof(range_bytes), 0); ... uint16_t distance (range_bytes[0] 8) | range_bytes[1]; range_array[(register_location - 2) / 2] distance; echo_number; } return echo_number; }一次测距的完整时序如下写命令向命令寄存器0x0写入ranging_mode。该参数来自srf08_mode_t枚举共 6 种取值三种真实测距模式SRF08_MODE_INCH0x50单位英寸、SRF08_MODE_CM0x51单位厘米测试默认、SRF08_MODE_MICRO_SEC0x52单位微秒可换算成距离三种伪测距模式SRF08_ANN_MODE_INCH0x53、SRF08_ANN_MODE_CM0x54、SRF08_ANN_MODE_MICRO_SEC0x55后三者用于校准不发射超声波脉冲。等待 70msxtimer_usleep(70000)等待声波往返最大 6m 量程对应的声波飞行时间。读取回波缓冲区从寄存器 0x2 开始每间隔 2 字节一个 16 位距离值读取一个回波直至读够num_echos个。每个回波值由高、低字节拼接而成distance (range_bytes[0] 8) | range_bytes[1]。合法性检查若写命令失败返回 -1若请求的回波数导致寄存器越界超过最高寄存器号 35即最多 17 个回波返回 -2读取失败返回 -3。main.c中每 1000ms 循环调用一次该函数正好覆盖了写入命令 → 等待 → 读取回波这一完整测距周期打印出的 3 个值即为range_array中前 3 个回波的距离。默认参数与板级覆盖drivers/srf08/include/srf08_params.h 提供了一套可被板级配置覆盖的默认参数#ifndef SRF08_PARAM_I2C #define SRF08_PARAM_I2C I2C_DEV(0) #endif #ifndef SRF08_PARAM_ADDR #define SRF08_PARAM_ADDR (0x70) /* 0xE0 shifted by 1 */ #endif #ifndef SRF08_PARAMS #define SRF08_PARAMS { .i2c SRF08_PARAM_I2C, \ .addr SRF08_PARAM_ADDR } #endif默认挂载在I2C 总线 0I2C_DEV(0)默认器件地址0x70若某块板卡的 SRF08 实际连接在其它 I2C 总线上可在板级board.h或应用Makefile中定义SRF08_PARAM_I2C/SRF08_PARAM_ADDR覆盖例如CFLAGS -DSRF08_PARAM_I2CI2C_DEV(1)参数表以srf08_params[]数组形式暴露SRF08_NUMOF宏给出设备数量默认 1这正是main.c中srf08_params[0]的来源。快速上手清单确认板卡支持periph_i2c可查看板卡目录下的Makefile.features将 SRF08 的 SDA/SCL 连接到板卡 I2C 总线 0 对应引脚确认器件地址为 0x70在tests/drivers/srf08目录执行make BOARDboard-name flash term观察串口输出Initializing SRF08 sensor at I2C_0... [Ok]随后应周期性出现stored distance XX cm , echo1/2/3把传感器对准反射面并前后移动确认echo1数值随之变化若输出An error occurred或初始化失败检查接线、I2C 总线编号与供电。小结SRF08 的手动测试应用虽然代码量不大却完整覆盖了 RIOT 外设驱动测试的标准范式通过srf08_params[]默认参数完成初始化、利用srf08_get_distances()的 I2C 寄存器时序完成周期采样、以改变反射距离观察 echo1作为人工验证手段。结合 drivers/srf08/srf08.c、drivers/include/srf08.h 与 drivers/srf08/include/srf08_params.h 三个源码文件开发者既可以把它当作现成的硬件验证工具也可以作为编写其他 I2C 传感器手动测试的参考模板。【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表