CW32L012的TOF200C激光测距案例分享 前言本实验用CW32L012作为主控TOF200C为激光测距模块最终测得距离在串口助手中显示。一、TOF200C传感器模块介绍TOF200C VL53L0X是ST公司推出的新一代 ToF 激光测距传感器采用了第二代 FlightSenseTM技术利用飞行时间ToF原理通过光子的飞行来回时间与光速的计算实现测距应用。较比上一代 VL6180X新的器件将飞行时间测距长度扩展至 2 米测量速度更快能效更高。除此之外为使集成度过程更加快捷方便 ST 公司为此也提供了 VL53L0X 软件 API应用编程接口以及完整的技术文档通过主 IIC 接口向应用端输出测距的数据大大降低了开发难度。VL53L0X的感测能力可以支持各种功能包括各种创新用户界面的手势感测或接近检测扫地机器人、服务型机器人的障碍物探测与防撞系统家电感应面板、笔记本电脑的用户存在检测或电源开关监控器以及无人机和物联网(IoT)产品等。下附传感器实物图CW32L012主板。TOF200C激光测距模块CW32L012主板二、TOF200C工作原理1.发射端内置940nm 近红外 VCSEL垂直腔面发射激光器发射人眼安全Class 1的短激光脉冲。2.接收端反射光子经透镜与窄带滤光片滤环境光打到SPAD单光子雪崩二极管阵列。SPAD 单光子灵敏、雪崩放大把弱光转为电脉冲。3.计时与计算内置TDC时间数字转换器皮秒级精度记录光子往返时间t。用TCSPC时间相关单光子计数发数百次脉冲统计 “时间-光子数直方图”取主峰得精准t。距离公式dct/2光速c≈3×10的八次方米每秒÷2 因往返TOF200C优点1.窄带滤光 阳光抑制算法80klux 强光稳定。2.内置玻璃盖板校准不用用户写校准流程。3.使用I2CUART 双接口用户可以自行选择。三、软件讲解本TOF200C模块使用I2C进行通讯下附Keil工程中代码例程vl53l0x_i2c.c以及vl53l0x_i2c.h bsp_VL53L0X.c以及bsp_VL53L0X.hbsp_uart.c以及bsp_uart.hmain等核心文件#include vl53l0x_i2c.h #include cw32l012_gpio.h #include cw32l012_sysctrl.h /* 端口定义 */ #define PORT_VL53L0x CW_GPIOB #define GPIO_SCL GPIO_PIN_6 #define GPIO_SDA GPIO_PIN_7 #define PORT_XSHUT CW_GPIOA #define GPIO_XSHUT GPIO_PIN_8 /* 简单循环延时 */ void Simple_Delay(uint32_t count) { while(count--) { __NOP(); } } /* 终极兼容延时将频率降到 50kHz 左右确保电平上升沿完整 */ #define IIC_DELAY() Simple_Delay(1000) /* 核心策略不再切换输入/输出方向。 将 SDA 始终保持为开漏输出模式Output_OD。 - 当我们要发送 1 或读取时向 ODR 写入 1释放总线靠上拉电阻拉高。 - 当我们要发送 0 时向 ODR 写入 0强行拉低。 */ #define SCL_LOW() PORT_VL53L0x-BRR GPIO_SCL #define SCL_HIGH() PORT_VL53L0x-BSRR GPIO_SCL #define SDA_LOW() PORT_VL53L0x-BRR GPIO_SDA #define SDA_HIGH() PORT_VL53L0x-BSRR GPIO_SDA #define SDA_GET() ((PORT_VL53L0x-IDR GPIO_SDA) ! 0) void VL53L0X_i2c_init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; __SYSCTRL_GPIOA_CLK_ENABLE(); __SYSCTRL_GPIOB_CLK_ENABLE(); // SCL 和 SDA 全部配置为开漏输出 开启内部上拉 GPIO_InitStruct.Pins GPIO_SCL | GPIO_SDA; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.IT GPIO_IT_NONE; GPIO_Init(PORT_VL53L0x, GPIO_InitStruct); // 强制开启内部上拉防止外部电阻虚接 PORT_VL53L0x-PUR | (GPIO_SCL | GPIO_SDA); // XSHUT 配置为推挽输出 GPIO_InitStruct.Pins GPIO_XSHUT; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_Init(PORT_XSHUT, GPIO_InitStruct); // 硬件复位流程 GPIO_WritePin(PORT_XSHUT, GPIO_XSHUT, GPIO_Pin_RESET); Simple_Delay(2000000); GPIO_WritePin(PORT_XSHUT, GPIO_XSHUT, GPIO_Pin_SET); Simple_Delay(2000000); SCL_HIGH(); SDA_HIGH(); } void IIC_Start(void) { SDA_HIGH(); SCL_HIGH(); IIC_DELAY(); SDA_LOW(); IIC_DELAY(); SCL_LOW(); IIC_DELAY(); } void IIC_Stop(void) { SCL_LOW(); SDA_LOW(); IIC_DELAY(); SCL_HIGH(); IIC_DELAY(); SDA_HIGH(); IIC_DELAY(); } uint8_t I2C_WaitAck(void) { uint16_t retry 0; SDA_HIGH(); // 释放 SDA让传感器有机会拉低它 IIC_DELAY(); SCL_HIGH(); IIC_DELAY(); // 给传感器留出应答时间 while(SDA_GET()) { retry; if(retry 5000) { IIC_Stop(); printf(WaitAck Timeout!\r\n); // 增加调试打印 return 1; } } SCL_LOW(); IIC_DELAY(); return 0; } void Send_Byte(uint8_t dat) { uint8_t i; for(i 0; i 8; i) { if(dat 0x80) SDA_HIGH(); else SDA_LOW(); dat 1; IIC_DELAY(); SCL_HIGH(); IIC_DELAY(); SCL_LOW(); IIC_DELAY(); } } uint8_t Read_Byte(uint8_t ack) { uint8_t i, receive 0; SDA_HIGH(); // 释放总线 IIC_DELAY(); for(i 0; i 8; i) { SCL_LOW(); IIC_DELAY(); SCL_HIGH(); IIC_DELAY(); receive 1; if(SDA_GET()) receive; IIC_DELAY(); } SCL_LOW(); IIC_DELAY(); if (ack) SDA_LOW(); else SDA_HIGH(); IIC_DELAY(); SCL_HIGH(); IIC_DELAY(); SCL_LOW(); IIC_DELAY(); return receive; } // ---------------- 以下为接口封装保持不变 ---------------- uint8_t VL_IIC_Write_nByte(uint8_t SlaveAddress, uint8_t REG_Address, uint16_t len, uint8_t *buf) { IIC_Start(); Send_Byte(SlaveAddress); if(I2C_WaitAck()) { IIC_Stop(); return 1; } Send_Byte(REG_Address); if(I2C_WaitAck()) { IIC_Stop(); return 1; } while(len--) { Send_Byte(*buf); if(I2C_WaitAck()) { IIC_Stop(); return 1; } } IIC_Stop(); return 0; } uint8_t VL_IIC_Read_nByte(uint8_t SlaveAddress, uint8_t REG_Address, uint16_t len, uint8_t *buf) { IIC_Start(); Send_Byte(SlaveAddress); if(I2C_WaitAck()) { IIC_Stop(); return 1; } Send_Byte(REG_Address); if(I2C_WaitAck()) { IIC_Stop(); return 1; } IIC_Start(); Send_Byte(SlaveAddress | 0x01); if(I2C_WaitAck()) { IIC_Stop(); return 1; } while(len) { *buf Read_Byte(len 1); buf; len--; } IIC_Stop(); return 0; } uint8_t VL53L0X_write_multi(uint8_t address, uint8_t index, uint8_t *pdata, uint16_t count) { return VL_IIC_Write_nByte(address, index, count, pdata); } uint8_t VL53L0X_read_multi(uint8_t address, uint8_t index, uint8_t *pdata, uint16_t count) { return VL_IIC_Read_nByte(address, index, count, pdata); } uint8_t VL53L0X_write_byte(uint8_t address, uint8_t index, uint8_t data) { return VL_IIC_Write_nByte(address, index, 1, data); } uint8_t VL53L0X_write_word(uint8_t address, uint8_t index, uint16_t data) { uint8_t b[2]; b[0](uint8_t)(data8); b[1](uint8_t)data; return VL_IIC_Write_nByte(address, index, 2, b); } uint8_t VL53L0X_write_dword(uint8_t address, uint8_t index, uint32_t data) { uint8_t b[4]; b[0](uint8_t)(data24); b[1](uint8_t)(data16); b[2](uint8_t)(data8); b[3](uint8_t)data; return VL_IIC_Write_nByte(address, index, 4, b); } uint8_t VL53L0X_read_byte(uint8_t address, uint8_t index, uint8_t *pdata) { return VL_IIC_Read_nByte(address, index, 1, pdata); } uint8_t VL53L0X_read_word(uint8_t address, uint8_t index, uint16_t *pdata) { uint8_t b[2]; uint8_t sVL_IIC_Read_nByte(address, index, 2, b); *pdata((uint16_t)b[0]8)|b[1]; return s; } uint8_t VL53L0X_read_dword(uint8_t address, uint8_t index, uint32_t *pdata) { uint8_t b[4]; uint8_t sVL_IIC_Read_nByte(address, index, 4, b); *pdata((uint32_t)b[0]24)|((uint32_t)b[1]16)|((uint32_t)b[2]8)|b[3]; return s; } #ifndef __VL53L0_I2C_H #define __VL53L0_I2C_H #include stdint.h // 1. 统一使用标准库定义的类型兼容旧代码 typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; // 2. 状态定义 #define STATUS_OK 0x00 #define STATUS_FAIL 0x01 // 3. I2C 底层操作函数声明 void VL53L0X_i2c_init(void); // 初始化引脚和复位传感器 void IIC_Start(void); // 起始信号 void IIC_Stop(void); // 停止信号 uint8_t I2C_WaitAck(void); // 等待应答 void Send_Byte(uint8_t dat); // 发送字节 uint8_t Read_Byte(uint8_t ack); // 读取字节 // 4. VL53L0X 官方 API 所需的底层读写接口声明 // 这些声明必须存在否则 vl53l0x_platform.c 编译会报错 uint8_t VL53L0X_write_multi(uint8_t address, uint8_t index, uint8_t *pdata, uint16_t count); uint8_t VL53L0X_read_multi(uint8_t address, uint8_t index, uint8_t *pdata, uint16_t count); uint8_t VL53L0X_write_byte(uint8_t address, uint8_t index, uint8_t data); uint8_t VL53L0X_write_word(uint8_t address, uint8_t index, uint16_t data); uint8_t VL53L0X_write_dword(uint8_t address, uint8_t index, uint32_t data); uint8_t VL53L0X_read_byte(uint8_t address, uint8_t index, uint8_t *pdata); uint8_t VL53L0X_read_word(uint8_t address, uint8_t index, uint16_t *pdata); uint8_t VL53L0X_read_dword(uint8_t address, uint8_t index, uint32_t *pdata); #endif#include bsp_vl53l0x.h #include cw32l012_gpio.h #include cw32l012_sysctrl.h #include stdio.h /* 外部延时函数声明 (需在main或sysctrl.c中实现) */ extern void delay_ms(uint32_t ms); /* 全局变量定义 */ VL53L0X_RangingMeasurementData_t vl53l0x_data; VL53L0X_Dev_t vl53l0x_dev; // 设备数据参数 VL53L0X_DeviceInfo_t vl53l0x_dev_info; // 设备信息 uint8_t AjustOK 0; // 校准标志位 /* 测量模式参数严格对照你提供的官方建议配置 */ mode_data Mode_data[] { {(FixPoint1616_t)(0.25*65536), (FixPoint1616_t)(18*65536), 33000, 14, 10}, // 默认 {(FixPoint1616_t)(0.25*65536), (FixPoint1616_t)(18*65536), 200000, 14, 10},// 高精度 {(FixPoint1616_t)(0.1*65536) , (FixPoint1616_t)(60*65536), 33000, 18, 14}, // 长距离 {(FixPoint1616_t)(0.25*65536), (FixPoint1616_t)(32*65536), 20000, 14, 10} // 高速 }; /** * brief 打印 PAL 层错误信息 * note 依赖你提供的串口重定向 printf */ void print_pal_error(VL53L0X_Error Status) { char buf[VL53L0X_MAX_STRING_LENGTH]; VL53L0X_GetPalErrorString(Status, buf); printf(VL53L0X Error: %i : %s\r\n, Status, buf); } /** * brief VL53L0X 综合初始化 * note 适配 CW32L012 寄存器与引脚控制 */ VL53L0X_Error vl53l0x_init(VL53L0X_Dev_t *dev) { VL53L0X_Error Status VL53L0X_ERROR_NONE; uint32_t refSpadCount; uint8_t isApertureSpads; uint8_t VhvSettings; uint8_t PhaseCal; // 1. 初始化 XSHUT 引脚 (PA8) - CW32风格 __SYSCTRL_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pins GPIO_PIN_8; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_Init(CW_GPIOA, GPIO_InitStruct); // 2. 初始化底层 I2C 接口 (调用适配过的模拟I2C) VL53L0X_i2c_init(); // 3. 硬件唤醒流程 (CW32引脚操作) GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_RESET); // XSHUT LOW delay_ms(20); GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_SET); // XSHUT HIGH delay_ms(20); // 4. 设备基础设置 dev-I2cDevAddr 0x52; // 默认地址 dev-comms_type 1; // I2C 模式 dev-comms_speed_khz 400; // 5. 数据初始化 Status VL53L0X_DataInit(dev); if(Status ! VL53L0X_ERROR_NONE) goto error; // 6. 获取设备信息 Status VL53L0X_GetDeviceInfo(dev, vl53l0x_dev_info); if(Status ! VL53L0X_ERROR_NONE) goto error; // 7. 静态初始化 Status VL53L0X_StaticInit(dev); if(Status ! VL53L0X_ERROR_NONE) goto error; // 8. 参考 Spad 管理与校准 Status VL53L0X_PerformRefSpadManagement(dev, refSpadCount, isApertureSpads); if(Status ! VL53L0X_ERROR_NONE) goto error; Status VL53L0X_PerformRefCalibration(dev, VhvSettings, PhaseCal); if(Status ! VL53L0X_ERROR_NONE) goto error; // 9. 设置为连续测量模式 Status VL53L0X_SetDeviceMode(dev, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); if(Status ! VL53L0X_ERROR_NONE) goto error; printf(VL53L0X HW Init Success!\r\n); return VL53L0X_ERROR_NONE; error: print_pal_error(Status); return Status; } /** * brief 设置测量模式 */ VL53L0X_Error vl53l0x_set_mode(VL53L0X_Dev_t *dev, uint8_t mode) { VL53L0X_Error Status VL53L0X_ERROR_NONE; if(mode 3) return VL53L0X_ERROR_INVALID_PARAMS; Status VL53L0X_SetLimitCheckValue(dev, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Mode_data[mode].signalLimit); if(Status ! VL53L0X_ERROR_NONE) return Status; Status VL53L0X_SetLimitCheckValue(dev, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, Mode_data[mode].sigmaLimit); if(Status ! VL53L0X_ERROR_NONE) return Status; Status VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, Mode_data[mode].timingBudget); if(Status ! VL53L0X_ERROR_NONE) return Status; Status VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, Mode_data[mode].preRangeVcselPeriod); if(Status ! VL53L0X_ERROR_NONE) return Status; Status VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, Mode_data[mode].finalRangeVcselPeriod); return Status; } #ifndef __BSP_VL53L0X_H #define __BSP_VL53L0X_H #include vl53l0x_api.h #include vl53l0x_platform.h #include cw32l012.h #include cw32l012_gpio.h #include stdint.h /* XSHUT 引脚控制宏 (PA8) - 适配 CW32 库函数 */ #define VL53L0X_XSHUT_LOW() GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_RESET) #define VL53L0X_XSHUT_HIGH() GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_SET) /* 测量模式宏定义 */ #define Default_Mode 0 #define HIGH_ACCURACY 1 #define LONG_RANGE 2 #define HIGH_SPEED 3 /* 模式参数结构体定义 */ typedef struct { FixPoint1616_t signalLimit; FixPoint1616_t sigmaLimit; uint32_t timingBudget; uint8_t preRangeVcselPeriod; uint8_t finalRangeVcselPeriod; } mode_data; /* 全局变量外部声明 (必须与 .c 文件中的定义严格对应) */ extern VL53L0X_Dev_t vl53l0x_dev; extern VL53L0X_RangingMeasurementData_t vl53l0x_data; extern mode_data Mode_data[]; extern uint8_t AjustOK; /* 函数声明 */ /** * brief VL53L0X 综合初始化 * param dev 设备结构体指针 * return VL53L0X_Error 错误码 */ VL53L0X_Error vl53l0x_init(VL53L0X_Dev_t *dev); /** * brief 设置测量模式默认/高精度/长距离/高速 * param dev 设备结构体指针 * param mode 模式编号 (0-3) * return VL53L0X_Error 错误码 */ VL53L0X_Error vl53l0x_set_mode(VL53L0X_Dev_t *dev, uint8_t mode); /** * brief 打印 PAL 层错误信息到串口 * param Status 错误状态码 */ void print_pal_error(VL53L0X_Error Status); /** * brief 底层模拟 I2C 初始化 * note 内部配置 PB6, PB7 为开漏输出 */ void VL53L0X_i2c_init(void); #endif#include bsp_uart.h #include stdio.h #include cw32l012_sysctrl.h #include cw32l012_gpio.h #include cw32l012_uart.h uint8_t u1_recv_buff[USART1_RECEIVE_LENGTH]; // 接收缓冲区 uint16_t u1_recv_length 0; // 接收数据长度 uint8_t u1_recv_flag 0; // 接收完成标志位 /** * brief 串口1初始化 * param __Baud 波特率 */ void uart1_init(uint32_t __Baud) { // 1. 开启 GPIOA 和 UART1 时钟 __SYSCTRL_GPIOA_CLK_ENABLE(); __SYSCTRL_UART1_CLK_ENABLE(); // 2. 引脚配置 (TX: PA09, RX: PA10) GPIO_InitTypeDef GPIO_InitStruct {0}; // TX 引脚: PA09 GPIO_InitStruct.Pins GPIO_PIN_9; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_Init(CW_GPIOA, GPIO_InitStruct); PA09_AFx_UART1TXD(); // 修正使用对应的 PA09 复用函数 // RX 引脚: PA10 GPIO_InitStruct.Pins GPIO_PIN_10; GPIO_InitStruct.Mode GPIO_MODE_INPUT_PULLUP; // 建议开启上拉防止浮空噪声 GPIO_Init(CW_GPIOA, GPIO_InitStruct); PA10_AFx_UART1RXD(); // 修正使用对应的 PA10 复用函数 // 3. UART 参数配置 UART_InitTypeDef UART_InitStruct {0}; UART_InitStruct.UART_BaudRate __Baud; UART_InitStruct.UART_Source UART_Source_PCLK; UART_InitStruct.UART_UclkFreq SystemCoreClock; // 自动获取系统主频 UART_InitStruct.UART_Mode UART_Mode_Rx | UART_Mode_Tx; // 开启全双工 UART_Init(CW_UART1, UART_InitStruct); // 4. 中断配置 // 使使能接收完成中断 (RC) 和 接收空闲中断 (RXIDLE) UART_ITConfig(CW_UART1, UART_IT_RC | UART_IT_RXIDLE, ENABLE); UART_ClearITPendingBit(CW_UART1, UART_IT_RC); UART_ClearITPendingBit(CW_UART1, UART_IT_RXIDLE); NVIC_SetPriority(UART1_IRQn, 0); NVIC_EnableIRQ(UART1_IRQn); } /** * brief printf 重定向 */ int fputc(int ch, FILE *f) { UART_SendData(CW_UART1, (uint8_t)ch); // 等待发送缓冲区空 while( UART_GetFlagStatus(CW_UART1, UART_FLAG_TXE) RESET ); return ch; } /** * brief 清除接收缓冲区 */ void uart1_receive_clear(void) { u1_recv_length 0; u1_recv_flag 0; } /** * brief 获取接收到的数据 */ uint8_t *uart1_get_data(void) { if( u1_recv_flag 1 ) { return u1_recv_buff; } return NULL; } /** * brief 串口1中断服务函数 */ void UART1_IRQHandler(void) { // 1. 处理接收完成中断 (RC) if (UART_GetITStatus(CW_UART1, UART_IT_RC) ! RESET) { if (u1_recv_length USART1_RECEIVE_LENGTH - 1) // 预留一个位置给 \0 { u1_recv_buff[u1_recv_length] UART_ReceiveData(CW_UART1); } UART_ClearITPendingBit(CW_UART1, UART_IT_RC); } // 2. 处理接收空闲中断 (RXIDLE) if (UART_GetITStatus(CW_UART1, UART_IT_RXIDLE) ! RESET) { UART_ClearITPendingBit(CW_UART1, UART_IT_RXIDLE); // 必须先清除标志位 if (u1_recv_length 0) { u1_recv_buff[u1_recv_length] \0; // 结尾补零 u1_recv_flag 1; // 标记一帧数据接收完成 } } } #ifndef __BSP_UART_H #define __BSP_UART_H #include cw32l012.h #include stdint.h #include stdio.h // 串口缓冲区的数据长度 #define USART1_RECEIVE_LENGTH 128 // 修正extern 数组时最好带上长度或者统一格式 extern uint8_t u1_recv_buff[USART1_RECEIVE_LENGTH]; extern uint16_t u1_recv_length; extern uint8_t u1_recv_flag; // 外部可调用函数声明 void uart1_init(uint32_t Baud); void uart1_receive_clear(void); uint8_t *uart1_get_data(void); #endif#include cw32l012.h #include cw32l012_sysctrl.h #include cw32l012_gpio.h #include bsp_uart.h #include bsp_VL53L0X.h #include vl53l0x_gen.h #include vl53l0x_api.h // 确保包含 API 头文件 #include stdio.h // 统一使用简单延时 extern void Simple_Delay(uint32_t count); void RCC_Configuration(void) { SystemCoreClockUpdate(); } int main(void) { VL53L0X_Error Status VL53L0X_ERROR_NONE; RCC_Configuration(); uart1_init(115200); Simple_Delay(5000000); printf(\r\n--- CW32 VL53L0X START ---\r\n); // 第一步硬件引脚初始化 printf(Step 1: Init I2C Pins...\r\n); VL53L0X_i2c_init(); // 快速扫描验证 (只需确认 0x29 是否存在) IIC_Start(); Send_Byte(0x52); // VL53L0X 默认写地址 (0x29 1) if (I2C_WaitAck() 0) { printf(I2C Check: Device Found at 0x29!\r\n); } else { printf(I2C Check: Device NOT Found! Check wiring/XSHUT.\r\n); } IIC_Stop(); printf(Step 1: Done.\r\n); // 第二步传感器软件初始化 (逐步执行) printf(Step 2-1: VL53L0X_DataInit...\r\n); vl53l0x_dev.I2cDevAddr 0x52; // 显式指定地址 Status VL53L0X_DataInit(vl53l0x_dev); if(Status ! VL53L0X_ERROR_NONE) { printf(DataInit FAILED! Error: %d\r\n, Status); } else { printf(DataInit Success! Next: StaticInit...\r\n); Status VL53L0X_StaticInit(vl53l0x_dev); if(Status ! VL53L0X_ERROR_NONE) { printf(StaticInit FAILED! Error: %d\r\n, Status); } else { printf(StaticInit Success! Next: SpadManagement...\r\n); // 这一步最耗时如果卡住请多等一会儿 uint32_t refSpadCount; uint8_t isApertureSpads; Status VL53L0X_PerformRefSpadManagement(vl53l0x_dev, refSpadCount, isApertureSpads); if(Status ! VL53L0X_ERROR_NONE) { printf(SpadManagement FAILED! Error: %d\r\n, Status); } else { printf(Step 2: ALL SUCCESS!\r\n); } } } // 第三步配置测量模式 (默认使用单次测量) if(Status VL53L0X_ERROR_NONE) { vl53l0x_set_mode(vl53l0x_dev, 0); printf(Sensor Ready to Range...\r\n); } while(1) { if(Status VL53L0X_ERROR_NONE) { Status VL53L0X_PerformSingleRangingMeasurement(vl53l0x_dev, vl53l0x_data); if(Status VL53L0X_ERROR_NONE) { printf(Distance: %d mm\r\n, vl53l0x_data.RangeMilliMeter); } else { printf(Ranging Error: %d\r\n, Status); } } else { printf(Sensor Error State, check hardware.\r\n); Simple_Delay(10000000); } Simple_Delay(5000000); } } void assert_failed(uint8_t *file, uint32_t line) { while (1); }四、总结与建议1.TOF200C为红外 dToF 激光测距靠光飞行时间算距离精度比超声波高、体积小。2.量程20cm2m室内好用斜测、黑面、镜面、强光下容易不准。3.只做近距离室内测距 / 避障选TOF200C远距离别用。4.必须3.3V 供电不能 5V安装垂直正对障碍物。5.程序加多次取平均滤波数值更稳。