Files
GD32E230_VL53L4CD/README.md
T

12 KiB
Raw Blame History

GD32E230 + VL53L4CD 测距项目

本仓库是基于 GD32E230 的 VL53L4CD 时间飞行(ToF)测距项目,硬件兼容 Adafruit VL53L4CD 模块。固件通过 I2C 驱动传感器,每 500ms 输出一次距离和测距质量参数。

目录

硬件连接

主控

  • MCUGD32E230 系列,Cortex-M23
  • 系统时钟:72MHz
  • Flash16KF4/ 32KF6/ 64KF8),上电自动识别

VL53L4CD

信号 引脚 说明
SCL PA9 I2C0 时钟,AF4
SDA PA10 I2C0 数据,AF4
VDD 3.3V 模块供电
GND GND 共地

传感器 7 位 I2C 地址默认为 0x29

串口

信号 引脚 说明
TX PA2 RS485 发送
RX PA3 RS485 接收
DE PA1 RS485 方向控制,硬件自动控制

波特率 1152008N1。

其他

  • LEDPB1
  • SWDSWDIO、SWCLK、GND,用于 DAPLink 烧录与调试

功能开关

所有开关集中在 Inc/board_config.h

当前值 作用
DEBUG_MODE CFG_DISABLE 关闭 Hello World 启动横幅;距离输出仍保留
DEBUG_VERBOSE CFG_DISABLE 关闭 IIC 调试打印和启动 I2C 扫描
COM_DEBUG CFG_DISABLE 关闭命令帧调试打印
SEGGER_RTT_DETECTION CFG_DISABLE 关闭 SEGGER RTT
VL53L4CD_CALIB_TARGET_MM 44 当前安装位置的目标实际距离
VL53L4CD_CALIB_SAMPLES 20 校准采样次数
VL53L4CD_AUTO_CALIB CFG_DISABLE 开机自动校准开关
VL53L4CD_CALIB_OFFSET_MM -9 当前固定的距离偏移量
VL53L4CD_GLASS_XTALK CFG_DISABLE 透过玻璃测距:开机写入串扰补偿
VL53L4CD_GLASS_XTALK_KCPS 20 编译期固定串扰值,单位 kcps,0..127
VL53L4CD_XTALK_CALIB_TARGET_MM 500 M104 串扰校准默认目标距离(玻璃后方)
VL53L4CD_XTALK_CALIB_SAMPLES 20 M104 串扰校准默认采样次数
VL53L4CD_PERSIST_CALIB CFG_ENABLE 开机优先从 Flash 末页加载校准数据
RS485_MODE CFG_ENABLE 使用 RS485 串口输出
SOFTWARE_IIC CFG_DISABLE 使用硬件 I2C

如果需要临时扫描 I2C 总线或查看 IIC 调试信息,把 DEBUG_VERBOSE 改为 CFG_ENABLE。注意 16K Flash 下全开会让固件体积非常紧张。

编译与烧录

编译

在仓库根目录执行:

cmake --preset Release
cmake --build Build/Release

Debug 构建:

cmake --preset Debug
cmake --build Build/Debug

产物位于 Build/Release/Application/

  • Application.elf
  • Application.hex
  • Application.bin
  • Application.map

烧录

通过 DAPLink/CMSIS-DAP 烧录:

D:/toolchain/openocd/bin/openocd.exe \
  -s D:/toolchain/openocd/scripts \
  -f interface/cmsis-dap.cfg \
  -f target/gd32e23x.cfg \
  -c "reset_config srst_only connect_assert_srst; init; reset halt; flash write_image erase Build/Release/Application/Application.elf; reset; exit"

也可以在 VSCode 中使用已配置的 Flash 任务。

串口命令(Mx

命令帧格式 D5 01 LEN [命令] CRC(LEN 为命令字节数,CRC 为帧内累加和),响应帧 B5 TYPE LEN [数据] CRCTYPE=0xF0 表示成功。波特率 115200,8N1。

基础命令

命令 功能 成功响应
M1 开启测距上报,LED 亮 ok
M2 关闭测距上报,LED 灭 ok
M3 立即返回最近一帧结果(上报关闭时也可查询) d=830;s=0
M888 软件重启 ok 后复位
M999 输出固件版本号 v20.0.0.1
M9999 复位进入 OTA/Bootloader 复位

校准命令

命令 功能 成功响应
M101 读取当前偏移量 o=-9
M101S<mm> 写入偏移量并立即生效,如 M101S-9 o=-9
M102S<mm> 执行偏移校准,S 为目标实际距离(默认 44 o=-9
M103 读取当前串扰补偿值 x=12
M103S<kcps> 写入串扰补偿值 0..127,如 M103S12 x=12
M104S<mm> 执行串扰校准,S 为玻璃后方目标距离(默认 500 x=12
M105 保存当前偏移+串扰到 Flash(掉电保持) ok
M106 从 Flash 读取并应用校准数据 o=-9
M107 擦除 Flash 校准数据,偏移/串扰清零 ok

说明:

  • M102/M104 为阻塞执行,耗时约 2 秒,期间连续上报暂停。
  • M101S/M103S/M102/M104 只改寄存器,掉电丢失;需要掉电保持时接一条 M105
  • 参数错误返回 0xFD,未知命令返回 0xFE,校准/Flash 失败返回 0xFF

串口输出

连接串口后使用 115200 8N1 查看,例如 COM17

Distance: 830 mm | status: 0 | signal: 1128 kcps | ambient: 72 kcps | sigma: 3 mm

默认每 500ms 输出一次。

VL53L4CD 驱动

驱动文件:

  • Inc/VL53L4CD_Driver.h
  • Src/VL53L4CD_Driver.c

主要接口

函数 作用
vl53l4cd_init() 初始化传感器,写入默认配置,默认 50ms 时序预算
vl53l4cd_start_ranging() 启动连续测距
vl53l4cd_stop_ranging() 停止连续测距
vl53l4cd_data_ready() 查询是否有新结果
vl53l4cd_clear_interrupt() 清除测距完成中断
vl53l4cd_get_result() 读取并解析测距结果
vl53l4cd_set_range_timing() 设置 10-200ms 时序预算,当前仅支持连续模式
vl53l4cd_set_offset(offset_mm) 写入手动指定的距离偏移量
vl53l4cd_get_offset(&offset_mm) 读取当前生效的距离偏移量
vl53l4cd_calibrate_offset(target_mm, samples, &offset) 对当前目标执行偏移校准并写回
vl53l4cd_set_xtalk(xtalk_kcps) 写入串扰补偿值(透过玻璃),0..127 kcps
vl53l4cd_get_xtalk(&xtalk_kcps) 读取当前串扰补偿值
vl53l4cd_calibrate_xtalk(target_mm, samples, &xtalk) 执行串扰校准并写回
vl53l4cd_read_reg8/16() 读 8/16 位寄存器
vl53l4cd_write_reg8/16() 写 8/16 位寄存器

偏移校准

VL53L4CD 出厂带有默认偏移,但器件之间存在差异,固定安装场景建议做一次单点校准。

当前安装位置的目标距离为 44mm,已通过 20 帧有效采样完成校准,校准得到的偏移量为 -9mm。固件在 vl53l4cd_init() 后调用 vl53l4cd_set_offset(VL53L4CD_CALIB_OFFSET_MM) 写回,因此每次上电都会保持校准结果。

需要重新校准时:

  1. 把目标放在已知距离,例如 44mm。
  2. Inc/board_config.hVL53L4CD_AUTO_CALIB 改为 CFG_ENABLE
  3. 上电后串口会打印 VL53L4CD offset calibrated: X mm
  4. 把打印出的 X 填入 VL53L4CD_CALIB_OFFSET_MM,再将 VL53L4CD_AUTO_CALIB 改回 CFG_DISABLE

也可以不发固件、直接用串口命令在线校准:目标放好后依次发送 M102S44(校准)、M105(保存到 Flash)。M101 可随时读回当前偏移。

也可以直接调用 vl53l4cd_calibrate_offset(),该函数会先清零偏移、热机 10 帧,再统计有效测距样本并计算 offset = 实际距离 - 平均距离,最后写入 RANGE_OFFSET_MM (0x001E)

注意:单点偏移只修正当前固定距离的绝对误差。近距离高反射金属目标存在非线性,建议使用哑光目标。

透过玻璃测距(Crosstalk

传感器透过盖板玻璃测距时,玻璃上下表面的反射会产生串扰(crosstalk),表现为读数偏小、近距离出现固定虚假目标。VL53L4CD 通过 XTALK 寄存器组(0x0016..0x001D)做信号级补偿。

固件按 ST ULD 官方算法(vl53l4cd_calibration.c)实现,并改为定点数运算以省 Flash:

xtalk = (1 - 平均距离/目标距离) * 平均信号速率/平均SPAD数

上限 127 kcps,超出判定为校准失败;寄存器值为 xtalk_kcps * 512

使用方式

方式一:编译期固定值(不使用串口)

  1. 测得或校准出串扰值后,打开 VL53L4CD_GLASS_XTALK,把值填入 VL53L4CD_GLASS_XTALK_KCPS
  2. Flash 中无校准数据时,开机自动写入该值。

方式二:串口命令(推荐)

  1. 装上玻璃,目标放在玻璃后方已知距离(如 500mm),确保目标与玻璃之间无遮挡。
  2. 先完成偏移校准:M102S44
  3. 执行串扰校准:M104S500,返回如 x=12
  4. M105 保存到 Flash,掉电不丢。
  5. M103 可随时读回当前串扰值。

注意:偏移校准与串扰校准相互影响,重新校准其中一项后建议两项都重新校准并再次 M105 保存。

校准数据 Flash 存储

校准数据(偏移 + 串扰)保存在主 Flash 的最后一页(1KB),由 Src/calib_store.c 管理:

器件 校准页地址
16KF4 0x0800 3C00
32KF6 0x0800 7C00
64KF8 0x0800 FC00
  • 页地址按上电检测到的 Flash 容量动态计算,一份固件适配三种容量。
  • 记录 16 字节,含魔数 CVL4、版本号、累加和校验;空白 Flash(全 0xFF)不会误判。
  • 链接脚本代码区已缩至 15K,避免代码长入校准页;擦写通过 GD32 SDK 的 fmc_page_erase() / fmc_doubleword_program() 完成,操作期间短暂暂停串口接收中断。
  • 上电加载顺序(VL53L4CD_PERSIST_CALIB = CFG_ENABLE 时):Flash 有有效数据 → 用 Flash 值;否则用 VL53L4CD_CALIB_OFFSET_MM(及开启 VL53L4CD_GLASS_XTALK 时的固定串扰值)。

修改时序预算

Src/VL53L4CD_Driver.cvl53l4cd_init() 末尾:

return vl53l4cd_set_range_timing(50U, 0U);

第一个参数是时序预算,范围 10-200ms。第二个参数当前只能传 0,表示连续测距模式。

修改输出间隔

Src/main.c 主循环中:

delay_ms(500);

改为需要的毫秒数即可。

I2C 16 位寄存器说明

测距结果字段

vl53l4cd_get_result() 返回 vl53l4cd_result_t

字段 含义
distance_mm 距离,单位 mm
range_status 测距状态码
number_of_spad 有效 SPAD 数
signal_rate_kcps 目标反射信号强度
ambient_rate_kcps 环境光/背景噪声强度
signal_per_spad_kcps 每个 SPAD 的信号强度
ambient_per_spad_kcps 每个 SPAD 的环境光强度
sigma_mm 测距噪声/不确定度,单位 mm

测距状态码

状态码 含义
0 测距有效
1 Sigma 超限,结果不稳定
2 信号太弱,目标太远、太黑或反射率低
3 目标过近
4 相位故障
5 硬件故障
6 未检测到目标
7 近距离信号不足
255 未知状态

I2C 16 位寄存器说明

VL53L4CD 的寄存器地址是 16 位。本项目的 i2c_read() / i2c_write() 已改为支持 uint16_t 寄存器地址,发送时先发高字节、再发低字节。

对原有 8 位寄存器地址的 I2C 器件仍然兼容:地址高字节为 0x00,发送序列与原来一致。

Flash 体积说明

链接脚本代码区为 15K(16K 容量器件预留最后 1KB 页存放校准数据)。当前 Release 固件约:

text   12908
data      24
bss     1704

15K 内仍有约 2.4K 余量。为省体积,主循环测距上报与启动信息改为手写格式化输出(不再链接 vfprintf,省约 2.7K),输出格式与旧版本逐字节一致。Debug 构建优化等级由 -O0 调整为 -Og(-O0 已无法放下),text 约 14876。保留 printf 会增加约 2.5K,因此 DEBUG_VERBOSE 全开仍会让 Flash 非常紧张。

已知限制

  • 驱动只支持连续测距模式
  • 距离阈值中断、自主低功耗模式、ULP 模式尚未实现
  • VL53L4CD 是单区传感器,不是多区测距
  • 串扰补偿为单区平面补偿(梯度寄存器清零),玻璃需正对传感器且尽量平行
  • DEBUG_VERBOSE 全开时 IIC 调试打印会让 Flash 非常紧张

变更记录

当前迭代的详细说明见 CHANGES.md