VL6180X传感器驱动
vl6180x_i2c.c
I2C通信
获取VL6180x地址
可以知道7位地址为0x29
写: 0x52
读: 0x53
写入数据
/** 通过I2C总线向某一寄存器写入一个字节数据* 成功 0* 失败 1 */
uint8 VL6180X_WriteBytes(uint8 I2C_addr,uint16 index,uint8 dat)
{uint8 Index_H = (uint8)(index >> 8);uint8 Index_L = (uint8)(index & 0xff);start();iic_write(I2C_addr | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(Index_H); //TDOS'registerif (check_ack()==0) {goto err;}iic_write(Index_L); //TDOS'registerif (check_ack()==0) {goto err;}iic_write(dat); //发送数据字节if (check_ack()==0) {goto err;}stop();return 0;
err:stop();return 1;
}
读出数据
读单个数据
/** 通过I2C总线读出某一寄存器的数据*/
uint8 VL6180x_ReadBytes(uint8 I2C_addr, uint16 index) {uint8 dat;uint8 Index_H = (uint8)(index >> 8);uint8 Index_L = (uint8)(index & 0xff);start();iic_write(I2C_addr | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(Index_H); //TDOS'registerif (check_ack()==0) {goto err;}iic_write(Index_L); //TDOS'registerif (check_ack()==0) {goto err;}start(); //重发起动信号iic_write(I2C_addr | 0X01); //READif (check_ack()==0) {goto err;}dat = iic_read(); //接收读出的数据stop();return dat;
err:stop();return 0;
}
读两组数据
/** 通过I2C总线读出某一寄存器的数据*/
uint16 VL6180x_Read_Two_Bytes(uint8 I2C_addr, uint16 index) {uint8 t;uint16 data_res;uint8 Index_H = (uint8)(index >> 8);uint8 Index_L = (uint8)(index & 0xff);start();iic_write(I2C_addr | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(Index_H); //TDOS'registerif (check_ack()==0) {goto err;}iic_write(Index_L); //TDOS'registerif (check_ack()==0) {goto err;}stop();start(); //重发起动信号iic_write(I2C_addr | 0X01); //READif (check_ack()==0) {goto err;}t = iic_read(); //接收读出的数据send_ack(); data_res = t; t = iic_read(); //接收读出的数据send_ack(); data_res = ((data_res<<8) | t);// t = iic_read(); //接收读出的数据
// send_ack();
// data_res = ((data_res<<16) | t);
//
// t = iic_read(); //接收读出的数据
// send_ack();
// data_res = ((data_res<<24) | t);stop();return data_res;
err:stop();return 0;
}
检测ID
从文档中获取ID地址:
地址:0x000
默认值: 0xB4
/*
*********************************************************************************************************1. 函 数 名: VL6180X_CheckID2. 功能说明: 获取VL6180X的ID3. 返 回 值: VL6180X_ID
*********************************************************************************************************
*/
uint8 VL6180X_CheckID(void)
{uint8 data_ID;data_ID = VL6180x_ReadBytes(DEV_ADDR, VL6180X_IDENTIFICATION_MODEL_ID);return data_ID;
}
获取芯片的ID目的:
- 检测通信是否成功
- 检测芯片是否正常工作
初始化
void VL6180X_Init(void)
{uint8 reset=0, timeOut=0;GPIO_0_OUTPUT;GPIO_1_OUTPUT;
// Power_PIN_OUTPUT;
// Power_PIN_PORT=0;
// GPIO_0_PIN_PORT = 0;
// GPIO_1_PIN_PORT = 0;
// DelayMS(5);
// Power_PIN_PORT=1;
// DelayMS(5);
// GPIO_0_PIN_PORT = 1;
// GPIO_1_PIN_PORT = 1;
// DelayMS(5);GPIO_0_PIN_PORT = 0;GPIO_1_PIN_PORT = 0;DelayMS(10);GPIO_0_PIN_PORT = 1;GPIO_1_PIN_PORT = 1;DelayMS(1);while(!(VL6180X_CheckID() == 0xB4));DelayMS(5);VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_FRESH_OUT_OF_RESET, 0x01); while (reset!=1 && timeOut<100) {reset = VL6180x_ReadBytes(DEV_ADDR, VL6180X_SYSTEM_FRESH_OUT_OF_RESET); // read fresh_out_of_reset bitif(reset == 1) { // if if fresh_out_of_reset bit set, then device has been freshly initialized// SR03 settings AN4545 24/27 DocID026571 Rev 19 SR03 settings// http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf// Below are the recommended settings required to be loaded onto the VL6180X during the// initialisation of the device (see Section 1.3).// Mandatory : private registersVL6180X_WriteBytes(DEV_ADDR, 0x0207, 0x01);data_reg = VL6180x_ReadBytes(DEV_ADDR, 0x0207);VL6180X_WriteBytes(DEV_ADDR, 0x0208, 0x01);VL6180X_WriteBytes(DEV_ADDR, 0x0096, 0x00);VL6180X_WriteBytes(DEV_ADDR, 0x0097, 0xFD);VL6180X_WriteBytes(DEV_ADDR, 0x00e3, 0x00);VL6180X_WriteBytes(DEV_ADDR, 0x00e4, 0x04);data_reg = VL6180x_ReadBytes(DEV_ADDR, 0x00e4);VL6180X_WriteBytes(DEV_ADDR, 0x00e5, 0x02);VL6180X_WriteBytes(DEV_ADDR, 0x00e6, 0x01);VL6180X_WriteBytes(DEV_ADDR, 0x00e7, 0x03);VL6180X_WriteBytes(DEV_ADDR, 0x00f5, 0x02);VL6180X_WriteBytes(DEV_ADDR, 0x00d9, 0x05);VL6180X_WriteBytes(DEV_ADDR, 0x00db, 0xce);VL6180X_WriteBytes(DEV_ADDR, 0x00dc, 0x03);VL6180X_WriteBytes(DEV_ADDR, 0x00dd, 0xf8);VL6180X_WriteBytes(DEV_ADDR, 0x009f, 0x00);VL6180X_WriteBytes(DEV_ADDR, 0x00a3, 0x3c);VL6180X_WriteBytes(DEV_ADDR, 0x00b7, 0x00);VL6180X_WriteBytes(DEV_ADDR, 0x00bb, 0x3c);VL6180X_WriteBytes(DEV_ADDR, 0x00b2, 0x09);VL6180X_WriteBytes(DEV_ADDR, 0x00ca, 0x09);VL6180X_WriteBytes(DEV_ADDR, 0x0198, 0x01);VL6180X_WriteBytes(DEV_ADDR, 0x01b0, 0x17);VL6180X_WriteBytes(DEV_ADDR, 0x01ad, 0x00);VL6180X_WriteBytes(DEV_ADDR, 0x00ff, 0x05);VL6180X_WriteBytes(DEV_ADDR, 0x0100, 0x05);VL6180X_WriteBytes(DEV_ADDR, 0x0199, 0x05);VL6180X_WriteBytes(DEV_ADDR, 0x01a6, 0x1b);VL6180X_WriteBytes(DEV_ADDR, 0x01ac, 0x3e);VL6180X_WriteBytes(DEV_ADDR, 0x01a7, 0x1f);VL6180X_WriteBytes(DEV_ADDR, 0x0030, 0x00);data_reg = VL6180x_ReadBytes(DEV_ADDR, 0x0030);// configure range measurement for low power// Specify range measurement interval in units of 10 ms from 0 (= 10 ms) - 254 (= 2.55 s)VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x0A); // 100 ms interval in steps of 10 msVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // sets number of range measurements after which autocalibrate is performedVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform temperature calibration of the ranging sensor// Set Early Convergence Estimate for lower power consumptionVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32); // set max convergence time to 50 ms (steps of 1 ms)VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); // enable (0x01) early convergence estimate// This ECE is calculated as follows:// [(1 - % below threshold) x 0.5 x 15630]/ range max convergence time// This is ~123 ms for 50 ms max convergence time and 80% below threshold// This is a sixteen bit (2 byte) register with the first byte MSByte and the second LSByteVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x00); // set early convergence estimate to 5%VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE + 1, 0x7B); // set early convergence estimate to 5%// Configure ALSVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // set to 100 msdata_reg = VL6180x_ReadBytes(DEV_ADDR, VL6180X_SYSALS_INTERMEASUREMENT_PERIOD);// Following is a 16-bit register with the first MSByte reservedVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_INTEGRATION_PERIOD, 0x00);VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_INTEGRATION_PERIOD+1, 0x63); // set ALS integration time to 100 ms in steps of 1 ms// The internal readout averaging sample period can be adjusted from 0 to 255. Increasing the sampling// period decreases noise but also reduces the effective max convergence time and increases power consumption:// Effective max convergence time = max convergence time - readout averaging period (see// Section 2.5: Range timing). Each unit sample period corresponds to around 64.5 ?s additional// processing time. The recommended setting is 48 which equates to around 4.3 msVL6180X_WriteBytes(DEV_ADDR, VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); // compromise between low noise and increased execution time// Gain can be 0 = 20, 1 = 10, 2 = 5, 3 = 2.5, 4 = 1.67, 5 = 1.25, 6 = 1.0 and 7 = 40// These are value possible for the lower nibble. The upper nibble must be 4VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_ANALOGUE_GAIN, 0x40 | 1); // Sets light and dark gain (don't change upper nibble)data_reg = VL6180x_ReadBytes(DEV_ADDR, VL6180X_SYSALS_ANALOGUE_GAIN);// Scalar (1 - 32, bits 4:0) to multiply raw ALS count for additonal gain, if necessaryVL6180X_WriteBytes(DEV_ADDR, VL6180X_FIRMWARE_RESULT_SCALER, 0x01);// Configure the interruptsVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_MODE_GPIO0, 0x00); // set up GPIO 0 (set to high impedence for now)VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_MODE_GPIO1, 0x00); // set up GPIO 1 (set to high impedence for now)VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // enable sample ready interrupt#if 0// enable continuous range modeif(VL6180XMode == contRangeMode) {VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_START, 0x03); // start auto range mode}// enable continuous ALS modeif(VL6180XMode == contALSMode) {// Configure ALSVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_INTERMEASUREMENT_PERIOD, 0x32); // set to 100 ms// Following is a 16-bit register with the first MSByte reservedVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_INTEGRATION_PERIOD+1, 0x32); // set ALS integration time to 50 ms in steps of 1 msVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSALS_START, 0x03); // start auto range mode}
#endif// Clear reset bitVL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_FRESH_OUT_OF_RESET, 0x00); // reset fresh_out_of_reset bit to zero} else {timeOut++;}}reset=0;}
这段代码可以移植官方例程,配置寄存器的值,初始化I\O口
获取光强值
uint16 ligthPollingRead(void)
{uint8 status;uint16 alsraw;/* Wait for device ready. */do {status = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_ALS_STATUS);} while ((status & (1 << 0)) == 0);VL6180X_WriteBytes(DEV_ADDR,VL6180X_SYSALS_START, START_SINGLE_MODE);data_reg = VL6180x_ReadBytes(DEV_ADDR, VL6180X_SYSALS_START);status = VL6180x_ReadBytes(DEV_ADDR,VL6180X_RESULT_INTERRUPT_STATUS_GPIO);status = status & ALS_SINGLE_MODE_MASK;// while (status != ALS_SINGLE_MODE_READY) {
// status = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_INTERRUPT_STATUS_GPIO);
// status = status & ALS_SINGLE_MODE_MASK;
// DelayMS(1);
// }alsraw = VL6180x_Read_Two_Bytes(DEV_ADDR, VL6180X_RESULT_ALS_VAL);//als = 0.32f * ((float) alsraw / 10.32) * (100.0f/100.0f);VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_INTERRUPT_CLEAR, CLEAR_ALS_INT);return alsraw;
}
获取距离数据
uint8 RangePollingRead(void)
{uint8 status;uint8 distance;/* Wait for device ready. */do {status = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_RANGE_STATUS);} while ((status & (1 << 0)) == 0);VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_START, START_SINGLE_MODE);data_reg = VL6180x_ReadBytes(DEV_ADDR, VL6180X_SYSRANGE_START);status = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_INTERRUPT_STATUS_GPIO);status = status & RANGE_SINGLE_MODE_MASK;/* Wait for measurement ready. */while (status != RANGE_SINGLE_MODE_READY) {status = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_INTERRUPT_STATUS_GPIO);status = status & RANGE_SINGLE_MODE_MASK;DelayMS(1);}DelayMS(10);distance = VL6180x_ReadBytes(DEV_ADDR, VL6180X_RESULT_RANGE_VAL);VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSTEM_INTERRUPT_CLEAR, CLEAR_ALS_INT);return distance;
}
GitHub工程源代码:
https://github.com/lanhaixuan/CC2541_VL6180X_BMA250
VL6180X传感器驱动相关推荐
- 第四章 PX4-Pixhawk-MPU6000传感器驱动解析
第四章MPU6000传感器驱动解析 Mpu6000是一个3轴加速度和3轴陀螺仪传感器,这一章节我们将对MPU6000这个传感器进行解析,依照这个解析步骤同样可以对L3GD20(3轴陀螺仪).HMC58 ...
- 第四章MPU6000传感器驱动解析
版权声明:本文为博主原创文章,未经博主允许不得转载. 第四章MPU6000传感器驱动解析 Mpu6000是一个3轴加速度和3轴陀螺仪传感器,这一章节我们将对MPU6000这个传感器进行解析,依照这个解 ...
- 外设驱动库开发笔记32:HLPM025K3 PM2.5传感器驱动
现在人们对大气环境及室内环境都比较关注.PM2.5在生活中也是常见的词汇.在有些产品中就要求检测PM2.5的数值.检测PM2.5的手段多种多样,在要求不高时我们通常可以采用激光模块.在这一篇中,我 ...
- 外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动
在气体分析类产品中,我们经常会用到远红外气体传感器.我们就在碳氢类气体成分分析中使用了S-Modlue远红外气体传感器.接下来,我们将讨论S-Modlue远红外气体传感器驱动的设计与实现. 1.功 ...
- 外设驱动库开发笔记13:MLX90614红外温度传感器驱动
红外温度传感器一般用于非接触式的温度检测.在我们的系统中经常会有这样的需求.所以我们将其设计为通用的驱动库以备复用.这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现. 1.功能概述 ML ...
- 外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动
在我们的产品中经常会遇到温湿度检测的需求.可以用于检测温湿度的传感器元件也有很多.我们经常使用的SHT各系列数字温湿度传感器来实现应用需求.在这里我们将设计并实现SHT3x系列温湿度传感器的驱动. 1 ...
- 外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动
温湿度检测是嵌入式编程中经常应用到的一项功能.在我们的产品中亦经常使用.SHT2x系列温湿度传感器作为一种高精度低成本的集成模块,一直应用于我们的产品中.在这里我们讨论如何封装SHT2x系列温湿度传感 ...
- 外设驱动库开发笔记9:SHT1x系列温湿度传感器驱动
在我们的产品中,经常需要检测温湿度数据.有很多检测温湿度的方法和模块,其中SHT1x系列温湿度传感器就是一种成本较低使用方便的温湿度检测模块.下面我们就来说一说如何实现SHT1x系列温湿度传感器的驱动 ...
- ESP8266-Arduino编程实例-MQ3酒精传感器驱动
MQ3酒精传感器驱动 1.MQ3介绍 MQ3 气体传感器模块可用于气体泄漏检测(在家庭和工业中). 适用于检测酒精.苯.CH4.己烷.液化石油气.一氧化碳.由于灵敏度高.响应时间快,可以尽快进行测量. ...
最新文章
- 通过 Mysql 官网配置更新本地的mysql源
- SAP MM 启用批次管理的物料,在分类视图里指派023类型分类不是必须的
- 《 自动化测试最佳实践:来自全球的经典自动化测试案例解析》一一2.4 开发内部测试工具...
- Java学习_day006:嵌套循环与数组
- ensp中ap获取不到ip_对比网络模拟器软件,Cisco Packet Tracer、华为eNSP、H3C Cloud Lab...
- UE4材质:纯数学算法实现水面水波扩散效果
- 用Python处理图片九宫格
- 如何使用Gitbook创建html技术文档
- vue监听移动设备的返回事件
- linux执行sh提示非标准环境,Linux执行.sh文件时提示No such file or directory该怎么办(三种解决办法)...
- 泛微OA ecology 您查看的文档过大,请下载文档后查看
- python画图设置字体_python Matplotlib画图之调整字体大小的示例
- 一文学会LCD12864显示中文、英文、反显
- switch删除用户显示正在维护服务器,Switch即将迎来6.0更新 账号与用户无法再正常解绑...
- 基于ssm+vue的综合项目 健康体检管理系统-第十章-权限控制、图形报表
- 电信光猫F420破解
- 用python爬取今日头条上的图片_Python爬虫:抓取今日头条图集
- 什么样的程序员才算得上优秀,把导师曾对我说的话送给大家(比代码更重要的事)
- 用Java语句判断一个数字是不是7的倍数
- bat备份MySQL失败_bat备份mysql的方法
热门文章
- 文章采集模板下载 采集文章大全
- a fatal error java sigsegv_在Linux中Java运行时环境中的致命SIGSEGV错误
- 部署微信小程序的后台服务器
- rsync 同步数据记录_非初学者指南与Rsync同步数据
- 怎么删除服务器存储虚拟磁盘,创建/修改/调整/连接/分离/删除虚拟磁盘(一)
- 微课与个性化学习路径之浅谈
- [SEEDLabs] Format String Attack Lab
- 题解 | 2023河南萌新联赛第(四)场:河南大学 解题报告
- python自动发QQ邮箱小程序
- 面试失败流的泪往往是写简历时脑袋进的水