Hi3061M——VL53L0X激光测距(IIC)(同样适用于其他MCU)2

前言

昨晚太晚了,草草结束了上一篇,今天更新下半部分。
昨天已经讲了VL53L0X的使用流程,无非就是进行6步的效准初始化,然后配置下模式和时间,开始采样,获取数据这四个部分,都是通过调用API来实现,那么这些API哪来呢,源码呢?
这就是今天补充的内容了。

资源下载

首先要说明的是,ST提供源码包和相关资料的下载,有一丢丢麻烦,但是也还好。ST官方链接
里面包含源码和一些其他的资料。
另外你还需要一个API手册,API使用手册
在这里插入图片描述
第一个ST官方链接打开会出现上面界面,点击get software即可跳转到下载源码的位置,可以登录下载也可以通过邮箱,发一封邮件给你提供的邮箱,然后在邮箱中点开下载链接,注意这里邮箱打开的浏览器要和你原来打开官方页面的浏览器一样,不然无法下载。
另外还要下载这个API使用手册,可以直接点API使用手册链接进行下载保存。这个链接是2022.10.25的2.0目前最新版本,后面如果有更新建议下载最新的。
此外觉得麻烦的也可以直接下载我提供的源码包。源码
里面包含2024-10-18 10:37:21下载的最新官方源码和API使用文档,以及我的移植相关代码my_vl53l0x和Hi3061M的一个使用案例。其中my_vl53l0x实现了代码的移植,基本上你只需要将这个文件添加到你的工程目录,然后修改一下vl53l0x_iic.h中的IO口配置和初始化即可,拿stm32移植举例,你需要将这个文件下的源码导入工程,当然还要配置.h,然后你需要将IIC通讯和x_shutIO口配置好初始化,和电平变化操作进行转换为stm32上的形式即可。

移植

移植主要就是放入源码, 该API适配的过程,要删删减减一些东西,不要的东西可以丢掉什么的,具体过程其实我自己也没记,反正就是删删改改,参考了正点原子的代码。
此外想要自己移植可以网上找资料看文档, 也可以看这篇文章https://blog.csdn.net/qlexcel/article/details/106154743
写的东西比较详细吧,但是感觉有点杂乱,又很长,我当时就不是很想看了,后面简单浏览了一遍,确实比我还是详细很多的,不过我这个主打一个简单高效的使用吧。

基本使用

首先下载了我提供的源码,放到gitee上了,和上面一样的。
在这里插入图片描述

IO配置

这个里面的就是相关包,放入你的工程文件,每个目录下包含inc和src,stm32需要包含头文件的分别包含进入即可。
导入文件后,需要修改vl53l0x_iic.h中的IO口配置和初始化
在这里插入图片描述
上图红框部分了,就是IIC通讯时的引脚电平设置,拿STM32举例就是改为:

//库函数
GPIO_SetBits(GPIOB,GPIO_Pin_10);//PB10 输出高
GPIO_ResetBits(GPIOB,GPIO_Pin_10);//PB10 输出低
//hal库
HAL_GPIO_WritePin(ATK_MS53L0_XSH_GPIO_PORT, ATK_MS53L0_XSH_GPIO_PIN, GPIO_PIN_SET) :
HAL_GPIO_WritePin(ATK_MS53L0_XSH_GPIO_PORT, ATK_MS53L0_XSH_GPIO_PIN, GPIO_PIN_RESET);

其他的MCU也是同样的原理,配置好这个就好。IO口的引脚电平设置,还有一个就是IO口的方向,和读取IO口的数据,这部分在IIC读和ACK读的时候是需要用到的。
另外IO口的初始化IIC两个引脚和VL53L0X_XSH复位引脚,这个IO初始化就需要自己在开始前进行初始化,上面IO口时钟和模式什么的,根据自己MCU配置。
还有IO口有关的头文件记得包含进去。

另外还有两个要修改
一个是串口打印函数,一个延时函数,us级别的

// 这里需要改为自己MCU相关的延时函数
#define vl53l0x_iic_delay(t) BASE_FUNC_DELAY_US(t)
// 这里需要改为自己MCU相关的延时函数
#define print_log DBG_PRINTF

调用测量

上面配置好后,我封装了一下连续测量的一个使用函数,在vl53l0x.c中,你只需要在main.c中包含vl53l0x.h,然后调用其中的函数就可以实现vl53l0x的测量了。vl53l0x.h中主要包含这四个函数:

// 初始化,包含硬件复位,芯片初次IIC通讯和设备验证,6步初始化校验,配置模式和时间。
void vl53l0x_init(void);
// 开始测量
void vl53l0x_start(void);
// 停止测量
void vl53l0x_stop(void);
// 获取测量距离,单位mm
unsigned short get_distance(void);

main函数中调用这四个函数即可实现功能,注意 配置vl53l0x初始化vl53l0x_init ,在初始化之前最好不要开中断(上面定时器中断什么的),可能会扰乱IIC通讯
因为这个初始化过程包含了IIC通讯过程,另外如果初始化成功了后面基本没问题(会有对应的输出),如果失败了那么会卡在这里,因为里面有个死循环。其他的配置可以进去vl53l0x.c在相应的函数实现中直接修改,代码有详细注释。

初始化后,调用vl53l0x_start开始测量,相当于启动按钮,这默认的模式是连续测量,一次时间66ms,vl53l0x.c中可以修改,这时候设备就会不断测量并将结果保存,你需要读取结果时调用get_distance即可得到测量结果,单位为mm。注意这里要开启了测量,因为里面有检查设备是否完成测量的循环,如果没有完成测量就会卡在循环那里,所以确保调用get_distance前,调用了vl53l0x_start。如果你想停止测量,因为是连续测量模式,可以调用vl53l0x_stop。

main.c使用样例

#include "vl53l0x.h" 
//其他相关头文件
unsigned short s_distance;
void main(){
//	注意需要先进行三个IO口的初始化
//	io_config_init();
// 	当然如果你用中断的方式,就是四个,还有一个外部中断IO口 
	vl53l0x_init();
//	time_start() ;定时器中断什么的最好在之后开启。
	vl53l0x_start() ;
//	这里就可以开启测量了,毕竟测量是芯片在做并不消耗mcu资源,
//	当然如果从功率的角度就另说 ,自行在地方调用 
	while(1){
//		主循环
		s_distance = get_distance() ;//这是轮询的方式获取测量结果 
//		printf("ranging result s_distance = %d\r\n",s_distance) ;
		//当然如果是中断的方式就是另外的实现了,但是要记得清除芯片中断标识 
		//vl53l0x.c的注释中有提到		
	}
}

总结

最后总结下流程:

1.下载 源码

2.将my_vl53l0x文件夹导入工程

3.修改vl53l0x_iic.h文件中的函数

4.main.c导入vl53l0x.h,参照样例调用函数,实现测量。

如何,还是很简单,很方便的吧,如果觉得还不错,点赞关注支持一下吧,哈哈~

另外附上vl53l0x.c文件源码


#include "vl53l0x.h"
#include "vl53l0x_iic.h"
#include "vl53l0x_api.h"


#define CUSTOM_DEV_IIC_ADDDR  (VL53L0X_IIC_ADDR)               /*自定义IICַ地址*/
#define DEMO_DEVICE_MODE    VL53L0X_DEVICEMODE_CONTINUOUS_RANGING   /* 连续测量模式 */
#define DEMO_BUDGET_TIME    (66*1000)                               /* 测量时间 */

/* VL53L0X设备结构体 */
static VL53L0X_Dev_t demo_dev = {
    .I2cDevAddr = VL53L0X_IIC_ADDR,                              /* 上电默认IIC通讯地址ַ*/
};


static void device_detect(VL53L0X_DEV dev, uint8_t iic_addr)
{
    uint16_t module_id = 0;
    VL53L0X_Error status;
    /**
     * 获取设备ID,身份鉴别
     * 另外可以相当于一次通讯验证,IIC是否可以正常通讯
     * */
    status = VL53L0X_RdWord(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &module_id);
    // DBG_PRINTF("ATK-MS53L0 ID: %d,status: %d\r\n",module_id,status);
    if (module_id != VL53L0X_MODULE_ID)
    {
        print_log("ATK-MS53L0 Detect Failed!\r\n");
        while (1)
        {
            // 如果通讯失败,就会卡在这个死循环中。
        }
    }   
    /**
     * 改变IIC设备地址
     * 如果你想改变IIC设备地址,有多个设备使用时,可用此API
     * 上电默认的地址是0x29,可以自己设置IIC地址   
    */
    if (iic_addr != dev->I2cDevAddr)
    {
        VL53L0X_SetDeviceAddress(dev, iic_addr << 1);
        dev->I2cDevAddr = iic_addr;
        print_log("Change IIC address success! IIC Address: 0x%x\r\n",iic_addr);
    }else{
        print_log("Default IIC Address: 0x%x\r\n",iic_addr);
    }   
}

/**
 * 设备配置:效准和初始化
 * 根据手册在测量前有一系列初始化和效准过程,保证测量精度

 */
static void device_init(VL53L0X_DEV dev)
{
    uint8_t vhvsettings;
    uint8_t phasecal;
    uint32_t refspadcount;
    uint8_t isaperturespads;
    // 设备初始化 
    VL53L0X_DataInit(dev);
    // 加载特殊配置
    VL53L0X_StaticInit(dev);
    // Spad(单光子雪崩二极管)效准,用来对返射会的IR光进行测量的
    VL53L0X_PerformRefSpadManagement(dev, &refspadcount, &isaperturespads);
    /*温度效准*/
    // VL53L0X_PerformRefCalibration(dev, &vhvsettings, &phasecal);   
    /*偏移效准*/
    // VL53L0X_PerformOffsetCalibration();
    /*串扰效准*/
    // VL53L0X_PerformXTalkCalibration();
    
    /**设置工作模式
     * 有三种工作模式
     * 单次测量         0
     * 连续测量         1
     * 连续延时测量     3
    */
    VL53L0X_SetDeviceMode(dev, DEMO_DEVICE_MODE);
    
    /**设置测量时间
     * 默认时间是33ms,最小的时间是20ms
     * 这个会涉及到准确率,太快,准确率会有所下降
     * 增加测量时间会提高准确率
     * 测量时间增加到2倍,测量的标准差减少到根号2
    */
    VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev, DEMO_BUDGET_TIME);
}

/**
 */
void vl53l0x_init(void)
{
    uint8_t ret;
    VL53L0X_RangingMeasurementData_t data;
    
    vl53l0x_hw_reset();                           //使能,设置 XSHUT引脚为高电平(低电平表示关闭)
    device_detect(&demo_dev, CUSTOM_DEV_IIC_ADDDR);  /*首次通讯验证和设备验证*/
    device_init(&demo_dev);                      /*设备初始化-会设置测试时间(精确相关)和设备工作模式*/
    
    print_log("VL53L0X init Succedded!\r\n");
    
    // /*开始测量*/
    // VL53L0X_StartMeasurement(&demo_dev);
    
    // while (1)
    // {
    //     /*检查是否完成一次测量*/
    //     do {
    //         VL53L0X_GetMeasurementDataReady(&demo_dev, &ret);
    //     } while (ret != 1);       
    //     /**清除中断
    //      * 如果使用中断的方式,通过连接中断引脚进行判断,进入中断后需要清除中断
    //      * 这里使用的是轮询的方式,所以可以不需要
    //     */
    //     // VL53L0X_ClearInterruptMask(&demo_dev, 0);
                
    //     /*获取测量结果*/
    //     VL53L0X_GetRangingMeasurementData(&demo_dev, &data);
    //     /*输出测量结果(单位mm)*/
    //     DBG_PRINTF("Distance: %dmm\r\n", data.RangeMilliMeter);
    // }
}
// 开始测量
void vl53l0x_start(void){
    /*开始测量*/
    VL53L0X_StartMeasurement(&demo_dev);
    print_log("VL53L0X start ranging!\r\n");
}
// 停止测量---连续测量模式下
void vl53l0x_stop(void){
    /*开始测量*/
    VL53L0X_StopMeasurement(&demo_dev);
    print_log("VL53L0X stop ranging!\r\n");
}
// 获取测量结果 单位mm
unsigned short get_distance(void){

    uint8_t ret;
    VL53L0X_RangingMeasurementData_t data;
    /*检查是否完成一次测量*/
    do {
        VL53L0X_GetMeasurementDataReady(&demo_dev, &ret);
    } while (ret != 1);
    /*获取测量结果*/
    VL53L0X_GetRangingMeasurementData(&demo_dev, &data);
    return data.RangeMilliMeter;
} 
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值