本文记录了我使用STM32F103结合VL53L0测距模块的一个学习过程。
VL53L0是由ST公司最新推出的一款飞行时间测距+手势检测的微型模块,它应用非常广泛包括:激光测距、避障检测、一维手势识别等;接下来我们重点介绍它的激光测距功能。
一、模块的硬件连接
上图便是我所使用的测距模块GYVL53L0XV2,它预留了六个接口:
1、VIN:供电电压,可在3V~5V范围内进行供电,但如果自己进行电路搭建的话,则需要一个线性稳压电路,将输入电压稳定在2.8V进行芯片供电和芯片I/O端口的上拉,这个可以自己看它的数据手册;
2、GND:参考地;
3、SCL:I2C通信的时钟线;
4、SDA:I2C通信的数据线;
5、XSHUT:芯片的使能管脚,电平1代表有效,电平0代表无效;
6、GPIO1:芯片的中断管脚。
本文与STM32F103的连线如下:
VIN--------------->3.3V
GND------------->GND
SCL-------------->PB6
SDA-------------->PB7
其中XSHUT与GPIO1没有连接,由电路可知,未连接时它们均上拉为高电平,XSHUT一直为高则代表芯片始终有效工作,如果有需要也可以进行连接,用单片机控制。在这里我没有使用到,因此直接不连接就行。
二、程序代码
- #ifndef _VL53L0_H
- #define _VL53L0_H
- #define VL53L0X_REG_IDENTIFICATION_MODEL_ID 0xc0
- #define VL53L0X_REG_IDENTIFICATION_REVISION_ID 0xc2
- #define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD 0x50
- #define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x70
- #define VL53L0X_REG_SYSRANGE_START 0x00
- #define VL53L0X_REG_RESULT_INTERRUPT_STATUS 0x13
- #define VL53L0X_REG_RESULT_RANGE_STATUS 0x14
- #define VL53L0X_Add 0x29
- #include "stm32f10x.h"
- #include "bsp_usart1.h"
- #include "bsp_i2c_gpio.h"
- u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);
- u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf);
- u8 VL53L0X_Write_Byte(u8 reg,u8 data);
- u8 VL53L0X_Read_Byte(u8 reg);
- uint16_t bswap(u8 b[]);
- uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg);
- uint16_t makeuint16(int lsb, int msb);
- #endif
- #include "VL53L0.h"
- uint16_t bswap(u8 b[])
- {
- uint16_t val = ((b[0]<< 8) & b[1]);
- return val;
- }
- uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg)
- {
- uint16_t vcsel_period_pclks = (vcsel_period_reg + 1) <<1;
- return vcsel_period_pclks;
- }
- uint16_t makeuint16(int lsb, int msb)
- {
- return ((msb & 0xFF) << 8) | (lsb & 0xFF);
- }
- u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
- {
- u8 i;
- i2c_Start();
- i2c_SendByte((addr<<1)|0);
- if(i2c_WaitAck())
- {
- i2c_Stop();
- return 1;
- }
- i2c_SendByte(reg);
- i2c_WaitAck();
- for(i=0;i<len;i++)
- {
- i2c_SendByte(buf[i]);
- if(i2c_WaitAck())
- {
- i2c_Stop();
- return 1;
- }
- }
- i2c_Stop();
- return 0;
- }
- u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
- {
- i2c_Start();
- i2c_SendByte((addr<<1)|0);
- if(i2c_WaitAck())
- i2c_Stop();
- return 1;
- }
- i2c_SendByte(reg);
- i2c_WaitAck();
- i2c_Start();
- i2c_SendByte((addr<<1)|1);
- i2c_WaitAck();
-
- while(len)
- {
- if(len==1)
- {
- *buf=i2c_ReadByte();
- i2c_NAck();
- }
- else
- {
- *buf=i2c_ReadByte();
- i2c_Ack();
- }
- len--;
- buf++;
- }
- i2c_Stop();
- return 0;
- }
- //IIC写一个字节
- //reg:寄存器地址
- //data:数据
- //·返回值:0,代表正常
- // 其他,错误代码
- u8 VL53L0X_Write_Byte(u8 reg,u8 data)
- {
- i2c_Start();
- i2c_SendByte((VL53L0X_Add<<1)|0);//发送器件地址+写命令
- if(i2c_WaitAck()) //等待应答
- {
- i2c_Stop();
- return 1;
- }
- i2c_SendByte(reg); //写寄存器地址
- i2c_WaitAck(); //等待应答
- i2c_SendByte(data);//发送数据
- if(i2c_WaitAck()) //等待应答
- {
- i2c_Stop();
- return 1;
- }
- i2c_Stop();
- return 0;
- }
- //IIC读一个字节
- //reg:寄存器地址
- //返回值:读到的数据
- u8 VL53L0X_Read_Byte(u8 reg)
- {
- u8 res;
- i2c_Start();
- i2c_SendByte(0x52);//发送器件地址+写命令
- i2c_WaitAck(); //等待应答
- i2c_SendByte(reg); //写寄存器地址
- i2c_WaitAck(); //等待应答
- i2c_Start();
- i2c_SendByte(0x53 );//发送器件地址+读命令
- i2c_WaitAck();
- i2c_SendByte(reg); //写寄存器地址
- res=i2c_ReadByte(); //读取数据,发送nACK
- i2c_Stop(); //产生一个停止条件
- return res;
- }
- main.c:
- #include "stm32f10x.h"
- #include "bsp_usart1.h"
- #include "bsp_i2c_gpio.h"
- #include "VL53L0.h"
- uint8_t Rxflag=0;
- uint8_t ucTemp;
- int main(void)
- {
-
- u8 val = 0;
- u8 gbuf[16];
- u8 DeviceRangeStatusInternal;
- u8 tp=0;
-
- uint32_t cnt = 0;
- uint16_t count[3];
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- USARTx_Config();
- NVIC_Configuration();
- InitSysTick();
- bsp_InitI2C();
- while(1)
- {
-
- VL53L0X_Write_Byte(VL53L0X_REG_SYSRANGE_START, 0x01);
-
- while(cnt < 100)
- {
- delay_ms(10);
- val = VL53L0X_Read_Byte(VL53L0X_REG_RESULT_RANGE_STATUS);
- if( val & 0x01) break;
- cnt++;
- }
- if( val & 0x01)
- printf("\r\n readey \r\n");
- else
- printf("\r\n not readey \r\n");
- VL53L0X_Read_Len(VL53L0X_Add, 0x14 , 12, gbuf);
-
- count[0] = makeuint16(gbuf[7], gbuf[6]);
- count[1] = makeuint16(gbuf[9], gbuf[8]);
- count[2] = makeuint16(gbuf[11], gbuf[10]);
- DeviceRangeStatusInternal = ((gbuf[0] & 0x78) >> 3);
- printf("\r\n ambient count = %4d signal count = %4d distance = %4d status = %d ",count[0],count[1],count[2],DeviceRangeStatusInternal);
- delay_ms(1000);
-
-
- }
- }
复制代码
————————————————
版权声明:TangPeng_HanMO
|