打印
[STM32F1]

vl53l0x激光测距

[复制链接]
81|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
uiint|  楼主 | 2023-12-30 21:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

#include "vl53l0x.h"

VL53L0X_Dev_t vl53l0x_dev;//设备I2C数据参数
VL53L0X_DeviceInfo_t vl53l0x_dev_info;//设备ID版本信息
uint8_t AjustOK=0;//校准标志位

//VL53L0X各精度模式参数
//0:默认;1:高精度;2:长距离;3:高速
mode_data Mode_data[]=
{
    {(FixPoint1616_t)(0.25*65536),
         (FixPoint1616_t)(18*65536),
         33000,
         14,
         10},//默认
               
        {(FixPoint1616_t)(0.25*65536) ,
         (FixPoint1616_t)(18*65536),
         200000,
         14,
         10},//高精度
               
    {(FixPoint1616_t)(0.1*65536) ,
         (FixPoint1616_t)(60*65536),
         33000,
         18,
         14},//长距离
      
    {(FixPoint1616_t)(0.25*65536) ,
         (FixPoint1616_t)(32*65536),
         20000,
         14,
         10},//高速
               
};

//API错误信息打印
//Status:详情看VL53L0X_Error参数的定义
void print_pal_error(VL53L0X_Error Status)
{
      
        char buf[VL53L0X_MAX_STRING_LENGTH];
      
        VL53L0X_GetPalErrorString(Status,buf);//根据Status状态获取错误信息字符串
      
    printf("API Status: %i : %s\r\n",Status, buf);//打印状态和错误信息
      
}

//模式字符串显示
//mode:0-默认;1-高精度;2-长距离;3-高速
void mode_string(u8 mode,char *buf)
{
        switch(mode)
        {
                case Default_Mode: strcpy(buf,"Default");        break;
                case HIGH_ACCURACY: strcpy(buf,"High Accuracy"); break;
                case LONG_RANGE: strcpy(buf,"Long Range");       break;
                case HIGH_SPEED: strcpy(buf,"High Speed");       break;
        }

}

//配置VL53L0X设备I2C地址
//dev:设备I2C参数结构体
//newaddr:设备新I2C地址
VL53L0X_Error vl53l0x_Addr_set(VL53L0X_Dev_t *dev,uint8_t newaddr)
{
        uint16_t Id;
        uint8_t FinalAddress;
        VL53L0X_Error Status = VL53L0X_ERROR_NONE;
        u8 sta=0x00;
      
        FinalAddress = newaddr;
      
        if(FinalAddress==dev->I2cDevAddr)//新设备I2C地址与旧地址一致,直接退出
                return VL53L0X_ERROR_NONE;
        //在进行第一个寄存器访问之前设置I2C标准模式(400Khz)
        Status = VL53L0X_WrByte(dev,0x88,0x00);
        if(Status!=VL53L0X_ERROR_NONE)
        {
                sta=0x01;//设置I2C标准模式出错
                goto set_error;
        }
        //尝试使用默认的0x52地址读取一个寄存器
        Status = VL53L0X_RdWord(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Id);
        if(Status!=VL53L0X_ERROR_NONE)
        {
                sta=0x02;//读取寄存器出错
                goto set_error;
        }
        if(Id == 0xEEAA)
        {
                //设置设备新的I2C地址
                Status = VL53L0X_SetDeviceAddress(dev,FinalAddress);
                if(Status!=VL53L0X_ERROR_NONE)
                {
                        sta=0x03;//设置I2C地址出错
                        goto set_error;
                }
                //修改参数结构体的I2C地址
                dev->I2cDevAddr = FinalAddress;
                //检查新的I2C地址读写是否正常
                Status = VL53L0X_RdWord(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Id);
                if(Status!=VL53L0X_ERROR_NONE)
                {
                        sta=0x04;//新I2C地址读写出错
                        goto set_error;
                }      
        }
        set_error:
        if(Status!=VL53L0X_ERROR_NONE)
        {
                print_pal_error(Status);//打印错误信息
        }
        if(sta!=0)
          printf("sta:0x%x\r\n",sta);
        return Status;
}

//vl53l0x复位函数
//dev:设备I2C参数结构体
void vl53l0x_reset(VL53L0X_Dev_t *dev)
{
        uint8_t addr;
        addr = dev->I2cDevAddr;//保存设备原I2C地址
    VL53L0X_Xshut=0;//失能VL53L0X
        delay_ms(30);
        VL53L0X_Xshut=1;//使能VL53L0X,让传感器处于工作(I2C地址会恢复默认0X52)
        delay_ms(30);      
        dev->I2cDevAddr=0x52;
        vl53l0x_Addr_set(dev,addr);//设置VL53L0X传感器原来上电前原I2C地址
        VL53L0X_DataInit(dev);      
}

//初始化vl53l0x
//dev:设备I2C参数结构体
VL53L0X_Error vl53l0x_init(VL53L0X_Dev_t *dev)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        VL53L0X_Error Status = VL53L0X_ERROR_NONE;
        VL53L0X_Dev_t *pMyDevice = dev;
      
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);    //使能AFIO时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //先使能外设IO PORTA时钟
      
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;                   //端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      //IO口速度为50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);                                   //根据设定参数初始化GPIOA

        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁止JTAG,从而PA15可以做普通IO使用,否则PA15不能做普通IO!!!
               
        pMyDevice->I2cDevAddr = VL53L0X_Addr;//I2C地址(上电默认0x52)
        pMyDevice->comms_type = 1;           //I2C通信模式
        pMyDevice->comms_speed_khz = 400;    //I2C通信速率
      
        VL53L0X_i2c_init();//初始化IIC总线
      
        VL53L0X_Xshut=0;//失能VL53L0X
        delay_ms(30);
        VL53L0X_Xshut=1;//使能VL53L0X,让传感器处于工作
        delay_ms(30);
      
    vl53l0x_Addr_set(pMyDevice,0x54);//设置VL53L0X传感器I2C地址
    if(Status!=VL53L0X_ERROR_NONE) goto error;
        Status = VL53L0X_DataInit(pMyDevice);//设备初始化
        if(Status!=VL53L0X_ERROR_NONE) goto error;
        delay_ms(2);
        Status = VL53L0X_GetDeviceInfo(pMyDevice,&vl53l0x_dev_info);//获取设备ID信息
    if(Status!=VL53L0X_ERROR_NONE) goto error;
      
        AT24CXX_Read(0,(u8*)&Vl53l0x_data,sizeof(_vl53l0x_adjust));//读取24c02保存的校准数据,若已校准 Vl53l0x_data.adjustok==0xAA
        if(Vl53l0x_data.adjustok==0xAA)//已校准
          AjustOK=1;      
        else //没校准      
          AjustOK=0;
      
        error:
        if(Status!=VL53L0X_ERROR_NONE)
        {
                print_pal_error(Status);//打印错误信息
                return Status;
        }
         
        return Status;
}

//主菜单界面
void vl53l0x_mtest_ui(void)
{
         POINT_COLOR=BLUE;//设置字体为蓝色
         LCD_Fill(30,170,300,300,WHITE);
         LCD_ShowString(30,170,200,16,16,"KEY_UP: Calibration mode");//校准模式
         LCD_ShowString(30,190,200,16,16,"KEY1:   General mode");    //普通测量模式
         LCD_ShowString(30,210,200,16,16,"KEY0:   Interrupt mode");  //中断测量模式
}

//VL53L0X主测试程序
void vl53l0x_test(void)
{   
         u8 i=0;
         u8 key=0;
         while(vl53l0x_init(&vl53l0x_dev))//vl53l0x初始化
         {
                LCD_ShowString(30,140,200,16,16,"VL53L0X Error!!!");
            delay_ms(500);
                LCD_ShowString(30,140,200,16,16,"                ");
                delay_ms(500);
                LED0=!LED0;//DS0闪烁
         }
         printf("VL53L0X OK\r\n");
         LCD_ShowString(30,140,200,16,16,"VL53L0X OK");
         vl53l0x_mtest_ui();//主菜单显示
         while(1)
         {
                 
                 key = KEY_Scan(0);
                 if(key)
                 {
                          switch(key)
                          {
                                  case WKUP_PRES:  vl53l0x_calibration_test(&vl53l0x_dev);           break;//校准模式
                                  case KEY1_PRES:  vl53l0x_general_test(&vl53l0x_dev);               break;//普通测量模式
                                  case KEY0_PRES:  vl53l0x_interrupt_test(&vl53l0x_dev);             break;//中断测量模式  
                          }
                          vl53l0x_mtest_ui();
                 }
                 i++;
                 if(i==5)
                 {
                         i=0;
                         LED0=!LED0;
                 }
                 delay_ms(50);
                 
         }
}

//----------以下函数为USMART调用------------//

//获取vl53l0x传感器ID信息
void vl53l0x_info(void)
{
        printf("\r\n-------vl53l0x传感器设备信息-------\r\n\r\n");
        printf("  Name:%s\r\n",vl53l0x_dev_info.Name);
        printf("  Addr:0x%x\r\n",vl53l0x_dev.I2cDevAddr);
        printf("  ProductId:%s\r\n",vl53l0x_dev_info.ProductId);
        printf("  RevisionMajor:0x%x\r\n",vl53l0x_dev_info.ProductRevisionMajor);
        printf("  RevisionMinor:0x%x\r\n",vl53l0x_dev_info.ProductRevisionMinor);
        printf("\r\n-----------------------------------\r\n");
}

//获取一次测量距离数据
//mode模式配置 0:默认;1:高精度;2:长距离;3:高速
void One_measurement(u8 mode)
{
        vl53l0x_set_mode(&vl53l0x_dev,mode);
        VL53L0X_PerformSingleRangingMeasurement(&vl53l0x_dev,&vl53l0x_data);
        printf("\r\n d: %4d mm.\r\n",vl53l0x_data.RangeMilliMeter);
               
}


#include "vl53l0x_gen.h"

VL53L0X_RangingMeasurementData_t vl53l0x_data;//测距测量结构体
vu16 Distance_data=0;//保存测距数据

//VL53L0X 测量模式配置
//dev:设备I2C参数结构体
//mode: 0:默认;1:高精度;2:长距离;3:高速
VL53L0X_Error vl53l0x_set_mode(VL53L0X_Dev_t *dev,u8 mode)
{
      
         VL53L0X_Error status = VL53L0X_ERROR_NONE;
         uint8_t VhvSettings;
         uint8_t PhaseCal;
         uint32_t refSpadCount;
         uint8_t isApertureSpads;
      
         vl53l0x_reset(dev);//复位vl53l0x(频繁切换工作模式容易导致采集距离数据不准,需加上这一代码)
         status = VL53L0X_StaticInit(dev);

     if(AjustOK!=0)//已校准好了,写入校准值
     {
            status= VL53L0X_SetReferenceSpads(dev,Vl53l0x_data.refSpadCount,Vl53l0x_data.isApertureSpads);//设定Spads校准值
        if(status!=VL53L0X_ERROR_NONE) goto error;      
        delay_ms(2);                 
            status= VL53L0X_SetRefCalibration(dev,Vl53l0x_data.VhvSettings,Vl53l0x_data.PhaseCal);//设定Ref校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
                 delay_ms(2);
            status=VL53L0X_SetOffsetCalibrationDataMicroMeter(dev,Vl53l0x_data.OffsetMicroMeter);//设定偏移校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
                 delay_ms(2);
                status=VL53L0X_SetXTalkCompensationRateMegaCps(dev,Vl53l0x_data.XTalkCompensationRateMegaCps);//设定串扰校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);                 
                 
     }
         else
         {
                status = VL53L0X_PerformRefCalibration(dev, &VhvSettings, &PhaseCal);//Ref参考校准
                if(status!=VL53L0X_ERROR_NONE) goto error;
                delay_ms(2);
                status = VL53L0X_PerformRefSpadManagement(dev, &refSpadCount, &isApertureSpads);//执行参考SPAD管理
                if(status!=VL53L0X_ERROR_NONE) goto error;
        delay_ms(2);                          
         }
         status = VL53L0X_SetDeviceMode(dev,VL53L0X_DEVICEMODE_SINGLE_RANGING);//使能单次测量模式
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,1);//使能SIGMA范围检查
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,1);//使能信号速率范围检查
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,Mode_data[mode].sigmaLimit);//设定SIGMA范围
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,Mode_data[mode].signalLimit);//设定信号速率范围范围
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev,Mode_data[mode].timingBudget);//设定完整测距最长时间
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, Mode_data[mode].preRangeVcselPeriod);//设定VCSEL脉冲周期
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, Mode_data[mode].finalRangeVcselPeriod);//设定VCSEL脉冲周期范围
         
         error://错误信息
         if(status!=VL53L0X_ERROR_NONE)
         {
                print_pal_error(status);
                LCD_Fill(30,140+20,300,300,WHITE);
                return status;
         }
         return status;
      
}      

//VL53L0X 单次距离测量函数
//dev:设备I2C参数结构体
//pdata:保存测量数据结构体
VL53L0X_Error vl53l0x_start_single_test(VL53L0X_Dev_t *dev,VL53L0X_RangingMeasurementData_t *pdata,char *buf)
{

        VL53L0X_Error status = VL53L0X_ERROR_NONE;
        uint8_t RangeStatus;
      
        status = VL53L0X_PerformSingleRangingMeasurement(dev, pdata);//执行单次测距并获取测距测量数据
        if(status !=VL53L0X_ERROR_NONE) return status;
   
        RangeStatus = pdata->RangeStatus;//获取当前测量状态
    memset(buf,0x00,VL53L0X_MAX_STRING_LENGTH);
        VL53L0X_GetRangeStatusString(RangeStatus,buf);//根据测量状态读取状态字符串
      
        Distance_data = pdata->RangeMilliMeter;//保存最近一次测距测量数据
      
    return status;
}


//启动普通测量
//dev:设备I2C参数结构体
//mode模式配置 0:默认;1:高精度;2:长距离
void vl53l0x_general_start(VL53L0X_Dev_t *dev,u8 mode)
{
        static char buf[VL53L0X_MAX_STRING_LENGTH];//测试模式字符串字符缓冲区
        VL53L0X_Error Status=VL53L0X_ERROR_NONE;//工作状态
        u8 key=0;
        u8 i=0;
      
        LED0=1;
        mode_string(mode,buf);//显示当前配置的模式
        while(vl53l0x_set_mode(dev,mode))//配置精度模式
        {
                LCD_ShowString(30,140+40,200,16,16,"Mode Set Error!!!");
                delay_ms(500);
                LCD_ShowString(30,140+40,200,16,16,"                 ");
                delay_ms(500);
                i++;
                if(i==2) return;
      
        }
        LCD_Fill(30,140+20,300,300,WHITE);
        LCD_ShowString(30,140+30,200,16,16,"KEY_UP: Exit the test             ");               
        LCD_ShowString(30,140+50,200,16,16,"Mode:        ");
        LCD_ShowString(80,140+50,200,16,16,(u8*)buf);
        LCD_ShowString(30,140+70,200,16,16,"State:");//显示测量状态         
        LCD_ShowString(30,140+90,200,16,16,"Distance:    0 mm");//显示测量距离
        while(1)
        {
                 key = KEY_Scan(0);
                 if(key == WKUP_PRES)
                 {
                         LED1=1;
                         break;//返回上一菜单
                        
                 }
                 if(Status==VL53L0X_ERROR_NONE)
                 {
                                Status = vl53l0x_start_single_test(dev,&vl53l0x_data,buf);//执行一次测量
                                LCD_ShowString(85,140+70,200,16,16,(u8*)buf);
                                LCD_ShowxNum(110,140+90,Distance_data,4,16,0);
                                //printf("State;%i , %s\r\n",vl53l0x_data.RangeStatus,buf);//打印测量状态      
                                printf("d: %4imm\r\n",Distance_data);//打印测量距离
                 }
                 i++;
                 if(i==5)
                 {
                         i=0;
                         LED1=!LED1;      
                 }
         delay_ms(50);      
               
        }      
      
}

//vl53l0x普通测量模式UI
void general_ui(void)
{
        LCD_Fill(30,140+20,300,300,WHITE);
        POINT_COLOR=RED;        //设置字体为红色
        LCD_ShowString(30,140+30,300,16,16,"General Mode                  ");
        LCD_ShowString(30,140+55,300,16,16,"KEY1: Switch working mode    ");
        POINT_COLOR=BLUE;       //设置字体为蓝色
        LCD_ShowString(30,140+75,300,16,16, "KEY_UP: Return menu    ");
        LCD_ShowString(30,140+95,300,16,16, "KEY0:   Default        ");
      
}

//vl53l0x普通测量模式测试
//dev:设备I2C参数结构体
void vl53l0x_general_test(VL53L0X_Dev_t *dev)
{
        u8 key=0;
        u8 i=0;
        u8 mode=0;
        LED1=1;
        general_ui();//显示普通测量模式UI
      
        while(1)
        {      

                key = KEY_Scan(0);
               
                if(key==WKUP_PRES)        break;//返回主菜单        
               
                else if(key==KEY1_PRES)//选择工作模式
                {
             mode++;
                         if(mode==4) mode=0;
                         switch(mode)
                         {
                                 case Default_Mode:  LCD_ShowString(95,140+95,300,16,16, "Default        "); break;//默认
                                 case HIGH_ACCURACY: LCD_ShowString(95,140+95,300,16,16, "High Accuracy  "); break;//高精度
                                 case LONG_RANGE:    LCD_ShowString(95,140+95,300,16,16, "Long Range     "); break;//长距离
                                 case HIGH_SPEED:    LCD_ShowString(95,140+95,300,16,16, "High Speed     "); break;//高速
                         }
                }      
                else if(key==KEY0_PRES)//启动测量
                {
                        vl53l0x_general_start(dev,mode);
                general_ui();
                        mode=0;
                }                       
                i++;
                if(i==5)
                {
                        i=0;
                        LED0=!LED0;
                }
                delay_ms(50);

        }
      
}
复制代码
#include "vl53l0x_it.h"


//上下限距离值 单位:mm
#define Thresh_Low  60
#define Thresh_High 150

//中断模式参数结构体
typedef struct
{
     const int VL53L0X_Mode;//模式
         uint32_t ThreshLow;    //下限值
         uint32_t ThreshHigh;   //上限值
}AlrmMode_t;

AlrmMode_t AlarmModes ={
      
     VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT,// value < thresh_low OR value > thresh_high
         Thresh_Low<<16,
         Thresh_High<<16
};

//中断配置初始化
static void exti_init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
      
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟
      
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource4);
        EXTI_InitStructure.EXTI_Line = EXTI_Line4;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);                 //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
      
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                            //使能按键WK_UP所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2,
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;                    //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                    //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);
      
}

//警报标志位 alarm_flag
//1:有警报
//0:无
u8 alarm_flag=0;

//外部中断服务函数
void EXTI4_IRQHandler(void)
{
        alarm_flag=1;//标志
        EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE4上的中断标志位
}

extern uint8_t AjustOK;
extern mode_data Mode_data[];

//vl53l0x中断测量模式测试
//dev:设备I2C参数结构体
//mode: 0:默认;1:高精度;2:长距离;3:高速
void vl53l0x_interrupt_start(VL53L0X_Dev_t *dev,uint8_t mode)
{
         uint8_t VhvSettings;
         uint8_t PhaseCal;
         uint32_t refSpadCount;
         uint8_t isApertureSpads;
         VL53L0X_RangingMeasurementData_t RangingMeasurementData;
         static char buf[VL53L0X_MAX_STRING_LENGTH];//测试模式字符串字符缓冲区
         VL53L0X_Error status=VL53L0X_ERROR_NONE;//工作状态
         u8 key;

         exti_init();//中断初始化
         LED0=1;
         mode_string(mode,buf);//显示当前配置的模式
         LCD_Fill(30,170,300,300,WHITE);
     POINT_COLOR=RED;        //设置字体为红色
         LCD_ShowString(30,140+30,300,16,16,"Interrupt Mode             ");
         POINT_COLOR=BLUE;       //设置字体为蓝色
         LCD_ShowString(30,140+50,200,16,16,"KEY_UP: Exit the test       ");
         LCD_ShowString(30,140+70,200,16,16,"Mode:        ");
         LCD_ShowString(80,140+70,200,16,16,(u8*)buf);
     sprintf((char*)buf,"Thresh Low:  %d mm ",Thresh_Low);      
         LCD_ShowString(30,140+90,300,16,16,(u8*)buf);
         sprintf((char*)buf,"Thresh High: %d mm",Thresh_High);      
         LCD_ShowString(30,140+110,300,16,16,(u8*)buf);
     LCD_ShowString(30,140+130,300,16,16,"Now value:     mm");
         
     vl53l0x_reset(dev);//复位vl53l0x(频繁切换工作模式容易导致采集距离数据不准,需加上这一代码)
         status = VL53L0X_StaticInit(dev);
         if(status!=VL53L0X_ERROR_NONE) goto error;

         if(AjustOK!=0)//已校准好了,写入校准值
         {
                status= VL53L0X_SetReferenceSpads(dev,Vl53l0x_data.refSpadCount,Vl53l0x_data.isApertureSpads);//设定Spads校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
        delay_ms(2);                 
                status= VL53L0X_SetRefCalibration(dev,Vl53l0x_data.VhvSettings,Vl53l0x_data.PhaseCal);//设定Ref校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
                delay_ms(2);
                status=VL53L0X_SetOffsetCalibrationDataMicroMeter(dev,Vl53l0x_data.OffsetMicroMeter);//设定偏移校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
                delay_ms(2);
                status=VL53L0X_SetXTalkCompensationRateMegaCps(dev,Vl53l0x_data.XTalkCompensationRateMegaCps);//设定串扰校准值
                if(status!=VL53L0X_ERROR_NONE) goto error;
         }else
         {
                 status = VL53L0X_PerformRefCalibration(dev, &VhvSettings, &PhaseCal);//Ref参考校准
                if(status!=VL53L0X_ERROR_NONE) goto error;
                delay_ms(2);
                status = VL53L0X_PerformRefSpadManagement(dev, &refSpadCount, &isApertureSpads);//执行参考SPAD管理
                if(status!=VL53L0X_ERROR_NONE) goto error;
        delay_ms(2);                 
         }
         status = VL53L0X_SetDeviceMode(dev,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING);//使能连续测量模式
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetInterMeasurementPeriodMilliSeconds(dev,Mode_data[mode].timingBudget);//设置内部周期测量时间
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,1);//使能SIGMA范围检查
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,1);//使能信号速率范围检查
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,Mode_data[mode].sigmaLimit);//设定SIGMA范围
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,Mode_data[mode].signalLimit);//设定信号速率范围范围
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev,Mode_data[mode].timingBudget);//设定完整测距最长时间
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, Mode_data[mode].preRangeVcselPeriod);//设定VCSEL脉冲周期
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, Mode_data[mode].finalRangeVcselPeriod);//设定VCSEL脉冲周期范围
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_StopMeasurement(dev);//停止测量
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetInterruptThresholds(dev,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,AlarmModes.ThreshLow, AlarmModes.ThreshHigh);//设定触发中断上、下限值
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_SetGpioConfig(dev,0,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,AlarmModes.VL53L0X_Mode,VL53L0X_INTERRUPTPOLARITY_LOW);//设定触发中断模式 下降沿
         if(status!=VL53L0X_ERROR_NONE) goto error;
         delay_ms(2);
         status = VL53L0X_ClearInterruptMask(dev,0);//清除VL53L0X中断标志位
         
         error://错误信息
         if(status!=VL53L0X_ERROR_NONE)
         {
                print_pal_error(status);
                return ;
         }

         alarm_flag = 0;
         VL53L0X_StartMeasurement(dev);//启动测量
         while(1)
         {   
                key = KEY_Scan(0);
                if(key==WKUP_PRES)
                {
                        VL53L0X_ClearInterruptMask(dev,0);//清除VL53L0X中断标志位
                        status = VL53L0X_StopMeasurement(dev); //停止测量
                        LED1=1;
                        break;//返回上一菜单
                }                       
                if(alarm_flag==1)//触发中断
                {
                        alarm_flag=0;
                        VL53L0X_GetRangingMeasurementData(dev,&RangingMeasurementData);//获取测量距离,并且显示距离
                        printf("d: %3d mm\r\n",RangingMeasurementData.RangeMilliMeter);
                        LCD_ShowxNum(110,140+130,RangingMeasurementData.RangeMilliMeter,4,16,0);
                        delay_ms(70);
                        VL53L0X_ClearInterruptMask(dev,0);//清除VL53L0X中断标志位
                       
                }
                delay_ms(30);
                LED1=!LED1;

         }
               
}

//vl53l0x中断测量模式UI
void interrupt_ui(void)
{
        LCD_Fill(30,140+20,300,300,WHITE);
        POINT_COLOR=RED;        //设置字体为红色
        LCD_ShowString(30,140+30,300,16,16,"Interrupt Mode                  ");
        LCD_ShowString(30,140+55,300,16,16,"KEY1: Switch working mode    ");
        POINT_COLOR=BLUE;       //设置字体为蓝色
        LCD_ShowString(30,140+75,300,16,16, "KEY_UP: Return menu    ");
        LCD_ShowString(30,140+95,300,16,16, "KEY0:   Default        ");
      
}

//vl53l0x中断测量模式测试
//dev:设备I2C参数结构体
void vl53l0x_interrupt_test(VL53L0X_Dev_t *dev)
{
        u8 key=0;
        u8 i=0;
        u8 mode=0;
        LED1=1;
        interrupt_ui();//显示中断测量模式UI
      
        while(1)
        {
                key = KEY_Scan(0);
               
                if(key==WKUP_PRES)        break;//返回主菜单        
               
                else if(key==KEY1_PRES)//选择工作模式
                {
             mode++;
                         if(mode==4) mode=0;
                       
                         switch(mode)
                         {
                                 case Default_Mode:  LCD_ShowString(95,140+95,300,16,16, "Default        "); break;//默认
                                 case HIGH_ACCURACY: LCD_ShowString(95,140+95,300,16,16, "High Accuracy  "); break;//高精度
                                 case LONG_RANGE:    LCD_ShowString(95,140+95,300,16,16, "Long Range     "); break;//长距离
                                 case HIGH_SPEED:    LCD_ShowString(95,140+95,300,16,16, "High Speed     "); break;//高速
                         }
                }      
                else if(key==KEY0_PRES)//启动测量
                {
                        vl53l0x_interrupt_start(dev,mode);
                interrupt_ui();
                        mode=0;
                }                       
                i++;
                if(i==5)
                {
                        i=0;
                        LED0=!LED0;
                }
                delay_ms(50);
        }
      
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

3938

帖子

1

粉丝