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目的:

  1. 检测通信是否成功
  2. 检测芯片是否正常工作

初始化

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传感器驱动相关推荐

  1. 第四章 PX4-Pixhawk-MPU6000传感器驱动解析

    第四章MPU6000传感器驱动解析 Mpu6000是一个3轴加速度和3轴陀螺仪传感器,这一章节我们将对MPU6000这个传感器进行解析,依照这个解析步骤同样可以对L3GD20(3轴陀螺仪).HMC58 ...

  2. 第四章MPU6000传感器驱动解析

    版权声明:本文为博主原创文章,未经博主允许不得转载. 第四章MPU6000传感器驱动解析 Mpu6000是一个3轴加速度和3轴陀螺仪传感器,这一章节我们将对MPU6000这个传感器进行解析,依照这个解 ...

  3. 外设驱动库开发笔记32:HLPM025K3 PM2.5传感器驱动

      现在人们对大气环境及室内环境都比较关注.PM2.5在生活中也是常见的词汇.在有些产品中就要求检测PM2.5的数值.检测PM2.5的手段多种多样,在要求不高时我们通常可以采用激光模块.在这一篇中,我 ...

  4. 外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动

      在气体分析类产品中,我们经常会用到远红外气体传感器.我们就在碳氢类气体成分分析中使用了S-Modlue远红外气体传感器.接下来,我们将讨论S-Modlue远红外气体传感器驱动的设计与实现. 1.功 ...

  5. 外设驱动库开发笔记13:MLX90614红外温度传感器驱动

    红外温度传感器一般用于非接触式的温度检测.在我们的系统中经常会有这样的需求.所以我们将其设计为通用的驱动库以备复用.这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现. 1.功能概述 ML ...

  6. 外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

    在我们的产品中经常会遇到温湿度检测的需求.可以用于检测温湿度的传感器元件也有很多.我们经常使用的SHT各系列数字温湿度传感器来实现应用需求.在这里我们将设计并实现SHT3x系列温湿度传感器的驱动. 1 ...

  7. 外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

    温湿度检测是嵌入式编程中经常应用到的一项功能.在我们的产品中亦经常使用.SHT2x系列温湿度传感器作为一种高精度低成本的集成模块,一直应用于我们的产品中.在这里我们讨论如何封装SHT2x系列温湿度传感 ...

  8. 外设驱动库开发笔记9:SHT1x系列温湿度传感器驱动

    在我们的产品中,经常需要检测温湿度数据.有很多检测温湿度的方法和模块,其中SHT1x系列温湿度传感器就是一种成本较低使用方便的温湿度检测模块.下面我们就来说一说如何实现SHT1x系列温湿度传感器的驱动 ...

  9. ESP8266-Arduino编程实例-MQ3酒精传感器驱动

    MQ3酒精传感器驱动 1.MQ3介绍 MQ3 气体传感器模块可用于气体泄漏检测(在家庭和工业中). 适用于检测酒精.苯.CH4.己烷.液化石油气.一氧化碳.由于灵敏度高.响应时间快,可以尽快进行测量. ...

最新文章

  1. 通过 Mysql 官网配置更新本地的mysql源
  2. SAP MM 启用批次管理的物料,在分类视图里指派023类型分类不是必须的
  3. 《 自动化测试最佳实践:来自全球的经典自动化测试案例解析》一一2.4 开发内部测试工具...
  4. Java学习_day006:嵌套循环与数组
  5. ensp中ap获取不到ip_对比网络模拟器软件,Cisco Packet Tracer、华为eNSP、H3C Cloud Lab...
  6. UE4材质:纯数学算法实现水面水波扩散效果
  7. 用Python处理图片九宫格
  8. 如何使用Gitbook创建html技术文档
  9. vue监听移动设备的返回事件
  10. linux执行sh提示非标准环境,Linux执行.sh文件时提示No such file or directory该怎么办(三种解决办法)...
  11. 泛微OA ecology 您查看的文档过大,请下载文档后查看
  12. python画图设置字体_python Matplotlib画图之调整字体大小的示例
  13. 一文学会LCD12864显示中文、英文、反显
  14. switch删除用户显示正在维护服务器,Switch即将迎来6.0更新 账号与用户无法再正常解绑...
  15. 基于ssm+vue的综合项目 健康体检管理系统-第十章-权限控制、图形报表
  16. 电信光猫F420破解
  17. 用python爬取今日头条上的图片_Python爬虫:抓取今日头条图集
  18. 什么样的程序员才算得上优秀,把导师曾对我说的话送给大家(比代码更重要的事)
  19. 用Java语句判断一个数字是不是7的倍数
  20. bat备份MySQL失败_bat备份mysql的方法

热门文章

  1. 文章采集模板下载 采集文章大全
  2. a fatal error java sigsegv_在Linux中Java运行时环境中的致命SIGSEGV错误
  3. 部署微信小程序的后台服务器
  4. rsync 同步数据记录_非初学者指南与Rsync同步数据
  5. 怎么删除服务器存储虚拟磁盘,创建/修改/调整/连接/分离/删除虚拟磁盘(一)
  6. 微课与个性化学习路径之浅谈
  7. [SEEDLabs] Format String Attack Lab
  8. 题解 | 2023河南萌新联赛第(四)场:河南大学 解题报告
  9. python自动发QQ邮箱小程序
  10. 面试失败流的泪往往是写简历时脑袋进的水