概述
VL6180X是基于ST FlightSense™专利技术的最新产品。作为一项突破性技术,它实现了独立于目标反射率的绝对距离测量。传统的测量方法通过测量反射光的光量来估算距离,然而这种方法存在一个主要缺点,即被测物体的颜色和表面特性对测量精度产生很大影响。VL6180X采用了一种全新的方法,它精确测量了光线从传感器照射到最近物体,并在反射回传感器所需的时间(即飞行时间),从而准确计算出两者之间的距离。
VL6180X模块集成了一个红外发射器、一个红外传感器和一个环境光传感器,全部封装在一个便于集成的三合一回流焊封装中。这种设计使终端产品制造商能够减少光学和机械设计的优化过程,并降低相关成本。 该模块具备低功耗操作的特点。测距和环境光感应(ALS)测量可以在用户定义的时间间隔内自动执行。此外,它支持多种门限和中断方案,以最大程度地减少主机操作的需要。 主机控制和结果读取是通过I2C接口实现的,方便快捷。此外,VL6180X还提供两个可编程的GPIO引脚,用于可选的附加功能,例如测量准备和门限中断。 通过以上的优化和扩写,文案更加详细地描述了VL6180X模块的工作原理、集成设计的优势以及支持的功能和接口。这些信息可以帮助读者更好地了解该模块的特性和应用价值。 最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:6_15061293 。
视频教程
[https://www.bilibili.com/video/BV1tX4y1q7Zj/]
样品申请
[https://www.wjx.top/vm/OhcKxJk.aspx#]
完整代码下载
[https://download.csdn.net/download/qq_24312945/87945855]
所有功能
三合一智能光学模块
接近传感器
环境光传感器
VCSEL光源
快速,精确测距
绝对测量范围从0到超过10 cm(10cm以上的测距取决于具体情况)
不受目标反射率影响
环境光抑制
盖片的串扰补偿
盖片的串扰补偿
主机系统可以用距离和信号电平实现手势识别
可用演示系统:P-NUCLEO-6180X1 评估板
环境光传感器
高动态范围
精确/超低光敏感
校准输出值(以勒克斯为单位)
方便集成
单回流焊元件
无附加光学元件
单电源
用于器件控制和数据的I2C接口
提供一个文档化的C可移植 API(应用程序接口)
两个可编程GPIO
测距和ALS的窗口和门限功能
技术规范
该模块的供电要求为2.8V,适合于低电压应用场景。它通过I2C接口进行主机控制和数据通信,方便与其他设备的集成。支持最大快速模式速率,达到400k,确保高效的数据传输。 此外,VL6180X模块具备出色的光照强度检测能力,覆盖了广泛的光照强度范围。从微弱的1 Lux到高达100 kLux的光照强度,该模块能够准确测量环境的光照水平。这使得它在需要实时监测光照条件的应用中非常有用,例如室内照明控制、自动调节显示亮度等。 最后,VL6180X模块具有一个默认地址为0x29的设备地址,这样在多个I2C设备共享同一总线时,可以轻松管理和区分不同的模块。
接口
vl6180模块接口的示意图如下所示。
接口说明
最小系统图
生成STM32CUBEMX
用STM32CUBEMX生成例程,这里使用MCU为STM32G030C8。 配置时钟树,配置时钟为64M。
串口配置
查看原理图,PA9和PA10设置为开发板的串口。
配置串口。
IIC配置
在这个应用中,VL6180模块通过I2C(IIC)接口与主控器通信。具体来说,VL6180模块的I2C引脚连接到主控器的PB6(引脚B6)和PB7(引脚B7)两个IO口。 这种连接方式确保了模块与主控器之间的可靠数据传输和通信。PB6作为I2C总线的串行数据线(SDA),负责数据的传输和接收。而PB7则充当I2C总线的串行时钟线(SCL),用于同步数据传输的时序。
配置IIC为快速模式,速度为400k。
串口重定向
打开魔术棒,勾选MicroLIB
在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函数声明和串口重定向:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END PFP */
模块片选
根据提供的表格信息,我们可以得知VL6180模块的GPIO0/CE引脚用作片选脚(Chip Enable),在需要使用该功能时,需要给该引脚一个高电平信号。 确保在使用GPIO0/CE引脚时,正确设置引脚的电平状态,并按照VL6180模块的规格和要求进行相应的配置和操作。这将确保模块按照预期工作,并满足特定的功能需求。
下面为模块启动时序图。
模块地址
VL6180模块的默认设备地址为0x29。设备地址是用来识别和通信特定设备的标识符。通过将VL6180模块的设备地址设置为0x29,您可以确保与该模块进行正常的通信和控制。
虽然VL6180模块的默认设备地址为0x29,但可以通过使用I2C_SLAVE__DEVICE_ADDRESS {0x212}来修改模块的设备地址。 通过修改设备地址,可以为VL6180模块指定一个与默认地址不同的唯一地址。这种灵活性使您能够在同一I2C总线上连接多个VL6180X模块或与其他设备进行通信,而无需担心地址冲突的问题。
读写位
在I2C总线上,由于可能连接多个设备,主设备在传输有效数据之前需要指定从设备的地址。大多数从设备使用7位地址,而一些设备支持10位地址寻址。主设备在需要发送或接收数据时,首先发送所需从设备的地址,并匹配总线上挂载的从设备的地址。然后,主设备可以将数据发送到SDA数据线上。 紧随地址的第8位是数据方向位(R/W),其中'0'表示发送(写入),'1'表示请求数据(读取)。 对于VL6180模块,默认的7位地址是0x29(二进制为010 1001),加上写位后为0x52(二进制为0101 0010),加上读位后为0x53(二进制为0101 0011)。 这意味着当主设备与VL6180模块进行通信时,要发送0x52地址字节进行写操作,或发送0x53地址字节进行读取操作。
extern I2C_HandleTypeDef hi2c1;
void VL6180X_WriteByte(uint8_t add,uint16_t reg,uint8_t data)
{
HAL_I2C_Mem_Write(&hi2c1 ,(add< < 1)|0,reg,I2C_MEMADD_SIZE_16BIT,&data,1,0xffff);
}
void VL6180X_WriteByte_16Bit(uint8_t add,uint16_t reg,uint16_t data)
{
uint8_t data2[2]={0,0};
data2[0]=data > >8;
data2[1]=data;
HAL_I2C_Mem_Write(&hi2c1 ,(add< < 1)|0,reg,I2C_MEMADD_SIZE_16BIT,data2,2,0xffff);
}
uint8_t VL6180X_ReadByte(uint8_t add,uint16_t reg)
{
uint8_t data=0;
HAL_I2C_Mem_Read(&hi2c1 ,(add< < 1)|1,reg,I2C_MEMADD_SIZE_16BIT,&data,1,0xffff);
return data;
}
uint16_t VL6180X_ReadBytee_16Bit(uint8_t add,uint16_t reg)
{
uint16_t data=0;
uint8_t data2[2];
HAL_I2C_Mem_Read(&hi2c1 ,(add< < 1)|1,reg,I2C_MEMADD_SIZE_16BIT,data2,2,0xffff);
data=data2[0];
data=data< < 8;
data+=data2[1];
return data;
}
模块寄存器
对于VL6180,模块寄存器的地址是16位的,不是8位的。VL6180模块使用16位的寄存器地址来访问和配置各种功能和参数。这种扩展的地址空间提供了更大的灵活性和更多的寄存器选项,以满足不同的应用需求。 在与VL6180模块进行通信时,主设备需要发送16位的寄存器地址,以指定所需的操作和寄存器位置。这样可以确保主设备与模块之间的正确数据交换和通信。
所以对于vl6180模块,读写代码如下所示。
void VL6180X_WriteByte(uint8_t add,uint16_t reg,uint8_t data)
{
HAL_I2C_Mem_Write(&hi2c1 ,(add< < 1)|0,reg,I2C_MEMADD_SIZE_16BIT,&data,1,0xffff);
}
void VL6180X_WriteByte_16Bit(uint8_t add,uint16_t reg,uint16_t data)
{
uint8_t data2[2]={0,0};
data2[0]=data > >8;
data2[1]=data;
HAL_I2C_Mem_Write(&hi2c1 ,(add< < 1)|0,reg,I2C_MEMADD_SIZE_16BIT,data2,2,0xffff);
}
uint8_t VL6180X_ReadByte(uint8_t add,uint16_t reg)
{
uint8_t data=0;
HAL_I2C_Mem_Read(&hi2c1 ,(add< < 1)|1,reg,I2C_MEMADD_SIZE_16BIT,&data,1,0xffff);
return data;
}
uint16_t VL6180X_ReadBytee_16Bit(uint8_t add,uint16_t reg)
{
uint16_t data=0;
uint8_t data2[2];
HAL_I2C_Mem_Read(&hi2c1 ,(add< < 1)|1,reg,I2C_MEMADD_SIZE_16BIT,data2,2,0xffff);
data=data2[0];
data=data< < 8;
data+=data2[1];
return data;
}
初始化
首先需要检查寄存器SYSTEM__FRESH_OUT_OF_RESET {0x16}是否为0x01.
可以通过读取SYSTEM__FRESH_OUT_OF_RESET {0x16}进行判断设备是否准备好,之后进行6180初始化。 初始化如下所示。
uint8_t ptp_offset;
uint8_t VL6180X_Init(uint8_t add)
{
ptp_offset=VL6180X_ReadByte(add,VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET);
printf("ptp_offset=%dn",ptp_offset);
// if(VL6180X_Read_ID(add) == VL6180X_DEFAULT_ID)
if(ptp_offset==0x01)
{
VL6180X_WriteByte(add,0x0207, 0x01);
VL6180X_WriteByte(add,0x0208, 0x01);
VL6180X_WriteByte(add,0x0096, 0x00);
VL6180X_WriteByte(add,0x0097, 0xfd);
VL6180X_WriteByte(add,0x00e3, 0x00);
VL6180X_WriteByte(add,0x00e4, 0x04);
VL6180X_WriteByte(add,0x00e5, 0x02);
VL6180X_WriteByte(add,0x00e6, 0x01);
VL6180X_WriteByte(add,0x00e7, 0x03);
VL6180X_WriteByte(add,0x00f5, 0x02);
VL6180X_WriteByte(add,0x00d9, 0x05);
VL6180X_WriteByte(add,0x00db, 0xce);
VL6180X_WriteByte(add,0x00dc, 0x03);
VL6180X_WriteByte(add,0x00dd, 0xf8);
VL6180X_WriteByte(add,0x009f, 0x00);
VL6180X_WriteByte(add,0x00a3, 0x3c);
VL6180X_WriteByte(add,0x00b7, 0x00);
VL6180X_WriteByte(add,0x00bb, 0x3c);
VL6180X_WriteByte(add,0x00b2, 0x09);
VL6180X_WriteByte(add,0x00ca, 0x09);
VL6180X_WriteByte(add,0x0198, 0x01);
VL6180X_WriteByte(add,0x01b0, 0x17);
VL6180X_WriteByte(add,0x01ad, 0x00);
VL6180X_WriteByte(add,0x00ff, 0x05);
VL6180X_WriteByte(add,0x0100, 0x05);
VL6180X_WriteByte(add,0x0199, 0x05);
VL6180X_WriteByte(add,0x01a6, 0x1b);
VL6180X_WriteByte(add,0x01ac, 0x3e);
VL6180X_WriteByte(add,0x01a7, 0x1f);
VL6180X_WriteByte(add,0x0030, 0x00);
// Recommended : Public registers - See data sheet for more detail
VL6180X_WriteByte(add,0x0011, 0x10); // Enables polling for 'New Sample ready'
// when measurement completes
VL6180X_WriteByte(add,0x010a, 0x30); // Set the averaging sample period
// (compromise between lower noise and
// increased execution time)
VL6180X_WriteByte(add,0x003f, 0x46); // Sets the light and dark gain (upper
// nibble). Dark gain should not be
// changed. !上半字节要写入0x4 默认增益是1.0
VL6180X_WriteByte(add,0x0031, 0xFF); // sets the # of range measurements after
// which auto calibration of system is
// performed
VL6180X_WriteByte(add,0x0041, 0x63); // Set ALS integration time to 100ms
VL6180X_WriteByte(add,0x002e, 0x01); // perform a single temperature calibration
// of the ranging sensor
// Optional: Public registers - See data sheet for more detail
VL6180X_WriteByte(add,0x001b, 0x09); //测量间隔 轮询模式
// period to 100ms 每步10ms- >0-10ms
VL6180X_WriteByte(add,0x003e, 0x31); //测量周期 ALS模式
// to 500ms