【硬件】
1、STM32H7S78-DK
2、X-NUCLEO-53L4A3 TOF评估板
【软件环境】
1、STM32CubeMX6.12
2、X-CUBE-TOF
3、X-CUBE_TOUCHGFX
4、TouchGFX-Designer
5、MDK5.38
【实现步步骤】
1、使用TouchGFX-Designer生成基于STM32H7S78L-DK的TouchGFX工程,设计界面如下:
2、使用STM32CubeMX打开工程,配置X-CBUE-TOF如下:
3、生成MDK工程,由于TouchGFX已经打开了I2C1,并且53L4A3也是使用I2C1所以无需重新配置。
4、打开MDK工程,可以看到STM32CubeMX已经给生成了53L4A3的工程文件:
【用户代码实现】
1、我们添加app_tof.h/c,来实现对53L4A3的初始化以及读取任务。
app_tof.c内存如下:
/**
******************************************************************************
* @File : app_tof.c
* @author : IMG SW Application Team
* @brief : This file provides code for the configuration
* of the STMicroelectronics.X-CUBE-TOF1.3.4.2 instances.
******************************************************************************
*
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "app_tof.h"
#include "main.h"
#include <stdio.h>
#include "cmsis_os2.h"
#include "53l4a3_ranging_sensor.h"
#define TIMING_BUDGET (100U) /* 10 ms < TimingBudget < 200 ms */
#define POLLING_PERIOD (250U) /* refresh rate for polling mode (ms, shall be consistent with TimingBudget value) */
/* Private variables ---------------------------------------------------------*/
static RANGING_SENSOR_Capabilities_t Cap;
static RANGING_SENSOR_ProfileConfig_t Profile;
static int32_t status = 0;
volatile uint8_t ToF_EventDetected = 0;
/* Private function prototypes -----------------------------------------------*/
static void MX_53L4A3_SimpleRanging_Init(void);
static void MX_53L4A3_SimpleRanging_Process(void);
static void print_result(RANGING_SENSOR_Result_t *Result);
static int32_t decimal_part(float_t x);
void MX_TOF_Init(void)
{
/* USER CODE BEGIN SV */
/* USER CODE END SV */
/* USER CODE BEGIN TOF_Init_PreTreatment */
/* USER CODE END TOF_Init_PreTreatment */
/* Initialize the peripherals and the TOF components */
MX_53L4A3_SimpleRanging_Init();
/* USER CODE BEGIN TOF_Init_PostTreatment */
/* USER CODE END TOF_Init_PostTreatment */
}
static void MX_53L4A3_SimpleRanging_Init(void)
{
/* reset XSHUT (XSDN) pin */
HAL_GPIO_WritePin(VL53L4A3_XSHUT_C_PORT, VL53L4A3_XSHUT_C_PIN, GPIO_PIN_RESET);
HAL_Delay(2);
HAL_GPIO_WritePin(VL53L4A3_XSHUT_C_PORT, VL53L4A3_XSHUT_C_PIN, GPIO_PIN_SET);
HAL_Delay(2);
printf("53L4A3 Simple Ranging demo application\n");
status = VL53L4A3_RANGING_SENSOR_Init(VL53L4A3_DEV_CENTER);
if (status != BSP_ERROR_NONE)
{
printf("VL53L4A3_RANGING_SENSOR_Init failed\n");
while (1);
}
}
/*
* LM background task
*/
void MX_TOF_Process(void)
{
/* USER CODE BEGIN TOF_Process_PreTreatment */
/* USER CODE END TOF_Process_PreTreatment */
MX_53L4A3_SimpleRanging_Process();
/* USER CODE BEGIN TOF_Process_PostTreatment */
/* USER CODE END TOF_Process_PostTreatment */
}
static void MX_53L4A3_SimpleRanging_Process(void)
{
uint8_t i;
uint32_t cal_distance_mm = 0; /* target distance used for offset calibration */
uint32_t Id;
RANGING_SENSOR_Result_t Result;
VL53L4A3_RANGING_SENSOR_ReadID(VL53L4A3_DEV_CENTER, &Id);
VL53L4A3_RANGING_SENSOR_GetCapabilities(VL53L4A3_DEV_CENTER, &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 */
VL53L4A3_RANGING_SENSOR_ConfigProfile(VL53L4A3_DEV_CENTER, &Profile);
printf("--- BEGIN OFFSET CALIBRATION ---\n");
/* make sure that a target is placed at cal_distance_mm (100 mm is the default value in this example)
* the application will perform some measure in order to have a log of some pre-calibration values
*/
status = VL53L4A3_RANGING_SENSOR_Start(VL53L4A3_DEV_CENTER, RS_MODE_BLOCKING_CONTINUOUS);
printf("--- Start testing ---\n");
while (1)
{
/* interrupt mode */
status = VL53L4A3_RANGING_SENSOR_GetDistance(VL53L4A3_DEV_CENTER, &Result);
if (status == BSP_ERROR_NONE)
{
print_result(&Result);
}
osDelay(100);
}
}
static void print_result(RANGING_SENSOR_Result_t *Result)
{
uint8_t i;
uint8_t j;
for (i = 0; i < RANGING_SENSOR_MAX_NB_ZONES; i++)
{
printf("\nTargets = %lu", (unsigned long)Result->ZoneResult[i].NumberOfTargets);
for (j = 0; j < Result->ZoneResult[i].NumberOfTargets; j++)
{
printf("\n |---> ");
printf("Status = %ld, Distance = %5ld mm ",
(long)Result->ZoneResult[i].Status[j],
(long)Result->ZoneResult[i].Distance[j]);
if (Profile.EnableAmbient)
printf(", Ambient = %ld.%02ld kcps/spad",
(long)Result->ZoneResult[i].Ambient[j],
(long)decimal_part(Result->ZoneResult[i].Ambient[j]));
if (Profile.EnableSignal)
printf(", Signal = %ld.%02ld kcps/spad",
(long)Result->ZoneResult[i].Signal[j],
(long)decimal_part(Result->ZoneResult[i].Signal[j]));
}
}
printf("\n");
}
static int32_t decimal_part(float_t x)
{
int32_t int_part = (int32_t) x;
return (int32_t)((x - int_part) * 100);
}
#ifdef __cplusplus
}
#endif
同时添加app_tof.h声明两个函数,用个Inint与任务
#ifndef __APP_TOF_H
#define __APP_TOF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
void MX_TOF_Init(void);
void MX_TOF_Process(void);
#ifdef __cplusplus
}
#endif
#endif /* __APP_TOF_H */
3、在freertos的任务中执行初始化,并运行检测任务。
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
MX_TOF_Init();
MX_TOF_Process();
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
使用串口助手,可以看到可以打印出测距信息:
4、为了在tochGFX中显示,我们在app_tof.c中添加一个函数,用于与TouchGFX的数据交换。
int get_distance(long * value)
{
RANGING_SENSOR_Result_t Result;
status = VL53L4A3_RANGING_SENSOR_GetDistance(VL53L4A3_DEV_CENTER, &Result);
if (status == BSP_ERROR_NONE)
{
*value = (long)Result.ZoneResult[0].Distance[0];
return 0;
}
return -1;
}
5、在ScreenView.hpp中添加handleTickEvent函数。
并在Screen1view.cpp中实现:
void Screen1View::handleTickEvent()
{
static int tick;
tick ++;
long value;
int ret;
if( 0 == (tick%20))
{
ret = get_distance(&value);
if(0 == ret)
{
Unicode::snprintf(textArea3Buffer,TEXTAREA3_SIZE,"%d",value);
textArea3.invalidate();
}
}
}
烧录后,可以成功的实现测距:
使用TouchGFX+X-CBUE-Tof可以快速的实现一个可视化的测距工具。
本帖最后由 lugl4313820 于 2024-11-2 15:46 编辑
引用: 秦天qintian0303 发表于 2024-11-2 23:10 用这个开发板有点大材小用了
开发板是非常强大的,不过我的能力有限呀,只能搞些小东西。
引用: lugl4313820 发表于 2024-11-2 23:23 开发板是非常强大的,不过我的能力有限呀,只能搞些小东西。
非常棒了,能够实现才是真实跨出的一步