STM32通信协议学习--I2C通信(了解)
好的,我们来详细解读一下I2C通信。这是一个在嵌入式系统中极其重要且常用的通信协议,尤其是在连接多个传感器、存储器等外设时。
一、I2C 是什么?
I2C,全称Inter-Integrated Circuit,中文译为集成电路总线,是由飞利浦公司开发的一种简单的同步、半双工、串行、低速的通信总线。
同步:通信双方使用同一个时钟信号(SCL)来同步数据。
半双工:数据可以在两个方向上传输,但不能同时进行。
串行:数据一位一位地依次传输。
多主从:一条总线上可以连接多个主设备(Master)和多个从设备(Slave)。
二、I2C 的核心特点与硬件结构
I2C总线最大的优点在于硬件连接极其简单,只需要两根线,非常适合板内短距离、低速的设备间通信。
1. 物理连接(只需要两根线)
| 线名称 | 全称 | 作用 | 备注 |
|---|---|---|---|
| SCL | Serial Clock | 时钟线,由主设备产生,用于同步数据。 | 两条线都是开源 drain或集电极开路结构,因此必须接上拉电阻。 |
| SDA | Serial Data | 数据线,用于传输实际的数据。 |
为什么需要上拉电阻?
因为I2C的物理结构是开源 drain。当总线空闲时,晶体管关闭,上拉电阻将SDA和SCL线拉至高电平;当需要输出低电平时,晶体管导通,将线拉至低电平。这种结构实现了"线与"功能,即只要有一个设备输出低电平,整条线就是低电平,这方便了时钟同步和仲裁。
2. 地址与从设备选择
在SPI通信中,每个从设备需要一根单独的片选线。而I2C通过地址来寻址,大大节省了引脚资源。
从设备地址:每个I2C从设备都有一个7位或10位的唯一地址(7位地址更常见)。例如,BME280气压传感器的地址可能是
0x76。寻址过程:主设备在发起通信时,首先在SDA线上发送一个目标从设备的地址字节,总线上所有的从设备都会收到这个地址,并与自己的地址进行比较。只有地址匹配的从设备才会响应主设备。
三、I2C 的通信协议与时序
理解I2C的通信协议,关键在于掌握几个关键的信号和数据传输单元。
1. 关键信号
| 信号 | 描述 | 时序图关键点 |
|---|---|---|
| 起始条件 | 当SCL为高电平时,SDA出现一个下降沿。表示一次传输的开始。 | SDA: 高 -> 低SCL: 高 |
| 停止条件 | 当SCL为高电平时,SDA出现一个上升沿。表示一次传输的结束。 | SDA: 低 -> 高SCL: 高 |
| 数据有效性 | 只有在SCL为低电平期间,SDA上的数据才允许改变。在SCL的上升沿,SDA上的数据被采样,视为有效数据。 | 改变数据时 SCL: 低读取数据时 SCL: 上升沿 |
| 应答信号 | 接收器在成功接收到8位数据(一个字节)后,需要在第9个时钟脉冲期间拉低SDA,作为应答。 | 第9个时钟周期 SDA: 低 |
| 非应答信号 | 如果接收器没有拉低SDA(即SDA为高),则表示非应答,通常意味着传输失败或结束。 | 第9个时钟周期 SDA: 高 |
2. 完整的数据传输流程
一次完整的I2C通信序列由起始条件、从机地址帧、读写位、应答位、数据帧、停止条件组成。
1. 起始起始条件2. 发送地址与写命令3. 发送数据loop[发送N个字节]4. 停止条件START Condition (S)Send Slave Address (7 bits) + Write Bit (0)ACK (应答)Send Data Byte (8 bits)ACK (应答)STOP Condition (P)
从设备地址帧详解:
主设备发送的第一个字节由两部分组成:
高7位:从设备地址。
最低位:读写位。
0:表示主设备要写入数据到从设备。
1:表示主设备要读取从设备的数据。
读数据流程:
读取数据的过程稍复杂一些,它通常以一个写操作开头(用于告诉从设备要读取哪个寄存器地址),然后重新起始条件,再开始读操作。在读取数据的最后,主设备需要发送一个非应答信号,然后停止。
伪代码流程:读取一个I2C设备
1. 发送 START。
2. 发送 从设备地址 + 写(0)。
3. 等待 ACK。
4. 发送 要读取的寄存器地址(8位)。
5. 等待 ACK。
6. 发送 Repeated START(重新起始条件)。
7. 发送 从设备地址 + 读(1)。
8. 等待 ACK。
9. 读取从设备返回的数据字节(8位)。
10. 主设备发送 NACK(非应答),表示读取结束。
11. 发送 STOP。
四、在STM32中使用I2C
在STM32中,你可以通过两种方式使用I2C。
1. 硬件I2C
STM32内部有专门的I2C外设控制器。你只需要配置好相应的GPIO(将引脚复用为I2C功能)、初始化I2C外设(时钟速度、模式等),然后就可以使用HAL库或LL库提供的API函数进行通信。
HAL库常用函数:
HAL_I2C_Master_Transmit():主设备发送数据。HAL_I2C_Master_Receive():主设备接收数据。HAL_I2C_Mem_Write():向从设备的指定存储器地址写入数据(非常常用,相当于自动完成了“写地址-写寄存器地址-写数据”的流程)。HAL_I2C_Mem_Read():从从设备的指定存储器地址读取数据(非常常用)。
优点:效率高,不占用CPU时间。
缺点:STM32的硬件I2C在某些型号或早期固件库中可能存在bug,配置和使用相对复杂。
2. 软件模拟I2C
如果硬件I2C出现问题,或者你使用的引脚没有I2C硬件功能,你可以用任意两个GPIO引脚来模拟I2C的时序。
你将SDA和SCL配置为推挽输出。
通过代码控制这两个引脚的高低电平,并严格按照I2C的时序(起始、停止、应答等)来模拟整个通信过程。
优点:灵活,不受引脚限制,绝对可靠。
缺点:占用CPU资源,速度不如硬件I2C快。
五、常见问题与调试技巧
通信失败:
检查上拉电阻:没有上拉电阻或阻值过大(导致上升沿太慢)是最常见的问题。通常使用4.7kΩ的电阻。
检查地址:确认从设备地址是否正确(注意数据手册里是7位地址,而HAL库有时需要左移一位)。很多传感器可以通过改变引脚电平来修改地址。
用逻辑分析仪:这是调试I2C的终极武器,可以清晰地看到起始、地址、数据、应答等每一个波形,快速定位问题。
速度:
I2C标准模式速度为100kbps,快速模式为400kbps,高速模式可达3.4Mbps。根据你的从设备支持的速度进行配置。
总结
| 特性 | I2C |
|---|---|
| 数据线数量 | 2根(SDA, SCL) |
| 通信类型 | 同步,半双工 |
| 拓扑结构 | 多主从,总线式 |
| 寻址方式 | 软件地址(7位/10位) |
| 优点 | 硬件简单,引脚资源占用少,支持多主从 |
| 缺点 | 速度相对较慢,协议稍复杂,需要上拉电阻 |
