一、IIC 简介
1.1 IIC 简介
I²C ( Inter-Integrated Circuit,总线制集成电路) 是由 Philips (现NXP) 在 1980 年代初期提出的一种 串行通信总线标准 ,用于微控制器与外设芯片之间的短距离通信。
它以两根信号线就能连接多个设备,具有结构简单、成本低、扩展方便等优点,是嵌入式系统中最常见的通信接口之一。
1.2 IIC 特性
1.2.1 特性
- 通讯线数:2 根:SCL (时钟线)、SDA (数据线)
 - 通讯方式:半双工、主从式
 - 电气结构:开漏 (Open-Drain) + 上拉电阻
 - 通讯举例:一般几十厘米以内 (视电容和速率而定)
 - 寻址方式:7 位或 10 位地址,可挂接多个从设备
 - 确认机制:每字节都有 ACK/NACK 确认信号
 - 速率等级:标准模式 100 kbit/s;快速模式:400 kbit/s;高速模式:3.4 Mbit/s;超高速模式:5 Mbit/s (少见)
 
1.2.1 优点
- 仅需两根信号线:只用SCL (时钟) 和 SDA (数据) 两条线即可完成通信,极大节省I/O口和布线。
 - 多主多从结构:支持多个主机和多个从机,具备仲裁机制,可以让不同主机共享同一总线。
 - 地址化通信:每个从设备都有唯一的 7 位或 10 位地址,通过地址寻址,扩展性好。
 - 硬件开销小:设备内部只需简单的接口逻辑,不需要复杂的收发电路。
 - 支持应答机制:每个字节传输后都有 ACK/NACK 确认,提高数据可靠性。
 - 支持热插拔:开漏结构+上拉电阻,使得设备插拔时不会造成总线短路。
 - 支持低速和高速模式:标准模式 (100 kHz) 、快速模式 (400 kHz) 、高速模式 (3.4 MHz) 等,可按需求选择。
 
1.2.2 缺点
- 通信速率较低:即便是高速模式也只有3.4 Mbps,远低于 SPI 等协议。
 - 总线电容限制传输距离:典型总线长度 < 1 m,线越长电容越大,信号边沿衰减严重。
 - 需要上拉电阻 SCL 和 SDA 均为开漏,需要外接上拉电阻,影响功耗与速率。
 - 协议复杂度比 SPI 高:需要起始位、地址位、应答位等控制信号,主机逻辑实现略复杂。
 - 占用总线风险:若从设备或主机异常 (拉低SDA不放),可能导致总线锁死。
 - 电气特性不兼容:各器件需在相同电平 (3.3 V或5 V) 下工作,否则需电平转换。
 
二、物理层
2.1 物理层定义
物理层是 OSI 模型的第一层 (最底层),它负责 在物理媒介上发送和接收原始比特流,也就是把 0 和 1 转换成实际可传输的信号。它完全和数据内容无关,只关注 信号如何在介质上传播。
物理层的主要定义有:
- 电气特性:电压幅度、逻辑电平、信号极性 (高电平/低电平表示 0/1)
 - 传输速率:比特率 (bps) 或以太网的 (Mbps) 等
 - 物理拓扑:点对点 (串口) 、总线 (CAN)、星型 (以太网) 等
 - 传输模式 :单工、半双工、全双工
 
2.2 连线定义
2.2.1 连线定义
其连线定义非常简单,只需要两根信号线就能实现主从通信。下面详细说明:
|----------|---------------|---------------------|
| 引脚名称 | 方向 (相对主机) | 功能说明            |
| SCL      | 输出            | 时钟线,由主设备产生,用于同步数据传输 |
| SDA      | 双向            | 数据线,在主从设备之间传输数据     |

2.2.2 拓扑结构
因地址限制,7 位地址模式最多有 128 个设备,保留 7 个地址:
|--------------|--------------------|
| 地址范围     | 用途             |
| 0x00         | 通用呼叫(General Call) |
| 0x01 ~ 0x02 | 保留(CBUS,HSM)       |
| 0x03 ~ 0x07 | 未来规范保留             |
| 0x78 ~ 0x7F | 用于 10-bit 地址扩展     |
因此在 7 位模式下可用地址约为 112 个,但是在 10 位地址下却有 1024 个地址。
但是 IIC 是开漏总线结构,总线电容 (所有设备 SDA、SCL 并联后的总电容) 会影响通信速度和稳定性。每个器件的 SDA/SCL 引脚大约有 10--20pF 电容,加上线缆、电路板走线电容,总线电容很快就上升,因此较为推荐的从机数量为:
|----------------------|------------|-----------------|
| 速率模式             | 最大总线电容 | 实际可连接数量(估算) |
| Standard (100 kHz)   | 400 pF     | 数十个设备 (取决于引脚电容) |
| Fast (400 kHz)       | 400 pF     | 10~20 个设备较稳    |
| Fast+ (1 MHz)        | 550 pF     | 一般不超过 10 个设备    |
| High Speed (3.4 MHz) | 550 pF     | 通常 3~5 个设备以内   |

2.3 通讯波形
2.3.1 起始信号与停止信号
起始信号

停止信号

2.3.2 数据波形
这时候,我们已经把整个写操作时序获取到,这样看肯定不清楚,所以我们可以通过时间档位进行放大。时间档位变为 10us 并通过水平偏移操作,放大波形如下:

S 就是经典的起始信号,当 SCL 线为高电平的时候,SDA 从高电平往低电平跳变 发送起始信号之后便是地址和方向组合的一个字节数据,这里就是0xA0。0xA0的由来可以查看一下IIC实验教程。
第九个时钟脉冲高电平期间便是检测应答信号,这里也是检测 IIC 有没有通信成功的地方。假如看到波形是有低电平,那么就证明从机应答了,否则就是没有应答,这时候你就需要检查第一个字节是不是应该发 0xA0。图中第九个时钟脉冲后,SDA 线出现绿色的小尖峰是由于从机发送完应答信号后,会释放 SDA 线,把总线的主动权交还给主机。这是正常现象。现在继续往后分析波形,通过水平偏移,把波形图整体往左移,如下:

这里传输的便是内存地址,前面也提到为地址 10 处,0xA0 即为 10,这里与你发送的是一致的内容,并且后面也能接收到从机返回的应答信号。继续通过水平偏移,查看剩下的波形内容。

这里传输的就是数据内容,通过波形分析,传输的数据为 0x41。'A'的ASCII 码值就是 0x41,发送与实际一致。随后便是从机的应答信号,低电平表示应答,最后便是经典的P停止信号,在SCL线为高电平的时候,数据线从低电平往高电平跳变。以上就是分析IIC波形图的过程。
2.3 通讯距离与速率
|----------------------|-----------|------------|----------------|-----------|
| 通信速率模式           | 标准名称  | 典型速率   | 实际稳定距离(估算) | 应用场景  |
| Standard Mode (SM)   | 标准模式      | 100 kbit/s | ≈ 0.5 ~ 2 米   | 板内、模块间通信  |
| Fast Mode (FM)       | 快速模式      | 400 kbit/s | ≈ 0.3 ~ 1 米   | 板内通信、较短排线 |
| Fast Mode Plus (FM+) | 快速增强模式    | 1 Mbit/s   | ≈ 0.2 ~ 0.5 米 | 传感器模块连接   |
| High Speed Mode (HS) | 高速模式      | 3.4 Mbit/s | < 0.1 米       | 芯片间高速通信   |
| Ultra Fast Mode (UF) | 超高速模式(少用) | 5 Mbit/s   | < 0.1 米       | 单向高速数据采集  |
三、的数据链路层
3.1 数据链路层定义
物理层定义了 0 和 1 的信号形式。数据链路层则提供可靠的数据传输,进行帧的封装、错误检测、流量控制。
- 帧封装:把目标数据封装成一帧 (Frame),加上帧头、帧尾,使接收方能识别帧的起止。
 - 物理寻址:每个链路设备都有一个地址,用于在同一总线中识别发送方和接收方。
 - 差错检测与纠正:CRC、奇偶校验等方式检测 (有时纠正) 比特错误。
 - 流量控制:控制发送速度,防止发送方过快导致接收方缓冲区溢出。
 - 重传控制:通过确认 (ACK) 机制与超时重传,提高传输可靠性。
 
其中 IIC 在数据链路层提供了帧封装、物理寻址、流量控制、重传控制。
3.2 IIC 的数据格式
3.2.1 IIC 固定格式
一帧固定的 IIC 数据格式如下:

|--------|----------|--------|----------|
| 名称 | 符号   | 作用 | 由谁发出 |
| 起始条件   | S        | 通讯开始   | 主机       |
| 地址字节   | A        | 指定目标设备 | 主机       |
| 读写位    | R/W      | 指示方向   | 主机       |
| 应答位    | ACK/NACK | 确认接收状态 | 从机/主机    |
| 数据字节   | D        | 实际内容   | 从机/主机    |
| 停止条件   | P        | 通信结束   | 主机       |
3.2.2 写数据
写数据流程如下:

3.2.3 读数据
在读数据中,我们需要先发送一条读命令,其包括我们希望读的寄存器地址。
之后再次发送一个起始位,这时候就是一条新的命令了,此条命令我们选择读数据帧,这时候从机便把我们的需要的数据发过来了。

为什么IIC的读数据会需要使用两条命令,这么奇怪呢?
因为IIC的数据传输方向由主机发出的 R/W 位决定。
也就是说:
- 当主机发出 写操作 (R/W = 0) 时,数据线 SDA 的驱动权在主机;
 - 当主机发出 读操作 (R/W = 1) 时,SDA 的驱动权交给从机。
 
所以,当我们发送读数据位后,此时 SDA 的驱动权就交给了从设备 (SDA 是单线双向),主机就不能再发送数据了,所以我们使用重复起始信号,也就是两条 IIC 命令进行一次读操作。这是 IIC 对半双工通讯的一种妥协。
3.3 仲裁
仲裁是指多个主设备 (Master) 在同一时间内争夺总线控制权的过程。
IIC 协议允许多个主机同时连接到总线上,而不需要专门的硬件来分配主控权。但是,若多个主机同时发起通信,必须有一种机制来决定哪一个主机会赢得总线的控制权。'
在 IIC 的物理层设计中:
SDA 和 SCL 都是 开漏输出 (open-drain) 或集电极开路 (open-collector)。
这意味着:IIC 器件不能主动输出高电平;
此时,如果有两个设备同时竞争总线,率先拉低的设备会获取总线的控制器,如下图所示,DATA1在 ③ 阶段的总线 被 DATA2 拉低了,此时便失去了仲裁,不再发送数据。
