VL53L4CD测距模块C++对象封装。

张开发
2026/4/7 9:21:14 15 分钟阅读

分享文章

VL53L4CD测距模块C++对象封装。
这是一个VL53L4CD测距模块的CLASS对象封装主要代码来自官方C程序目标是封装成一个CLASS对象方便大家使用特将代码记录于此#define _VL53L4CD_H_ #ifdef _VL53L4CD_H_ class VL53L4CD{ private: /*使用步骤 * 首先配置好I2C以及XSHUT引脚。 * VL53L4CD vl53l1; * begin(hi2c4,GPIOG,GPIO_PIN_10,0x52); * vl53l1.SetRangeTiming(10, 1000);//低功耗测量每秒一次。或者vl53l1.SetRangeTiming(30, 0);//连续测量模式曝光时间30毫秒。 * vl53l1.StartRanging(); * while(1){ * * if(vl53l1.CheckForDataReady(TemNum8) HAL_OK){//检查测量数据是否已经准备好。 * if(TemNum80){ * if(vl53l1.GetDistance(TemNum16) HAL_OK){//获取测量数据。 * vl53l1.ClearInterrupt();//清中断继续下一轮测量。 * 这里添加业务逻辑 * } * } * } * * } * */ //公开的用户操作寄存器。 const uint16_t VL53L4CD_SOFT_RESET 0x0000; const uint16_t VL53L4CD_I2C_SLAVE__DEVICE_ADDRESS 0x0001; const uint16_t VL53L4CD_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008; const uint16_t VL53L4CD_XTALK_PLANE_OFFSET_KCPS 0x0016; const uint16_t VL53L4CD_XTALK_X_PLANE_GRADIENT_KCPS 0x0018; const uint16_t VL53L4CD_XTALK_Y_PLANE_GRADIENT_KCPS 0x001A; const uint16_t VL53L4CD_RANGE_OFFSET_MM 0x001E; const uint16_t VL53L4CD_INNER_OFFSET_MM 0x0020; const uint16_t VL53L4CD_OUTER_OFFSET_MM 0x0022; const uint16_t VL53L4CD_GPIO_HV_MUX__CTRL 0x0030; const uint16_t VL53L4CD_GPIO__TIO_HV_STATUS 0x0031; const uint16_t VL53L4CD_SYSTEM__INTERRUPT 0x0046; const uint16_t VL53L4CD_RANGE_CONFIG_A 0x005E; const uint16_t VL53L4CD_RANGE_CONFIG_B 0x0061; const uint16_t VL53L4CD_RANGE_CONFIG__SIGMA_THRESH 0x0064; const uint16_t VL53L4CD_MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066; const uint16_t VL53L4CD_INTERMEASUREMENT_MS 0x006C; const uint16_t VL53L4CD_THRESH_HIGH 0x0072; const uint16_t VL53L4CD_THRESH_LOW 0x0074; const uint16_t VL53L4CD_SYSTEM__INTERRUPT_CLEAR 0x0086; const uint16_t VL53L4CD_SYSTEM_START 0x0087; const uint16_t VL53L4CD_RESULT__RANGE_STATUS 0x0089; const uint16_t VL53L4CD_RESULT__SPAD_NB 0x008C; const uint16_t VL53L4CD_RESULT__SIGNAL_RATE 0x008E; const uint16_t VL53L4CD_RESULT__AMBIENT_RATE 0x0090; const uint16_t VL53L4CD_RESULT__SIGMA 0x0092; const uint16_t VL53L4CD_RESULT__DISTANCE 0x0096; //系统状态寄存器。 const uint16_t VL53L4CD_RESULT__OSC_CALIBRATE_VAL 0x00DE; const uint16_t VL53L4CD_FIRMWARE__SYSTEM_STATUS 0x00E5; const uint16_t VL53L4CD_IDENTIFICATION__MODEL_ID 0x010F; //自定义隐藏寄存器。 const uint16_t VL53L4CD_INTERRUPT_CONTROLLER_RESET 0x000B; //中断控制器复位寄存器,写入0x00可复位整个中断控制器清除残留中断状态 const uint16_t VL53L4CD_RESULT__PEAK_SIGNAL_COUNT_RATE_THRESH 0x0024;//峰值信号率阈值寄存器,单位KCPS千计数/秒,过滤弱信号干扰. const uint16_t VL53L4CD_RESULT__TEMPERATURE 0x010D;// 温度寄存器8位有符号单位℃ //#define VL53L4CD_I2C_FAST_MODE_PLUS //定义该宏则启用高速模式1MHZ不定义则为常规模式400MHZ。 const uint8_t VL53L4CD_DEFAULT_CONFIGURATION[91] { #ifdef VL53L4CD_I2C_FAST_MODE_PLUS 0x12, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), else dont touch */ #else 0x00, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), else dont touch */ #endif 0x00,0x00,0x11,0x02,0x00,0x02,0x08,0x00,0x08,0x10, 0x01,0x01,0x00,0x00,0x00,0x00,0xff,0x00,0x0F,0x00, 0x00,0x00,0x00,0x00,0x20,0x0b,0x00,0x00,0x02,0x14, 0x21,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0xc8,0x00, 0x00,0x38,0xff,0x01,0x00,0x08,0x00,0x00,0x01,0xcc, 0x07,0x01,0xf1,0x05,0x00,0xa0,0x00,0x80,0x08,0x38, 0x00,0x00,0x00,0x00,0x0f,0x89,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x07,0x05,0x06,0x06,0x00,0x00, 0x02,0xc7,0xff,0x9B,0x00,0x00,0x00,0x01,0x00,0x00 }; I2C_HandleTypeDef* i2c_handle;//VL53L4CD硬件IIC控制句柄。 GPIO_TypeDef* XSHUT_GPIOx;//GPIO分组。//上电/下电控制引脚。 uint16_t XSHUT_GPIO_Pin;//GPIO引脚编号。 uint8_t driverAddr0x52;//VL53L4CD默认地址。 protected: HAL_StatusTypeDef init(void){ if(i2c_handlenullptr || i2c_handle-Instancenullptr || XSHUT_GPIOx nullptr){return HAL_ERROR;} GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pin XSHUT_GPIO_Pin; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP;//输出模式。 GPIO_InitStruct.Pull GPIO_PULLUP;//上拉。 GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate 0; HAL_GPIO_Init(XSHUT_GPIOx, GPIO_InitStruct); setXSHUT(true); return SensorInit(); } HAL_StatusTypeDef SensorInit(void) { //传感器初始化。 HAL_StatusTypeDef status HAL_OK; uint8_t Addr, tmp; uint8_t continue_loop 1; uint16_t i 0; HAL_Delay(3); /*检查系统启动是否完成超过1秒未完成则启动失败*/ do{ tmp0; ReadReg8(VL53L4CD_FIRMWARE__SYSTEM_STATUS, tmp);//如果上电没有完成这里会返回错误码但是不能因为错误而退出而是应该一直读直到读出正确否则在超时后再处理。 if(tmp 0x3){continue_loop 0;}else if(i 1000){i;}else{return HAL_ERROR;} HAL_Delay(1); }while(continue_loop 1); /*写入默认值*/ for (Addr 0x2D; Addr 0x87; Addr) { status WriteReg8(Addr,VL53L4CD_DEFAULT_CONFIGURATION[Addr - 0x2D]);if(status ! HAL_OK)return status; } /*启动测距并等待测距完成*/ status WriteReg8(VL53L4CD_SYSTEM_START,0x40);if(status ! HAL_OK)return status; i 0; continue_loop 1; do{ tmp0; CheckForDataReady(tmp); if(tmp 1) { continue_loop 0; }else if(i 1000){ i; }else{ return HAL_ERROR; } HAL_Delay(1); }while(continue_loop 1); status ClearInterrupt();if(status ! HAL_OK)return status; status StopRanging();if(status ! HAL_OK)return status; status WriteReg8(VL53L4CD_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,0x09);if(status ! HAL_OK)return status;//设置每次上电/启动测距前必须完成的核心校准VHV次数 status WriteReg8(VL53L4CD_INTERRUPT_CONTROLLER_RESET, 0);if(status ! HAL_OK)return status;//中断控制器复位寄存器(中断控制器复位。非必需清除上电残留的中断状态避免误判。)。 status WriteReg16(VL53L4CD_RESULT__PEAK_SIGNAL_COUNT_RATE_THRESH, 0x500);if(status ! HAL_OK)return status;//峰值信号率阈值寄存器,单位KCPS千计数/秒,过滤弱信号干扰. return SetRangeTiming(50, 0);//将传感器的时序预算Timing Budget即单次测距花费的时间设为 50ms、测量间隔Intermeasurement即连续测量模式每次测距间隔时间设为 0最终让传感器工作在「连续测距模式」下。 } HAL_StatusTypeDef WriteReg8(uint16_t reg_addr, uint8_t data) { uint8_t tx_buf[3] { (uint8_t)( (reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF), (uint8_t)(data 0xFF) }; return HAL_I2C_Master_Transmit(i2c_handle, driverAddr, tx_buf, 3, 100); } HAL_StatusTypeDef WriteReg16(uint16_t reg_addr, uint16_t data) { uint8_t tx_buf[4] { (uint8_t)( (reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF), (uint8_t)((data 8) 0xFF), (uint8_t)(data 0xFF) }; return HAL_I2C_Master_Transmit(i2c_handle, driverAddr, tx_buf, 4, 100); } HAL_StatusTypeDef WriteReg32(uint16_t reg_addr, uint32_t data) { uint8_t tx_buf[6] { (uint8_t)((reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF), (uint8_t)((data 24) 0xFF), (uint8_t)((data 16) 0xFF), (uint8_t)((data 8) 0xFF), (uint8_t)((data 0) 0xFF), }; return HAL_I2C_Master_Transmit(i2c_handle, driverAddr, tx_buf, 6, 100); } HAL_StatusTypeDef ReadReg8(uint16_t reg_addr, uint8_t *p_data) { if(p_data NULL) return HAL_ERROR; uint8_t reg_addr_buf[2] {(uint8_t)((reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF)}; if(HAL_I2C_Master_Transmit(i2c_handle, driverAddr, reg_addr_buf, 2, 100) ! HAL_OK)return HAL_ERROR; return HAL_I2C_Master_Receive(i2c_handle, driverAddr | 0x01, p_data, 1, 100); } HAL_StatusTypeDef ReadReg16(uint16_t reg_addr, uint16_t *p_data) { if(p_data NULL) return HAL_ERROR; uint8_t reg_addr_buf[2] {(uint8_t)((reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF)}; uint8_t rx_buf[2] {0}; if(HAL_I2C_Master_Transmit(i2c_handle, driverAddr, reg_addr_buf, 2, 100) ! HAL_OK) return HAL_ERROR; if(HAL_I2C_Master_Receive(i2c_handle, driverAddr | 0x01, rx_buf, 2, 100) ! HAL_OK) return HAL_ERROR; *p_data (rx_buf[0] 8) | rx_buf[1]; return HAL_OK; } HAL_StatusTypeDef ReadReg32(uint16_t reg_addr, uint32_t *p_data) { if(p_data NULL) return HAL_ERROR; uint8_t reg_addr_buf[2] {(uint8_t)((reg_addr 8) 0xFF), (uint8_t)(reg_addr 0xFF)}; uint8_t rx_buf[4] {0}; if(HAL_I2C_Master_Transmit(i2c_handle, driverAddr, reg_addr_buf, 2, 100) ! HAL_OK) return HAL_ERROR; if(HAL_I2C_Master_Receive(i2c_handle, driverAddr | 0x01, rx_buf, 4, 100) ! HAL_OK) return HAL_ERROR; *p_data (rx_buf[0] 24) | (rx_buf[1] 16) | (rx_buf[2] 8) | rx_buf[3]; // 大端序拼接 return HAL_OK; } public: VL53L4CD(I2C_HandleTypeDef* in_i2c_handlenullptr,GPIO_TypeDef* in_gpioxGPIOG,uint16_t in_gpio_pinGPIO_PIN_10,uint8_t in_Addr0x52):i2c_handle(in_i2c_handle),XSHUT_GPIOx(in_gpiox),XSHUT_GPIO_Pin(in_gpio_pin),driverAddr(in_Addr){init();} ~VL53L4CD(){;} HAL_StatusTypeDef begin(I2C_HandleTypeDef* in_i2c_handlenullptr,GPIO_TypeDef* in_gpioxGPIOG,uint16_t in_gpio_pinGPIO_PIN_10,uint8_t in_Addr0x52){ i2c_handlein_i2c_handle;driverAddrin_Addr;XSHUT_GPIOxin_gpiox;XSHUT_GPIO_Pinin_gpio_pin; return init(); } HAL_StatusTypeDef setXSHUT(bool in_Mode){ if(XSHUT_GPIOx nullptr) {return HAL_ERROR;} if(clk_enable_gpio(XSHUT_GPIOx) ! HAL_OK)return HAL_ERROR;//开GPIO时钟。 //XSHUT引脚配置并上电。 if(in_Mode){ HAL_GPIO_WritePin(XSHUT_GPIOx, XSHUT_GPIO_Pin, GPIO_PIN_SET); }else{ HAL_GPIO_WritePin(XSHUT_GPIOx, XSHUT_GPIO_Pin, GPIO_PIN_RESET); } return HAL_OK; } HAL_StatusTypeDef setTiming(uint32_t i2c_pclk, uint32_t i2c_speed) { //设置I2C通信速率。 //i2c_pclk:总线时钟频率i2c_speedI2C通信速率。 if(i2c_handlenullptr || i2c_handle-Instancenullptr){return HAL_ERROR;} uint32_t presc 0; // 自动分频系数 uint32_t i2c_clk; // 分频后的 I2C 基础时钟 uint32_t scll, sclh; // 高低电平周期 const uint32_t SDADEL 2;// 官方推荐固定值 const uint32_t STADEL 0;// 官方推荐固定值 // // 第一步自动计算 PRESC核心 // 规则必须让算出来的 SCLL / SCLH ≤ 255 // for (presc 0; presc 16; presc) { i2c_clk i2c_pclk / (presc 1); if (i2c_speed 100000) { // 100kHz 要求低电平 5.5us高电平 4.5us scll (i2c_clk * 55 / 10000000) - 1; sclh (i2c_clk * 45 / 10000000) - 1; } else { // 400kHz 要求低电平 1.5us高电平 0.6us scll (i2c_clk * 15 / 10000000) - 1; sclh (i2c_clk * 6 / 10000000) - 1; } // 关键判断只要不超过 8 位最大值 255就用这个分频 if (scll 255 sclh 255 scll 0 sclh 0) { break; } } // // 第二步组装寄存器 // uint32_t timing 0; timing | (presc 0x0F) 28; // 分频 timing | (SDADEL 0x0F) 20; // 数据延时 timing | (STADEL 0x0F) 16; // 起始延时 timing | (sclh 0xFF) 8; // 高电平 timing | (scll 0xFF); // 低电平 i2c_handle-Init.Timing timing; return HAL_I2C_Init(i2c_handle); } HAL_StatusTypeDef SetAddress(uint8_t new_address) { //修改传感器I2C地址只在不断电情况下有效下次重新上电恢复默认地址。7位地址0x29(参数传入的是八位地址0x52)。 if(WriteReg8(VL53L4CD_I2C_SLAVE__DEVICE_ADDRESS,new_address 1) ! HAL_OK)return HAL_ERROR; driverAddrnew_address; return SensorInit();//实践证明修改地址后必须重新初始化。 } HAL_StatusTypeDef GetSensorId(uint16_t *p_id) { //读传感器ID(0xEBAA). return ReadReg16(VL53L4CD_IDENTIFICATION__MODEL_ID, p_id); } HAL_StatusTypeDef isDeviceConnected(void) { //检查设备是否在线。 uint16_t measurement0; if(ReadReg16(VL53L4CD_IDENTIFICATION__MODEL_ID,measurement) ! HAL_OK) return HAL_ERROR; if(measurement ! 0xEBAA) return HAL_ERROR; return HAL_OK; } HAL_StatusTypeDef StartRanging(void) { //启动测距。0x0087寄存器VL53L4CD_SYSTEM_START值0X00--待机0X10--单次测距0X21--连续测距0X40--低功耗自动测距0X80--停止测距。 HAL_StatusTypeDef status HAL_OK; uint32_t tmp; status ReadReg32(VL53L4CD_INTERMEASUREMENT_MS, tmp);if(status ! HAL_OK)return status; if(tmp (uint32_t)0) { status WriteReg8(VL53L4CD_SYSTEM_START, 0x21);//连续测距模式。 }else{ status WriteReg8(VL53L4CD_SYSTEM_START, 0x40);//自动定时低功耗模式 } return status; } HAL_StatusTypeDef StopRanging(void) { //停止测距。 HAL_StatusTypeDef status HAL_OK; status WriteReg8(VL53L4CD_SYSTEM_START,0x80); return status; } HAL_StatusTypeDef SetOffset(int16_t OffsetValueInMm) { //设置距离偏移校准值 uint16_t temp; temp (uint16_t)((uint16_t)OffsetValueInMm*(uint16_t)4); if(WriteReg16(VL53L4CD_RANGE_OFFSET_MM, temp) ! HAL_OK)return HAL_ERROR; if(WriteReg16(VL53L4CD_INNER_OFFSET_MM, (uint8_t)0x0) ! HAL_OK)return HAL_ERROR; if(WriteReg16(VL53L4CD_OUTER_OFFSET_MM, (uint8_t)0x0) ! HAL_OK)return HAL_ERROR; return HAL_OK; } HAL_StatusTypeDef GetOffset(int16_t *p_offset) { //读取距离偏移校准值 uint16_t temp; if(ReadReg16(VL53L4CD_RANGE_OFFSET_MM, temp) ! HAL_OK)return HAL_ERROR; temp temp3; temp temp5; *p_offset (int16_t)(temp); if(*p_offset 1024){*p_offset *p_offset - 2048;} return HAL_OK; } HAL_StatusTypeDef SetXtalk(uint16_t XtalkValueKcps) { //设置串扰补偿值 if(WriteReg16(VL53L4CD_XTALK_X_PLANE_GRADIENT_KCPS, 0x0000) ! HAL_OK)return HAL_ERROR; if(WriteReg16(VL53L4CD_XTALK_Y_PLANE_GRADIENT_KCPS, 0x0000) ! HAL_OK)return HAL_ERROR; return WriteReg16(VL53L4CD_XTALK_PLANE_OFFSET_KCPS,XtalkValueKcps9); } HAL_StatusTypeDef GetXtalk(uint16_t *p_xtalk_kcps) { //读取当前串扰值 float_t tmp_xtalk; if(ReadReg16(VL53L4CD_XTALK_PLANE_OFFSET_KCPS, p_xtalk_kcps) ! HAL_OK)return HAL_ERROR; tmp_xtalk (float_t)*p_xtalk_kcps / (float_t)512.0; *p_xtalk_kcps (uint16_t)(round(tmp_xtalk)); return HAL_OK; } HAL_StatusTypeDef SetDetectionThresholds(uint16_t distance_low_mm,uint16_t distance_high_mm,uint8_t window) { //设置距离阈值distance_low_mm--最小距离distance_high_mm-最大距离 //window-检测模式(中断触发方式)0 低于低阈值1 高于高阈值2 低于低阈值 OR 高于高阈值3 在低与高之间4 每次测量都触发 不管距离是多少。 if(WriteReg8(VL53L4CD_SYSTEM__INTERRUPT, window) ! HAL_OK)return HAL_ERROR; if(WriteReg16(VL53L4CD_THRESH_HIGH, distance_high_mm) ! HAL_OK)return HAL_ERROR; return WriteReg16(VL53L4CD_THRESH_LOW, distance_low_mm); } HAL_StatusTypeDef GetDetectionThresholds(uint16_t *p_distance_low_mm,uint16_t *p_distance_high_mm,uint8_t *p_window) { //读出距离阈值及检测模式。 if(ReadReg16(VL53L4CD_THRESH_HIGH,p_distance_high_mm) ! HAL_OK)return HAL_ERROR; if(ReadReg16(VL53L4CD_THRESH_LOW, p_distance_low_mm) ! HAL_OK)return HAL_ERROR; if(ReadReg8(VL53L4CD_SYSTEM__INTERRUPT, p_window) ! HAL_OK)return HAL_ERROR; *p_window (*p_window (uint8_t)0x7); return HAL_OK; } HAL_StatusTypeDef SetSignalThreshold(uint16_t signal_kcps) { //设置最小有效反射信号强度过滤弱信号、噪声、无效测量。 return WriteReg16(VL53L4CD_MIN_COUNT_RATE_RTN_LIMIT_MCPS,signal_kcps3); } HAL_StatusTypeDef GetSignalThreshold(uint16_t *p_signal_kcps) { //读出最小有效反射信号强度。 uint16_t tmp 0; if(ReadReg16(VL53L4CD_MIN_COUNT_RATE_RTN_LIMIT_MCPS, tmp) ! HAL_OK)return HAL_ERROR; *p_signal_kcps tmp 3; return HAL_OK; } HAL_StatusTypeDef SetRangeTiming(uint32_t timing_budget_ms,uint32_t inter_measurement_ms) { //单次测距时间曝光时间和连续模式测距间隔时间设置。 uint16_t clock_pll, osc_frequency, ms_byte; uint32_t macro_period_us 0, timing_budget_us 0, ls_byte, tmp; float_t inter_measurement_factor 1.055; if(ReadReg16(0x0006,osc_frequency) ! HAL_OK)return HAL_ERROR; if(osc_frequency ! 0) { timing_budget_us timing_budget_ms*1000; macro_period_us (uint32_t)((uint32_t)2304 * ((uint32_t)0x40000000 / (uint32_t)osc_frequency)) 6; }else{ return HAL_ERROR; } if ((timing_budget_ms 10) || (timing_budget_ms 200)) { return HAL_ERROR; }else if(inter_measurement_ms 0){ if(WriteReg32(VL53L4CD_INTERMEASUREMENT_MS, 0) ! HAL_OK)return HAL_ERROR; timing_budget_us - 2500; }else if(inter_measurement_ms timing_budget_ms){ if(ReadReg16(VL53L4CD_RESULT__OSC_CALIBRATE_VAL, clock_pll) ! HAL_OK)return HAL_ERROR; clock_pll clock_pll (uint16_t)0x3FF; inter_measurement_factor inter_measurement_factor * (float_t)inter_measurement_ms * (float_t)clock_pll; if(WriteReg32(VL53L4CD_INTERMEASUREMENT_MS,(uint32_t)inter_measurement_factor) ! HAL_OK)return HAL_ERROR; timing_budget_us - (uint32_t)4300; timing_budget_us / (uint32_t)2; }else{ return HAL_ERROR; } ms_byte 0; timing_budget_us timing_budget_us 12; tmp macro_period_us*(uint32_t)16; ls_byte ((timing_budget_us ((tmp 6)1)) /(tmp 6)) - (uint32_t)1; while ((ls_byte 0xFFFFFF00U) 0U) { ls_byte ls_byte 1; ms_byte; } ms_byte (uint16_t)(ms_byte 8) (uint16_t) (ls_byte (uint32_t)0xFF); if(WriteReg16(VL53L4CD_RANGE_CONFIG_A,ms_byte) ! HAL_OK)return HAL_ERROR; ms_byte 0; tmp macro_period_us*(uint32_t)12; ls_byte ((timing_budget_us ((tmp 6)1)) /(tmp 6)) - (uint32_t)1; while ((ls_byte 0xFFFFFF00U) 0U) { ls_byte ls_byte 1; ms_byte; } ms_byte (uint16_t)(ms_byte 8) (uint16_t) (ls_byte (uint32_t)0xFF); return WriteReg16(VL53L4CD_RANGE_CONFIG_B,ms_byte); } HAL_StatusTypeDef GetRangeTiming(uint32_t *p_timing_budget_ms,uint32_t *p_inter_measurement_ms) { uint16_t osc_frequency 1, range_config_macrop_high, clock_pll 1; uint32_t tmp, ls_byte, ms_byte, macro_period_us; float_t clock_pll_factor 1.065; if(ReadReg32(VL53L4CD_INTERMEASUREMENT_MS, tmp) ! HAL_OK)return HAL_ERROR; if(ReadReg16(VL53L4CD_RESULT__OSC_CALIBRATE_VAL, clock_pll) ! HAL_OK)return HAL_ERROR; clock_pll clock_pll 0x03FF; clock_pll_factor clock_pll_factor * clock_pll; clock_pll (uint16_t)clock_pll_factor; *p_inter_measurement_ms tmp/clock_pll; if(ReadReg16(0x0006, osc_frequency) ! HAL_OK)return HAL_ERROR; if(ReadReg16(VL53L4CD_RANGE_CONFIG_A,range_config_macrop_high) ! HAL_OK)return HAL_ERROR; macro_period_us (uint32_t)((uint32_t)2304 * ((uint32_t)0x40000000 / (uint32_t)osc_frequency)) 6; ls_byte (range_config_macrop_high (uint32_t)0x00FF) 4; ms_byte (range_config_macrop_high (uint32_t)0xFF00) 8; ms_byte (uint32_t)0x04 - (ms_byte - (uint32_t)1) - (uint32_t)1; macro_period_us macro_period_us * (uint32_t)16; *p_timing_budget_ms (((ls_byte (uint32_t)1)*(macro_period_us 6)) - ((macro_period_us 6)1)) 12; if(ms_byte (uint8_t)12) { *p_timing_budget_ms (uint32_t)(*p_timing_budget_ms (uint8_t)ms_byte); } /* Mode continuous */ if(tmp (uint32_t)0) { *p_timing_budget_ms (uint32_t)2500; } /* Mode autonomous */ else { *p_timing_budget_ms * (uint32_t)2; *p_timing_budget_ms (uint32_t)4300; } *p_timing_budget_ms *p_timing_budget_ms/(uint32_t)1000; return HAL_OK; } HAL_StatusTypeDef StartTemperatureUpdate() { //执行温度校准VHV Calibration uint8_t tmp 0, continue_loop 1; uint16_t i 0; if(WriteReg8(VL53L4CD_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,0x81) ! HAL_OK)return HAL_ERROR; if(WriteReg8(VL53L4CD_INTERRUPT_CONTROLLER_RESET, 0x92) ! HAL_OK)return HAL_ERROR; if(StartRanging() ! HAL_OK)return HAL_ERROR; do{ tmp0; CheckForDataReady(tmp); if(tmp 1) { continue_loop 0; }else if(i 1000){ i; }else{ return HAL_ERROR; } HAL_Delay(1); }while(continue_loop 1); if(ClearInterrupt() ! HAL_OK)return HAL_ERROR; if(StopRanging() ! HAL_OK)return HAL_ERROR; if(WriteReg8(VL53L4CD_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09) ! HAL_OK)return HAL_ERROR; return WriteReg8(VL53L4CD_INTERRUPT_CONTROLLER_RESET, 0); } HAL_StatusTypeDef CheckForDataReady(uint8_t *p_is_data_ready) { //检查测距数据是否准备就绪。 uint8_t temp; uint8_t int_pol; if(ReadReg8(VL53L4CD_GPIO_HV_MUX__CTRL, temp) ! HAL_OK)return HAL_ERROR;//读中断极性位 temp temp 0x10;temp temp 4; if (temp 1) { int_pol 0;// 极性为1 → 中断低电平有效 }else{ int_pol 1;// 极性为0 → 中断高电平有效 } if(ReadReg8(VL53L4CD_GPIO__TIO_HV_STATUS, temp) ! HAL_OK)return HAL_ERROR;//读中断状态 if ((temp 0x01) int_pol) { *p_is_data_ready 1;// 数据就绪 }else{ *p_is_data_ready 0;// 数据未就绪 } return HAL_OK; } HAL_StatusTypeDef GetDistance(uint16_t* Distance) { return ReadReg16(VL53L4CD_RESULT__DISTANCE,Distance); } HAL_StatusTypeDef ClearInterrupt(void) { //清中断标志。 return WriteReg8(VL53L4CD_SYSTEM__INTERRUPT_CLEAR, 0x01); } HAL_StatusTypeDef GetTemperature(int8_t *p_temperature) { //读传感器内部温度。 uint8_t temp; if(ReadReg8(VL53L4CD_RESULT__TEMPERATURE, temp) ! HAL_OK)return HAL_ERROR; *p_temperature (int8_t)temp; return HAL_OK; } }; #endif这些代码还是借助AI找出来的进行了一些修改做成一个CLASS前面注释已经将使用方法写出来了就不再赘述了。

更多文章