【X-NUCLEO-53L4A3】+驱动TOF传感器测距
[复制链接]
本帖最后由 superw 于 2024-11-18 09:01 编辑
此贴主要介绍如何使用X-CUBE-TOF1软件包基于自定义的VL53系列TOF传感器进行驱动,并进行基础测距功能,在OLED屏幕上可实时显示。正常使用VL53系列TOF传感器肯定是自己设计的板子,一个VL53L4ED传感器二十来块,一个X-NUCLEO-53L4A3扩展板将近三百,而且扩展板上也没什么其他特殊的IC,选哪个不用多说。
硬件清单
X-NUCLEO-53L4A3、NUCLEO-F401RE、0.96寸OLED屏幕(IIC接口)
测距工程创建
使用STM32CubeIDE创建NUCLEO-F401RE工程过程略过,非常简单,网上教程也一大堆。
配置VL53L4ED需要的IIC接口和GPIO,以及OLED需要的IIC接口。
根据X-NUCLEO-53L4A3原理图,板载的VL53L4ED与STM32F401RE的PB8(SCL)、PB9(SDA)连接,并且时钟线和数据线都通过上拉电阻拉高,可以使用GPIO软件模拟IIC时序驱动,也可以使用STM32F401RE片上的硬件IIC控制器驱动。VL53L4ED的XSHUT引脚与PB3连接,通过上拉电阻拉高,用做GPIO输出;GPIO1引脚与PA4连接,通过上拉电阻拉高,用做中断输入。OLED屏幕与STM32F401RE的PA8(SCL)、PB4(SDA)连接,并且时钟线和数据线都通过上拉电阻拉高,可以使用GPIO软件模拟IIC时序驱动,也可以使用STM32F401RE片上的硬件IIC控制器驱动。
下面对于VL53L4ED和OLED屏幕,都采用硬件IIC驱动,PB8、PB9对应IIC1,PA8、PB4对应IIC3。
引脚配置如上图所示,在创建工程时,STM32CubeF4软件包默认将下载接口、调试USART接口、板载按键、板载LED配置完成,剩下需要自己配置VL53L4ED和OLED屏幕用到的IO资源。
VL53L4ED使用I2C总线进行通信,最大支持1MHz,地址为0x52。开启STM32F401RE的I2C1,模式为Fast Mode,时钟频率为400KHz。
OLED使用I2C总线进行通信,最大支持1MHz,地址为0x52。开启STM32F401RE的I2C3,模式为Fast Mode,时钟频率为400KHz。
选择Middleware and Software Packs,接着选择X-CUBE-TOF1软件包,在里面选择器件为VL53L4ED,板子为custom,应用为53L4A3_SimpleRanging,之后点击Ok即可。
重新进入X-CUBE-TOF1软件包,将软件包需要的IP与STM32F401RE配置的一一对应即可,之后生成代码。
在Drivers/BSP目录下创建OLED文件夹,将OLED相关的I2C驱动复制进去,把相关I2C操作的句柄改为I2C3。
X-CUBE-TOF1软件包默认创建了app_tof.c、app_tof.h应用层代码,可以在main函数里,直接调用MX_TOF_Init、MX_TOF_Process函数完成测距。
MX_TOF_Init通过函数调用完成USART2打印串口初始化,VL53L4ED传感器初始化。
MX_TOF_Process通过获取VL53L4ED器件ID,获取属性,配置TOF后,开启TOF传感器,并间隔POLLING_PERIOD周期获取一次测距结果并打印出来。
测距结果包括目标NumberOFTargets数量,Distance距离,Status状态,Ambient环境光,Signal信号速率。需要注意,只有当Status状态值为0时,才代表TOF传感器捕捉到目标物体,当获取到状态值不为0的信息时,可以直接舍去,无意义。
static void display_result(RANGING_SENSOR_Result_t *Result)
{
uint8_t i;
uint8_t j;
char message[50];
for (i = 0; i < RANGING_SENSOR_MAX_NB_ZONES; i++)
{
OLED_NewFrame();
sprintf(message, "Targets = %lu", (unsigned long)Result->ZoneResult[i].NumberOfTargets);
OLED_PrintString(0, 0, message, &font12x12, OLED_COLOR_NORMAL);
for (j = 0; j < Result->ZoneResult[i].NumberOfTargets; j++)
{
sprintf(message, "Status = %ld", (long)Result->ZoneResult[i].Status[j]);
OLED_PrintString(0, 20, message, &font12x12, OLED_COLOR_NORMAL);
sprintf(message, "Distance = %ld mm", (long)Result->ZoneResult[i].Distance[j]);
OLED_PrintString(0, 35, message, &font12x12, OLED_COLOR_NORMAL);
}
OLED_ShowFrame();
}
}
static void MX_VL53L4ED_SimpleRanging_Process(void)
{
uint32_t Id;
CUSTOM_RANGING_SENSOR_ReadID(CUSTOM_VL53L4ED, &Id);
CUSTOM_RANGING_SENSOR_GetCapabilities(CUSTOM_VL53L4ED, &Cap);
Profile.RangingProfile = VL53L4ED_PROFILE_CONTINUOUS;
Profile.TimingBudget = TIMING_BUDGET;
Profile.Frequency = 0; /* Induces intermeasurement period, NOT USED for normal ranging */
Profile.EnableAmbient = 1; /* Enable: 1, Disable: 0 */
Profile.EnableSignal = 1; /* Enable: 1, Disable: 0 */
/* set the profile if different from default one */
CUSTOM_RANGING_SENSOR_ConfigProfile(CUSTOM_VL53L4ED, &Profile);
status = CUSTOM_RANGING_SENSOR_Start(CUSTOM_VL53L4ED, RS_MODE_BLOCKING_CONTINUOUS);
while (1)
{
/* polling mode */
status = CUSTOM_RANGING_SENSOR_GetDistance(CUSTOM_VL53L4ED, &Result);
if (status == BSP_ERROR_NONE)
{
print_result(&Result);
display_result(&Result);
}
HAL_Delay(POLLING_PERIOD);
}
}
前面已经将OLED显示驱动复制到工程里,需要重新构建一个显示测距结果的函数display_result,与print_result一块调用,就可以在串口和OLED显示屏上分别看到测距结果。
实现效果
c547f52027568bb2897e7122f745703c
尺子长度为30cm,视频中可以看到实际测距效果误差在mm之内
|