STM32 IIC协议基础概念
@TOC
前言
本篇文章将带大家学习IIC通信协议的一些基础概念和使用。
一、IIC协议介绍
I2C(Inter-Integrated Circuit),通常也称为IIC(Inter-IC),是一种串行通信协议,用于在集成电路之间进行数据传输。它是由飞利浦半导体(现在的恩智浦半导体)开发的,并且在各种芯片和模块中被广泛采用。I2C协议的设计旨在简化芯片之间的通信,使得多个芯片可以通过共享同一条总线来交换信息。
以下是I2C协议的基本特点和工作原理:
总线架构:
I2C使用两条线进行通信:串行数据线(SDA)和串行时钟线(SCL)。
SDA用于传输数据,而SCL则用于同步时钟信号,指示何时可以读取或写入数据。
主从结构:
在I2C通信中,设备分为主设备(Master)和从设备(Slave)。
主设备负责发起通信并控制总线的访问,而从设备则响应主设备的请求。
起始和停止条件:
通信开始时,主设备发送起始条件(Start),即将SDA从高电平切换到低电平时,同时保持SCL为高电平。
通信结束时,主设备发送停止条件(Stop),即将SDA从低电平切换到高电平时,同时保持SCL为高电平。
在通信过程中,每个数据传输都以起始和停止条件作为边界。
地址传输:
在每次通信开始时,主设备首先发送目标设备的地址。
地址包括7位或10位,取决于I2C设备的寻址模式。
对于每个从设备,必须分配一个唯一的地址,以便主设备可以识别和访问它。
数据传输:
在发送完目标设备的地址后,主设备可以选择读取数据或向设备写入数据。
数据传输是以字节为单位进行的,每个字节的传输都会收到从设备的应答信号(Acknowledge)。
时钟同步:
时钟同步是通过SCL线实现的,主设备控制时钟信号的频率和节奏。
从设备在SCL线上接收时钟信号,并在适当的时候进行数据传输。
多主机操作:
I2C允许多个主设备共享同一条总线,但是在同一时间只能有一个主设备在操作。
多主机操作需要对总线进行仲裁(Arbitration),以确保每个主设备的请求得到正确的响应。
总的来说,I2C是一种简单而灵活的串行通信协议,适用于连接多个设备,如传感器、存储器、显示器等,以实现各种应用,如嵌入式系统、物联网设备等。
二、IIC硬件框图和程序层次
(以下图片来自百问网)
我们先来看一个IIC的硬件框图操作OLED屏幕。
STM32的内部有IIC控制器,STM32通过IIC控制器和SSD1306 OLED屏幕驱动来给屏幕发送数据,当屏幕接收到数据时就可以将数据显示出来。
程序结构由四部分组成:
1.应用程序
2.库函数也就是我们封装好的OLED显示屏操作函数
3.OLED驱动程序(根据SSD1306数据手册编写)
4.I2C控制器驱动(STM32 HAL库中IIC的操作函数)
三、IIC协议
1.IIC协议通信流程
这里的话就不多讲解这个IIC的通信流程,大家可以看下面的这篇文章。
IIC协议通信流程
2.IIC的引脚为什么需要加入上拉电阻
我们在IIC的框图中就可以知道IIC的引脚是需要接入一个上拉电阻的。
-
开漏(Open-Drain)/开集(Open-Collector)输出
I2C总线上的设备通常使用开漏(对于MOS技术)或开集(对于双极性技术)输出来驱动SDA和SCL线。这意味着设备可以将总线拉低(连接到地),但不能直接将总线拉高。要将线拉高,需要通过外部电阻(上拉电阻)来完成,这些电阻连接到高电平电源(通常是VCC)。 -
逻辑电平的创建
通过使用上拉电阻,当总线上没有任何设备试图将线拉低时,总线自然会被拉到高电平状态。这样就可以创建稳定的逻辑高电平和低电平,确保I2C通信的可靠性。 -
多主设备支持
I2C允许多个主设备存在于同一个总线上。上拉电阻确保了在任何给定时间,只要没有设备主动将总线拉低,总线就会保持在高电平状态。这样的设计允许任何设备可以在任何时间检测并开始通信,而不会干扰到总线上其他的设备。 -
防止总线冲突
在I2C通信中,如果两个设备同时尝试通信,可能会导致总线冲突(比如,一个设备试图发送高电平,而另一个设备同时发送低电平)。上拉电阻确保在这种情况下,总线能够安全地默认到高电平状态,同时提供一种机制(通过检测总线电平)来识别和解决冲突。 -
确定上拉电阻的值
上拉电阻的值不是随意选择的,它需要根据总线的电容、所需的通信速率以及总线上连接的设备数量来计算。电阻值太低会导致功耗增加和电源负载过大,而电阻值太高则可能无法在高速通信时有效地将总线拉到高电平状态,影响信号的质量和可靠性。
上拉电阻在I2C通信中扮演着至关重要的角色,它们确保了总线的稳定和设备间的可靠通信。
3.IIC的引脚为什么需要配置为开漏输出
允许多主设备: I2C支持多个主设备同时连接到同一总线上。通过将引脚配置为开漏输出,任何设备都可以将线拉低(Ground),但不能直接将线拉高(VCC)。这样,当多个主设备同时尝试发送数据时,如果有一个设备将线拉低,其他设备就能感知到总线被占用,从而避免冲突。
下面列出一个真值表来说明上面的功能,假设有两个设备A和B:
1.当A和B都输出1时,因为是开漏输出截止,所以这个时候SDA接到上拉电阻表现为高电平。
2.当A输出为0时,B输出为1,SDA输出的电平是0,因为此时开漏输出可以输出低电平,SDA此时被拉低。
3.这一种情况和第二种情况类似
4.当A和B都输出为0的时候SDA也输出为0
那么这样的话一旦有一个主设备想要输出低电平占用SDA线,那么SDA线就会表现为低电平,此时就可以避免冲突。
另一个重要原因是防止器件烧毁。在推挽输出模式下,引脚可以输出逻辑高电平和逻辑低电平,这样如果两个设备同时尝试将总线拉到不同的电平(一个设备拉高,另一个设备拉低),可能会导致电流直接从一个设备流向另一个设备,形成短路,从而损坏其中一个设备。
通过将引脚配置为开漏输出,设备只能拉低总线,而不能直接拉高总线。上拉电阻将总线拉高,当没有设备拉低时,总线保持在逻辑高电平。这种设计防止了推挽输出模式下的短路和过大电流的流动,从而降低了器件损坏的风险。因此,配置为开漏输出是一种更安全的设计选择,能够有效保护设备免受损坏。
四、STM32 IIC硬件结构
在写入数据时将数据写入IIC控制器的数据寄存器,写入数据后数据移位寄存器会将数据发送到SDA数据线。
当读取数据的时候,数据从SDA从传输进来,放入移位寄存器中,移位寄存器将数据放入数据寄存器中并且读取出来。
通过配置I2C_CR2寄存器可以配置IIC的时钟源:
通过配置I2C_CCR寄存器可以来配置I2C高低电平的时间:
(I2C_TRISE) 寄存器的作用是控制I2C总线上拉电阻的上升时间。这个时间是在I2C总线由逻辑低电平转变为逻辑高电平时的上升时间。上升时间的设定对于I2C通信的稳定性和性能至关重要。
配置I2C_CR1中的STOP和START位可以产生起始信号和停止信号。
总结
本篇文章主要讲解了IIC协议的基础概念,下篇文章将带大家来学习
- 点赞
- 收藏
- 关注作者
评论(0)