移植VL53L1X(二)代码开源

本文档详细描述了如何在VL53L1传感器平台上进行I2C通信,包括写入和读取多字节操作,以及与GD32F4xx微控制器的集成,展示了传感器模块的移植测试工程实现。
摘要由CSDN通过智能技术生成

测试工程链接:传感器_梁山派: 梁山派移植各个传感器模块的测试工程 - Gitee.com

相关文件:

platform.c


/* 
* This file is part of VL53L1 Platform 
* 
* Copyright (c) 2016, STMicroelectronics - All Rights Reserved 
* 
* License terms: BSD 3-clause "New" or "Revised" License. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions are met: 
* 
* 1. Redistributions of source code must retain the above copyright notice, this 
* list of conditions and the following disclaimer. 
* 
* 2. Redistributions in binary form must reproduce the above copyright notice, 
* this list of conditions and the following disclaimer in the documentation 
* and/or other materials provided with the distribution. 
* 
* 3. Neither the name of the copyright holder nor the names of its contributors 
* may be used to endorse or promote products derived from this software 
* without specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
* 
*/

#include "vl53l1_platform.h"
#include <string.h>
#include <time.h>
#include <math.h>

#include "vl53l1_iic.h"/* 该文件为vl53l1_platform.c相关函数的底层实现 */
#include "systick.h"

int8_t VL53L1_WriteMulti( uint16_t dev, uint16_t index, uint8_t *pdata, uint32_t count) {
	int8_t status;
	
	status = vl53_writeBytes((uint8_t)dev, index, pdata, count);
	
	return status; // to be implemented
}

int8_t VL53L1_ReadMulti(uint16_t dev, uint16_t index, uint8_t *pdata, uint32_t count){
	int8_t status;
	
	status = vl53_readBytes((uint8_t)dev, index, pdata, count);
	
	return status; // to be implemented
}

int8_t VL53L1_WrByte(uint16_t dev, uint16_t index, uint8_t data) {
	int8_t status;
	
	status = vl53_writeBytes((uint8_t)dev, index, &data, 1);
	
	return status; // to be implemented
}

int8_t VL53L1_WrWord(uint16_t dev, uint16_t index, uint16_t data) {
	int8_t status;
	uint8_t buffer[2];
	
	// Split 16-bit word into MS and LS uint8_t
	buffer[0] = (uint8_t)(data >> 8);
	buffer[1] = (uint8_t)(data &  0x00FF);
	
	status = vl53_writeBytes((uint8_t)dev, index, buffer, 2);
	
	return status; // to be implemented
}

int8_t VL53L1_WrDWord(uint16_t dev, uint16_t index, uint32_t data) {
	int8_t status;
	uint8_t  buffer[4];

	// Split 32-bit word into MS ... LS bytes
	buffer[0] = (uint8_t) (data >> 24);
	buffer[1] = (uint8_t)((data &  0x00FF0000) >> 16);
	buffer[2] = (uint8_t)((data &  0x0000FF00) >> 8);
	buffer[3] = (uint8_t) (data &  0x000000FF);
	
	status = vl53_writeBytes((uint8_t)dev, index, buffer, 4);
	
	return status; // to be implemented
}

int8_t VL53L1_RdByte(uint16_t dev, uint16_t index, uint8_t *data) {
	int8_t status;
	
	status = vl53_readBytes((uint8_t)dev, index, data, 1);
	
	return status; // to be implemented
}

int8_t VL53L1_RdWord(uint16_t dev, uint16_t index, uint16_t *data) {
	int8_t status;
	uint8_t buffer[2];
	
	status = vl53_readBytes((uint8_t)dev, index, buffer, 2);
	
	*data = (uint16_t)(((uint16_t)(buffer[0])<<8) + (uint16_t)buffer[1]);
	
	return status; // to be implemented
}

int8_t VL53L1_RdDWord(uint16_t dev, uint16_t index, uint32_t *data) {
	int8_t status;
	uint8_t buffer[4];
	
	status = vl53_readBytes((uint8_t)dev, index, buffer, 4);
	
	*data = ((uint32_t)buffer[0]<<24) + ((uint32_t)buffer[1]<<16) + ((uint32_t)buffer[2]<<8) + (uint32_t)buffer[3];
	
	return status; // to be implemented
}

int8_t VL53L1_WaitMs(uint16_t dev, int32_t wait_ms){
	int8_t status = 0;
	
	delay_1ms((uint32_t)wait_ms);
	
	return status; // to be implemented
}

vl53_iic.c

#include "vl53l1_iic.h"
#include "gd32f4xx.h"

/* 此处定义了与VL53L1X有关的宏 */
#define VL53_IIC			I2C0
#define VL53_IIC_RCU		RCU_I2C0
/* VL53L1X使用的IIC总线及相关宏 */

#define VL53_GPIO_SCL_RCU	RCU_GPIOB
#define VL53_GPIO_SCL_PORT	GPIOB
#define VL53_GPIO_SCL_PIN	GPIO_PIN_8
#define VL53_GPIO_SCL_AF	GPIO_AF_4
/* SCL引脚相关宏 */

#define VL53_GPIO_SDA_RCU	RCU_GPIOB
#define VL53_GPIO_SDA_PORT	GPIOB
#define VL53_GPIO_SDA_PIN	GPIO_PIN_7
#define VL53_GPIO_SDA_AF	GPIO_AF_4
/* SDA引脚相关宏 */

#define IIC_MASTER_ADDR		0x80

/* 时钟使能 */
static void rcu_config(void)
{
	rcu_periph_clock_enable(VL53_IIC_RCU);
	rcu_periph_clock_enable(VL53_GPIO_SCL_RCU);
	rcu_periph_clock_enable(VL53_GPIO_SDA_RCU);
}

/* 引脚配置 */
static void gpio_config(void)
{
	gpio_af_set(VL53_GPIO_SCL_PORT, VL53_GPIO_SCL_AF, VL53_GPIO_SCL_PIN);
	gpio_mode_set(VL53_GPIO_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, VL53_GPIO_SCL_PIN);
	gpio_output_options_set(VL53_GPIO_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, VL53_GPIO_SCL_PIN);
	/* 配置SCL引脚 */
	
	gpio_af_set(VL53_GPIO_SDA_PORT, VL53_GPIO_SDA_AF, VL53_GPIO_SDA_PIN);
	gpio_mode_set(VL53_GPIO_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, VL53_GPIO_SDA_PIN);
	gpio_output_options_set(VL53_GPIO_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, VL53_GPIO_SDA_PIN);
	/* 配置SDA引脚 */
}

/* IIC配置 */
static void iic_config(void)
{
	i2c_deinit(VL53_IIC);
	i2c_clock_config(VL53_IIC, 100000, I2C_DTCY_2);/* 通信速率为100khz */
	i2c_mode_addr_config(VL53_IIC, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, IIC_MASTER_ADDR);/* iic模式,7位地址 */
	i2c_enable(VL53_IIC);/* 使能iic */
	i2c_ack_config(VL53_IIC, I2C_ACK_ENABLE);/* 使能应答位发送 */
}

/* IIC总线初始化 */
void vl53_IICinit(void)
{
	rcu_config();
	gpio_config();
	iic_config();
}

/* 
* 功能	将提供的字节缓冲区写入设备,用于对接platform.c中相关函数
* 参数	dev_addr:	7位设备地址
*		reg_addr:	16位寄存器地址
*		*pdata:	数据缓冲区指针
*		len:		数据长度
* 返回	操作是否成功
*/
int8_t vl53_writeBytes(uint8_t dev_addr, uint16_t reg_addr, uint8_t *pdata, uint32_t len)
{
	uint32_t i = 0;
	uint8_t *ptr = pdata;
	
	i2c_start_on_bus(VL53_IIC);/* 生成起始信号 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_SBSEND));/* 等待SBSEND标志位置位 */
	
	i2c_master_addressing(VL53_IIC, dev_addr, I2C_TRANSMITTER);/* 发送地址与写指令 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_ADDSEND));/* 等待ADDSEND置位 */	
	i2c_flag_clear(VL53_IIC, I2C_FLAG_ADDSEND);/* 清除ADDSEND标志位 */
	
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	i2c_data_transmit(VL53_IIC, (uint8_t)((reg_addr & 0xff00) >> 8));/* 发送高8位寄存器地址 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	i2c_data_transmit(VL53_IIC, (uint8_t)(reg_addr & 0x00ff));/* 发送低8位寄存器地址 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	while(i < len)/* 循环发送需要写入的数据 */
	{
		i2c_data_transmit(VL53_IIC, *ptr);/* 发送数据缓冲区指针指向的数据 */
		while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
		ptr++;
		i++;
	}
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_BTC));/* 等待最后一个字节发送完成 */
	i2c_stop_on_bus(VL53_IIC);/* 生成停止信号 */
	
	return 0;
}

/*
* 功能	从设备读取请求的字节数,用于对接platform.c中相关函数
* 参数	dev_addr:	7位设备地址
*		reg_addr:	16位寄存器地址
*		*pdata:	数据缓冲区指针,用于存储读出的数据
*		len:		数据长度	
* 返回	操作是否成功
*/
int8_t vl53_readBytes(uint8_t dev_addr, uint16_t reg_addr, uint8_t *pdata, uint32_t len)
{
	uint32_t i = 0;
	uint8_t *ptr = pdata;
	
	i2c_start_on_bus(VL53_IIC);/* 生成起始信号 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_SBSEND));/* 等待SBSEND标志位置位 */
	
	i2c_master_addressing(VL53_IIC, dev_addr, I2C_TRANSMITTER);/* 发送地址与写指令 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_ADDSEND));/* 等待ADDSEND置位 */	
	i2c_flag_clear(VL53_IIC, I2C_FLAG_ADDSEND);/* 清除ADDSEND标志位 */	
	
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	i2c_data_transmit(VL53_IIC, (uint8_t)((reg_addr & 0xff00) >> 8));/* 发送高8位寄存器地址 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	i2c_data_transmit(VL53_IIC, (uint8_t)(reg_addr & 0x00ff));/* 发送低8位寄存器地址 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_TBE));/* 等待发送缓冲区清零 */
	
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_BTC));/* 等待最后一个字节发送完成 */
	i2c_stop_on_bus(VL53_IIC);/* 生成停止信号 */
	
	i2c_start_on_bus(VL53_IIC);/* 再次生成起始信号 */
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_SBSEND));/* 等待SBSEND标志位置位 */
	
	i2c_master_addressing(VL53_IIC, dev_addr, I2C_RECEIVER);/* 发送地址与读指令 */
	if(SET == i2c_flag_get(VL53_IIC, I2C_FLAG_RBNE))
		i2c_data_receive(VL53_IIC);/* 读取接收缓冲区的数据以清空接收缓冲区 */	
	while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_ADDSEND));/* 等待ADDSEND置位 */
	i2c_flag_clear(VL53_IIC, I2C_FLAG_ADDSEND);/* 清除ADDSEND标志位 */		
	
	while(i < len)
	{
		if(i == len - 1)
			i2c_ack_config(VL53_IIC, I2C_ACK_DISABLE);/* 在接收最后一个数据前失能应答发送功能 */
		
		while(RESET == i2c_flag_get(VL53_IIC, I2C_FLAG_RBNE));/* 等待接收缓冲区收到数据 */
		*ptr = i2c_data_receive(VL53_IIC);/* 读取接收缓冲区的数据 */
		
		ptr++;
		i++;
	}
	i2c_stop_on_bus(VL53_IIC);/* 生成停止信号 */
	i2c_ack_config(VL53_IIC, I2C_ACK_ENABLE);/* 在接收完成后重新使能应答发送功能 */

	return 0;
}

vl53_iic.h

#ifndef __VL53L1_IIC_H__
#define __VL53L1_IIC_H__

#include "gd32f4xx.h"

void vl53_IICinit(void);/* IIC初始化 */
int8_t vl53_writeBytes(uint8_t dev_addr, uint16_t reg_addr, uint8_t *pdata, uint32_t len);/* 写入任意个字节 */
int8_t vl53_readBytes(uint8_t dev_addr, uint16_t reg_addr, uint8_t *pdata, uint32_t len);/* 读取任意个字节 */

#endif

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值