STM32F103+VL53L0测距(二)

在上一篇文章中,我们讲了VL53L0传感器与MCU之间的硬件连接,以及如何用STM32F103对其寄存器进行读写操作,接下来我们一起学习在STM32F103中如何用它的GPIO口来模拟I2C通信。

对于STM32F103单片机来说,它是自带了硬件 IIC,但是出于使用习惯和程序可移植性考虑,我们一般选择用 IO 口去模拟 I2C 协议。
使用 IO 口模拟 IIC 的好处有三点:
1. 使用 IO 模拟 IIC 协议可以让大家把之前学过的 GPIO 知识再进行深度的理解和扩展;
2. 加深对 IIC 时序流程的认识;
3. 方便移植到 STM32 的任何一个引脚,如再做修改可以移植到其他 MCU 平台。

当然这种方法也存在一些缺点,比如考虑这样一种极端情况,在程序运行时会有执行时
间很长的中断服务函数打断 IIC 时序,造成 IIC 写失败或者读失败。如果存在这种情况,建
议大家在进行 IIC 操作之前关闭全局中断,使用后再打开。

首先,对模拟I2C的I/O管脚进行宏定义,包括SDA线、SCL线管脚的定义等,代码如下:

#define RCC_I2C_PORT 	RCC_APB2Periph_GPIOB		

#define PORT_I2C_SCL	GPIOB		
#define PIN_I2C_SCL		GPIO_Pin_6		

#define PORT_I2C_SDA	GPIOB			
#define PIN_I2C_SDA		GPIO_Pin_7		

#define I2C_SCL_PIN		GPIO_Pin_6			
#define I2C_SDA_PIN		GPIO_Pin_7			


#define I2C_SCL_1()  PORT_I2C_SCL->BSRR = I2C_SCL_PIN			
#define I2C_SCL_0()  PORT_I2C_SCL->BRR = I2C_SCL_PIN				

#define I2C_SDA_1()  PORT_I2C_SDA->BSRR = I2C_SDA_PIN				
#define I2C_SDA_0()  PORT_I2C_SDA->BRR = I2C_SDA_PIN				

#define I2C_SDA_READ()  ((PORT_I2C_SDA->IDR & I2C_SDA_PIN) != 0)	
#define I2C_SCL_READ()  ((PORT_I2C_SCL->IDR & I2C_SCL_PIN) != 0)	

void SetSDA_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = PIN_I2C_SDA;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(PORT_I2C_SDA, &GPIO_InitStructure);
}
void SetSDA_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = PIN_I2C_SDA;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(PORT_I2C_SDA, &GPIO_InitStructure);
}	

接下来便是模拟I2C的初始化函数与时序操作的函数
初始化操作与GPIO初始化基本一致:
1.配置时钟;
2.配置管脚的输入输出模式,其中输出模式最好设为上拉输出;
3.设置管脚。

void bsp_InitI2C(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);	

	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;	
	
	GPIO_InitStructure.GPIO_Pin = PIN_I2C_SCL;
	GPIO_Init(PORT_I2C_SCL, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_I2C_SDA;
	GPIO_Init(PORT_I2C_SDA, &GPIO_InitStructure);
	i2c_Stop();
}
static void i2c_Delay(void)
{
	uint8_t i;
	for (i = 0; i < 30; i++);
}
void i2c_Start(void)
{
	SetSDA_OUT();
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	
	I2C_SCL_0();
	i2c_Delay();
}
void i2c_Stop(void)
{
	SetSDA_OUT();
	I2C_SDA_0();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_1();
	i2c_Delay();
}
void i2c_SendByte(uint8_t _ucByte)
{
	uint8_t i;
	SetSDA_OUT();
	for (i = 0; i < 8; i++)
	{
		if (_ucByte & 0x80)
		{
			I2C_SDA_1();
		}
		else
		{
			I2C_SDA_0();
		}
		i2c_Delay();
		I2C_SCL_1();
		i2c_Delay();
		I2C_SCL_0();
		if (i == 7)
		{
			 I2C_SDA_1(); 
		}
		_ucByte <<= 1;	
		i2c_Delay();
	}
}
uint8_t i2c_ReadByte(void)
{
	uint8_t i;
	uint8_t value;
	SetSDA_IN();
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		I2C_SCL_1();
		i2c_Delay();
		if (I2C_SDA_READ())
		{
			value++;
		}
		I2C_SCL_0();
		i2c_Delay();
	}
	return value;

}
uint8_t i2c_WaitAck(void)
{
	uint8_t re;
	SetSDA_IN();
	I2C_SDA_1();	
	i2c_Delay();
	I2C_SCL_1();	
	i2c_Delay();
	if (I2C_SDA_READ())	
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	I2C_SCL_0();
	i2c_Delay();
	return re;
}
void i2c_Ack(void)
{
	I2C_SDA_0();	
	i2c_Delay();
	I2C_SCL_1();	
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
	I2C_SDA_1();	
}
void i2c_NAck(void)
{
	I2C_SDA_1();	
	i2c_Delay();
	I2C_SCL_1();	
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
}
uint8_t i2c_CheckDevice(uint8_t _Address)
{
	uint8_t ucAck;

	if (I2C_SDA_READ() && I2C_SCL_READ())
	{
		i2c_Start();		
		
		i2c_SendByte(_Address | I2C_WR);
		ucAck = i2c_WaitAck();

		i2c_Stop();			

		return ucAck;
	}
	return 1;	
}

以上便是STM32F103模拟I2C的全部操作。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
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的强大性能和丰富的外设来进行控制和数据处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值