STM32——通过GPIO来模拟I2C

本文介绍了I2C总线的基本概念和通信协议,重点讲解了如何使用STM32的GPIO模拟I2C,包括起始信号、停止信号、应答信号的生成,以及发送和接收数据的步骤。通过GPIO模拟I2C适用于硬件I2C不稳定或不支持的情况。
摘要由CSDN通过智能技术生成

I2C总线是一种同步、双向、半双工的串行总线,通信双方只需要两条线就可以实现通信,非常方便。

1. 硬件I2C和软件I2C

I2C有硬件I2C和软件I2C之分,简单介绍如下:

  • 硬件I2C:即对应芯片上的I2C外设,速度比软件I2C快,并且可以使用DMA,但有些单片机的I2C
    外设不太稳定,就例如STM32上的I2C就有bug。
  • 软件I2C:用程序来控制IO口输出高低电平,模拟I2C协议的时序,从而实现I2C协议。相对于硬件I2C,软件I2C一般较稳定,但速度较慢,不过软件I2C可以模拟在任何管脚上,不像硬件I2C只有固定管脚。

2. I2C协议

在模拟I2C之前,得了解I2C总线的通讯过程,不然只会无从下手。

I2C总线的传输一个字节的过程概括如下:
在总线空闲(即SDA线和SCL线处于高电平,在I2C中要通过上拉电阻才能实现高电平)时,发送端产生起始信号,表示本次传输的开始,之后发送一个字节的数据(该数据总是高位在前的),然后等待接收端的应答信号或非应答信号,应答信号和非应答信号分别表示接受端接受到数据和没接收到数据,最后产生停止信号,表示本次传输的结束。

有几个要注意的点:

  1. 除了起始信号和停止信号,其他信号的电平状态切换只能在SCL线处于低电平时进行;而且在SCL线处于高电平时,SDA线必须保持稳定的电平状态。
  2. I2C协议支持的通讯速度在100kHz到400kHz之间,如果是模拟I2C,要保证所写的延时函数延时的时间尽量在频率对应的范围之内。

接下来,来看看各信号的定义:

  • 起始信号和停止信号
    在这里插入图片描述
    起始信号:在SCL线高电平时,SDA线从高电平向低电平切换
    停止信号:在SCL线高电平时,SDA线从低电平向高电平切换

  • 应答信号和非应答信号
    在这里插入图片描述
    在传输一个byte数据后,在第9个bit对的脉冲高电平期间,SDA线若保持高电平,即为应答信号;SDA线若保持低电平,即为非应答信号。

3. 通过IO口模拟I2C

那么下来就是如何通过IO口来模拟I2C了,话就不多说,直接开冲!

既然模拟I2C是通过IO来模拟的,那首先肯定是要对相关GPIO进行初始化的,代码如下:

void I2C_GPIO_Init()
{
   
	GPIO_InitTypeDef I2C_GPIO_InitStruct;

	//打开数据信号线SDA和时钟信号线SCL的时钟
	RCC_APB2PeriphClockCmd(I2C_SDA_CLK|I2C_SCL_CLK, ENABLE);
	
	//SDA线对应IO口的配置
	I2C_GPIO_InitStruct.GPIO_Pin = I2C_SDA_PIN;
	I2C_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	I2C_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(I2C_SDA_PORT, &I2C_GPIO_InitStruct);
	
	//SCL线对应IO口的配置
	I2C_GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN;
	I2C_GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	I2C_GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值