

//四個VL53L0掛載在同一個IIC總線下,所以使用四個片選信號--2019/10/30//!!!!!!!注意:重新使能設備后,設備iic的地址會恢復為默認值0x52--2019/10/30//VL53L0 0//片選使能--2019/10/30void i2c_init(void);uint8_t i2c_write(uint8_t addr, uint8_t reg, uint32_t len, uint8_t * data);uint8_t i2c_read(uint8_t addr, uint8_t reg, uint32_t len, uint8_t *buf);
void i2c_init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//模擬iic配置GPIO_InitStructure.GPIO_Pin = I2C_PIN_SCL;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_SCL_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = I2C_PIN_SDA;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_Init(I2C_SDA_GPIO, &GPIO_InitStructure);//片選使能配置GPIO_InitStructure.GPIO_Pin = I2C_PIN_X0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_X_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = I2C_PIN_X1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_X_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = I2C_PIN_X2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_X_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = I2C_PIN_X3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_X_GPIO, &GPIO_InitStructure);I2C_X0_LOW();I2C_X1_LOW();I2C_X2_LOW();I2C_X3_LOW();delay_ms(20);}
VL53L0X_Error vl53l0x_init(void){VL53L0X_Error Status = VL53L0X_ERROR_NONE; //初始值賦值為0//初始化一定按照這個順序執行,否則不成功VL53L0X_i2c_init();vl53l0x_initX(&vl53l0x_dev0,0);vl53l0x_initX(&vl53l0x_dev1,1);vl53l0x_initX(&vl53l0x_dev2,2);vl53l0x_initX(&vl53l0x_dev3,3);return Status; //返回0}
//單個VL53L0初始化VL53L0X_Error vl53l0x_initX( VL53L0X_Dev_t *pMyDevice ,u8 vl53l0_x_id){VL53L0X_Error Status = VL53L0X_ERROR_NONE; //初始值賦值為0pMyDevice->I2cDevAddr = 0x52; //iic地址 0x52是默認地址,要初始化必須先寫0x52,才能初始化,之后再通過軟件修改pMyDevice->comms_type = 1; //選擇IIC還是SPI iic=1;SPI=0pMyDevice->comms_speed_khz = 400; //iic速率//正點原子的VL53L0用戶手冊上寫明了再次使能時地址會恢復為0x52,所以只能使能一次,設置好地址即可,這里是核心switch(vl53l0_x_id){case 0:I2C_X0_HIGH();delay_ms(20);vl53l0x_Addr_set(pMyDevice,0x60);//設置第一個VL53L0X傳感器I2C地址break;case 1:I2C_X1_HIGH();delay_ms(20);vl53l0x_Addr_set(pMyDevice,0x62);//設置第一個VL53L0X傳感器I2C地址break;case 2:I2C_X2_HIGH();delay_ms(20);vl53l0x_Addr_set(pMyDevice,0x64);break;case 3:I2C_X3_HIGH();delay_ms(20);vl53l0x_Addr_set(pMyDevice,0x66);break;}Status = VL53L0X_DataInit(pMyDevice); // Data initialization //VL53L0X_DataInit:一次設備的初始化,初始化成功返回0if(Status != VL53L0X_ERROR_NONE){ //判斷如果狀態不為0 打印錯誤信息print_pal_error(Status);return Status; // 返回錯誤值 可通過此值DEBUG查找錯誤位置}Status = VL53L0X_GetDeviceInfo(pMyDevice, &vl53l0x_dev_info); //讀取給定設備的設備信息if(Status != VL53L0X_ERROR_NONE){print_pal_error(Status);return Status;}printf("VL53L0X_GetDeviceInfo:\n");printf("Device Name : %s\n", vl53l0x_dev_info.Name); //設備名printf("Device Type : %s\n", vl53l0x_dev_info.Type); //產品類型VL53L0X = 1, VL53L1 = 2printf("Device ID : %s\n", vl53l0x_dev_info.ProductId); // 設備IDprintf("ProductRevisionMajor : %d\n", vl53l0x_dev_info.ProductRevisionMajor);printf("ProductRevisionMinor : %d\n", vl53l0x_dev_info.ProductRevisionMinor);if ((vl53l0x_dev_info.ProductRevisionMajor != 1) && (vl53l0x_dev_info.ProductRevisionMinor != 1)){printf("Error expected cut 1.1 but found cut %d.%d\n",vl53l0x_dev_info.ProductRevisionMajor, vl53l0x_dev_info.ProductRevisionMinor);Status = VL53L0X_ERROR_NOT_SUPPORTED;print_pal_error(Status);return Status;}Status = vl53l0x_measure_init(pMyDevice); //測量配置vl53l0x_status = Status;if(Status != VL53L0X_ERROR_NONE){ //判斷如果不為0打印錯誤信息print_pal_error(Status);return Status;}}
模塊的初始化順序是:使用默認地址初始化設備---修改傳感器IIC地址---再次初始化---測量配置
所以在這個傳感器的初始化中我們先用默認的0X52地址將VL53L0X模塊初始化,初始化完成后方可修改其地址,這里使用SWITCH函數判斷用戶配置的地址,避免函數重寫,減小代碼尺寸。修改完地址調用VL53L0X_DataInit()函數進行模塊的再次初始化,使修改生效。
注意:VL53L0X不能保存地址,如果掉電后地址會恢復為默認的0X52,同時修改完地址后只能執行一次初始化,更多的初始化次數會也會導致地址復位。這在硬件的處理上要加倍注意。

VL53L0X_Error vl53l0x_start_single_test(VL53L0X_Dev_t *pdev, \VL53L0X_RangingMeasurementData_t *pdata){int i=0,j=0,sum=0;VL53L0X_Error status = VL53L0X_ERROR_NONE;if(vl53l0x_status != VL53L0X_ERROR_NONE)return vl53l0x_status;status = VL53L0X_PerformSingleRangingMeasurement(pdev, pdata); ////執行單次測距并獲取測距測量數據if(status != VL53L0X_ERROR_NONE){printf("error:Call of VL53L0X_PerformSingleRangingMeasurement\n");return status;}for(i=0;i<5;i++)sum+=pdata->RangeMilliMeter;pdata->RangeMilliMeter=sum/5;printf("%d\r\n",pdata->RangeMilliMeter);return status;}
