number headings: auto, first-level 2, max 6, 1.1
目录
1 I2C总线标简介
I2C是指Inter-Integrated Circuit,由飞利浦公司制定,其协议标准为UM10204。
除了基础的I2C总线传输外,还有基于I2C总线协议的SMB(System Management Bus)、PMBus(Power Management Bus)、IMPI(ntelligent Platform Management Interface)、DDC(Display Data Channel)和ATCA(Advanced Telecom Computing Architecture)等拓展协议。
此外,还有由MIPI联盟推出的向下兼容I2C的I3C协议,不过不在本文讨论范围内。
2 I2C总线特性
2.1 I2C总线的电气特性规定
- SDA和SCL均为开漏模式。
- SDA和SCL均有一个10K的上拉电阻。
这样设计的好处是当总线上出现电平冲突时,不会有短路情况出现。
且需要注意,I2C与大多数通信协议一样,当其需要传输逻辑 "1" 时,其GPIO其实什么都不需要做(此时GPIO悬空,被上拉电阻拉高)。
该规定使得I2C总线有"线与"特性,即总线上只要有一个设备发出逻辑"0",则总线上的数据就会被定义为逻辑"0"。
2.2 传输的若干基本环节及其时序
本章节仅为传输的若干基本环节及其时序的讲解。不涉及总体的流程。总体流程见下一章节。
2.2.1 SDA与SCL电平变化顺序的基本要求
在I2C协议中,SDA与SCL电平变化顺序主要有以下两种模式:
- 在传输普通数据时,SCL会周期性的输出高电平脉冲,并且在SCL保持为高电平时,SDA不可发生电平变化。

- 在表示I2C控制信息时(即开始信号和结束信号),SCL会保持高电平,并且SDA发生电平变化。
- 当发送开始信号时,SCL保持高电平,同时SDA由高变低。
- 当发送停止信号时,SCL保持高电平,同时SDA由低变高。
2.2.2 开始信号及I2C空闲状态
在开始信号发生之前,SDA和SCL均要保持在高电平,此时I2C为空闲状态。
2.2.3 通用八位数据传输以及ACK/NACK
- 在通用八位数据传输时,SDA先到达目标电平,随后SCL发送一个高电平脉冲。在此环节内,SDA高电平表示1,低电平表示0。
- 重复8次完成一个Byte发送后,数据发送方会释放数据总线,数据接收方会在下一个SCL周期到来前将SDA的电平控制到ACK/NACK的目标电平。
- 上述两步共计9个SCL脉冲完成了一个通用八位数据传输。ACK/NACK具体见下一同级章节。
地址数据和普通八位数据均用此方法传输。
数据先发送高位再发送低位。
2.2.4 应答要求
应答信号的发送时机如上一章节所述,此处不再赘述。
应答信号一共两种:
- ACK应答信号:此时数据接收方会将SDA控制为低电平,表示"数据接收成功,并且期待接收下一字节"
- NACK应答信号:此时数据接收方会将SDA控制为高电平,表示"不再接收更多数据"。
- 应答信号必须由接收方主动发送,且可以不立即ACK。但是从机可以使用I2C时钟延长特性,主动拉低SCL延长该时钟周期,到准备好ACK时再放开。也就是说ACK依旧必定在第九个时钟周期内完成传输,只是该时钟周期可以被从机主动延长。
- 应答信号必须在SCL的某个下降沿后(可以不立即ACK),上升沿前进入低电平,且必须在SCL高电平时长内一直维持低电平。
- 对于上一条,ACK信号必须在其包含的SCL高电平时段内永久保持,无论该高电平时长有多长。这也是I2C死锁的一个来源I2C死锁问题。
2.3 I2C传输的总体流程
通常来说,嵌入式开发框架会同时提供普通的基本环节操作和封装好的数据传输操作,以分别应用于非标准的和标准的I2C硬件模型。
对于标准的I2C硬件模型,其从设备通常会有固定的I2C地址和若干可选的寄存器地址,对于这种标准模型,其读写流程是固定的,具体如下列章节所述。
2.3.1 写入数据
对于8位地址的标准I2C通信模型,其写入数据的流程如下:
- 发送开始信号
- 发送8位的从设备I2C地址
- 等待从机ACK
- 发送要写入的寄存器地址
- 等待从机ACK
- 传送n byte(s)数据,并在:
- 非末尾byte处等待从设备ACK
- 末尾byte不等待从设备ACK,进入环节5
- 发送结束信号
数据包结构如下:
2.3.2 读取数据
对于8位地址的标准I2C通信模型,其读取数据的流程如下:
- 发送开始信号
- 发送8位的从设备I2C地址
- 等待从设备ACK
- 发送要读取的寄存器地址
- 等待从设备ACK
- 重新发送开始信号
- 主设备接收I2C数据,并发送ACK直到数据传输完毕
- 发送结束信号
2.4 I2C的地址位数
I2C支持7位和10位的地址模式,10位的地址模式在I2C传输的第一个字节为 11110${A9}${A8}${R/W}
,第二个字节为 ${A7~A0}
。