VL53L1CB驱动移植

前言

VL53L1CB是一款测距模块,根据飞行时间(Time of Flight,TOF)来测量距离。支持I2C接口。
在这里插入图片描述

硬件

芯片型号:STM32F405RGT6
硬件连接:I2C2(PB10,PB11),UART6(打印调试信息)

CUBEMX配置

这里除了时钟之外,需要配置的外设有跟VL53L1通信的I2C以及打印调试信息用的UART6。详细过程跳过。。。

驱动移植

  1. 驱动文件下载
    首先是下载官方驱动
    在这里插入图片描述下载完解压出来后就是这三个文件夹,BareDriver是相关驱动代码和API,Docs是文档,Example是提供的一个例程。
    在这里插入图片描述2. 代码移植
    这个版本的例程是用HAL库来实现的,为了快速移植,我选择参考Example中的例程来移植。
    主要移植的是这些函数
    在这里插入图片描述首先将\VL53L1CB_BareDriver_6.6.15.2625\Example\Drivers\BSP\Components\vl53l1这个文件夹复制到自己的工程中
    在这里插入图片描述并且在工程中添加对应的c文件(vl53l1文件夹下的所有c文件)以及头文件路径
    在这里插入图片描述在这里插入图片描述接着将VL53L1CB_BareDriver_6.6.15.2625\Example\Projects\STM32F401RE-Nucleo\Examples\53L1A2\SimpleRanging\Src文件夹下vl53l1_platform.c和vl53l1_platform_ipp.c文件以及VL53L1CB_BareDriver_6.6.15.2625\Example\Projects\STM32F401RE-Nucleo\Examples\53L1A2\SimpleRanging\Inc下的vl53l1开头的.h文件到自己的工程文件中。
    这里我把所有跟vl53l1相关的代码都放在一个文件夹下
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在工程中添加.c文件和头文件路径

在这里插入图片描述在这里插入图片描述3. 编译工程
在这里插入图片描述发现会报错。原因是工程所用的芯片跟我所用的芯片不一样,stm32xxx_hal.h文件不同,因此只需要把报错的地方将stm32xxx_hal.h替换成对应的头文件即可。我这里用的芯片对应头文件是stm32f4xx_hal.h。将两处报错的地方给修改后,编译就没问题了。
在这里插入图片描述4. 测试例程移植
定义全局变量和函数

/* USER CODE BEGIN 0 */
VL53L1_Dev_t                   dev;
VL53L1_DEV                     Dev = &dev;
int status;
volatile int IntCount;
uint8_t isInterrupt = 0;
void RangingLoop(void)
{
  VL53L1_MultiRangingData_t MultiRangingData;
  VL53L1_MultiRangingData_t *pMultiRangingData = &MultiRangingData;
  uint8_t NewDataReady = 0;
  int no_of_object_found = 0, j;
  printf("Ranging loop starts\n");
  status = VL53L1_WaitDeviceBooted(Dev);
  status = VL53L1_DataInit(Dev);
  status = VL53L1_StaticInit(Dev);
  /* VL53L1_SetPresetMode function is mandatory to be called even if default PresetMode is the VL53L1_PRESETMODE_RANGING */
  status = VL53L1_SetPresetMode(Dev, VL53L1_PRESETMODE_RANGING);
  //	status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_SHORT);
  //	status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 60000);
  status = VL53L1_StartMeasurement(Dev);
  if(status){
    printf("VL53L1_StartMeasurement failed: error = %d \n", status);
    while(1);
  }
  if (isInterrupt){
    do // HW interrupt mode
    {
      __WFI();
      if(IntCount !=0 ){
        IntCount=0;
        status = VL53L1_GetMultiRangingData(Dev, pMultiRangingData);
        no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
        printf("Count=%5d, ", pMultiRangingData->StreamCount);
        printf("#Objs=%1d ", no_of_object_found);
        for(j=0;j<no_of_object_found;j++){
          if(j!=0)printf("\r\n                     ");
          printf("status=%d, D=%5dmm, Signal=%2.2f Mcps, Ambient=%2.2f Mcps",
                 pMultiRangingData->RangeData[j].RangeStatus,
                 pMultiRangingData->RangeData[j].RangeMilliMeter,
                 pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
                 pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
        }
        printf ("\r\n");
        if (status==0){
          status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
        }
      }
    }
    while(1);
  }
  else{
    do{ // polling mode
      status = VL53L1_GetMeasurementDataReady(Dev, &NewDataReady);
      HAL_Delay(1);
      if((!status)&&(NewDataReady!=0)){
        status = VL53L1_GetMultiRangingData(Dev, pMultiRangingData);
        no_of_object_found=pMultiRangingData->NumberOfObjectsFound;
        printf("Count=%5d, ", pMultiRangingData->StreamCount);
        printf("#Objs=%1d ", no_of_object_found);
        for(j=0;j<no_of_object_found;j++){
          if(j!=0)printf("\r\n");
          printf("status=%d, D=%5dmm, Signal=%2.2f Mcps, Ambient=%2.2f Mcps",
                 pMultiRangingData->RangeData[j].RangeStatus,
                 pMultiRangingData->RangeData[j].RangeMilliMeter,
                 pMultiRangingData->RangeData[j].SignalRateRtnMegaCps/65536.0,
                 pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps/65536.0);
        }
        printf ("\r\n");
        if (status==0){
          status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
        }
      }
    }
    while (1);
  }
}
/* USER CODE END 0 */

main函数

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t byteData;
	uint16_t wordData;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C2_Init();
  MX_USART6_UART_Init();
  /* USER CODE BEGIN 2 */
	printf("VL53L1X Examples...\r\n");
  Dev->I2cHandle = &hi2c2;
  Dev->I2cDevAddr = 0x52;
  
  VL53L1_RdByte(Dev, 0x010F, &byteData);
  printf("VL53L1X Model_ID: %02X\n\r", byteData);
  VL53L1_RdByte(Dev, 0x0110, &byteData);
  printf("VL53L1X Module_Type: %02X\n\r", byteData);
  VL53L1_RdWord(Dev, 0x010F, &wordData);
  printf("VL53L1X: %02X\n\r", wordData);
  
  RangingLoop();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

测试结果

在这里插入图片描述
注意事项:实际测试的时候,发现vl53l1开启测量后,烧录程序后,读取的数据会有问题。像这样

在这里插入图片描述
应该是VL53L1开启测量后,需要调用停止测量的函数,才能对其进行操作。当出现这种情况时,需要对整个硬件系统重新上电,或者重新拔插vl53l1模块,也可以在初始化前调用停止测量的函数。

完整工程下载链接

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值