STM32F103+VL53L0测距(一)

本文记录了我使用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);
		 
	
	}
}

具体代码可下载:以上代码的完整版-STM32F103+VL53L0源代码

**未完待续:STM32F103+VL53L0测距(二)

接下来将要发布的内容是关于STM32F103使用GPIO模拟I2C与VL53L0通信的代码**

  • 18
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
这两年来,AI技术的迅猛发展,无人驾驶汽车热度疯狂,智能产品的不断涌现,图像识别、语音识别、神经网络感知等人工智能正处于难得的发展机遇期,人工智能和实体经济融合进一步深化,智能化产品也源源不断地涌现。产品智能化就需要大脑主控芯片和各种各样的sensor,ST现有推出一款TOF激光测距sensoor VL53L0,高精度测距,可以用于机器人、无人机、扫地机、手机等。目前ST推出VL53L0+ STM32F401RE智能机器人扫地方案。 核心技术优势1、 前、后、左、右各装一个VL53L0激光测距sensor, 每个sensor发射940nm波长非可见光,通过TOF测出各方向的距离, 通过软件计算,得出房子环境空间的布局情况。 2、 可以设定多种清扫模式。包括沿边清扫、集中清扫、随机清扫、直线清扫等工作模式。 3、 设定好清扫模式后,可以开始清扫操作,如遇难到障碍物,会自动避让,自动选择最佳的行进路线。 4、 清扫完成后,机器会自动停机 方案规格1.STM32F401RE和VL53L0都是ST自产芯片,ST MCU具有极高的性价比,市面普及度也高。 2.VL53L0功耗低、体积小,正常工作模式下功耗仅20mW,待机功耗只有5µA。封装尺寸为2.4mm x 4.4mm x 1mm,业界目前体积最小的同类产品,同时支持手势识别。 3.距离测量精度高,可以达毫米级。 4.测量距离最长可达2米。 5.ST可以提供基于STM32F401RE和VL53L0软件开发包。 6.可以外扩一块蓝牙模块和重力、陀螺sensor,进行更精确的运动轨迹操控和手机APP操作。 7.VL53L0可以同时挂载多颗。 8.VL53L0采用快速响应的FlightSenseTM技术。 方案来源于大大通。
基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例 基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例 基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例 基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例基于51单片机开发的小程序,学习资料,用于学习51单片机的嵌入式开发,应用案例
STM32F103VL53L0是两种不同的产品。STM32F103是意法半导体公司生产的32位ARM Cortex-M3微控制器,而VL53L0是STMicroelectronics公司生产的Time of Flight(Time-of-Flight)激光测距模块。 STM32F103是一款性能强大的微控制器,具有高性能处理器和丰富的外设接口,可以广泛应用于各种嵌入式系统中。它采用ARM Cortex-M3处理器,时钟频率可达到72MHz,具有多种片上存储器选项和丰富的外设,如通用I/O口、串口、SPI、I2C、定时器、ADC等,同时也提供了丰富的开发工具和软件库,为开发人员提供了方便。 而VL53L0是一款高精度激光测距模块,采用ToF(Time-of-Flight)技术,可以实现长距离非接触式测距。它可以通过测量光脉冲的往返时间来计算出距离,具有高精度、快速、低功耗等优点。VL53L0模块支持I2C接口,可以方便地与微控制器进行通信,适用于各种距离测量应用,如机器人导航、物体检测等。 当使用STM32F103搭配VL53L0模块时,可以通过I2C接口将两者连接起来,实现距离测量功能。开发人员可以借助STM32F103微控制器的丰富外设和软件库,与VL53L0模块进行通信和控制,从而实现对距离测量的精确控制和数据处理。 综上所述,STM32F103VL53L0是两种不同的产品,STM32F103是一款强大的32位微控制器,而VL53L0是一款高精度激光测距模块。当二者组合使用时,可以实现距离测量功能,并借助STM32F103的强大性能和丰富的外设来进行控制和数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值