1. 引言
I2C(Inter-Integrated Circuit,集成电路总线)是一种由飞利浦公司(现恩智浦半导体)在 1980 年代开发的同步、多主从、串行、半双工通信总线协议。它以其简洁的硬件接口(仅需两根线)、支持多设备连接以及灵活的通信速率等优点,在嵌入式系统、传感器网络、EEPROM、实时时钟(RTC)等场景中得到了广泛应用。本文将深入剖析 I2C 协议的工作原理、通信时序、寻址方式,并通过实战代码示例,帮助读者全面掌握这一经典总线协议。
2. I2C 总线物理层与信号
I2C 总线仅由两根双向开漏(Open-Drain)线构成:
- SDA(Serial Data Line):串行数据线,用于传输数据。
- SCL(Serial Clock Line):串行时钟线,由主设备产生,用于同步数据位传输。
由于采用开漏输出,总线需要外接上拉电阻(通常为 4.7 kΩ 或 10 kΩ)至电源电压(VCC)。这种设计允许多个设备“线与”(Wire-AND),任何设备都可以将总线拉低(输出 0),而释放总线(输出 1)则依靠上拉电阻将电平拉高。
总线电平:
- 逻辑低电平(0):电压接近 GND。
- 逻辑高电平(1):电压接近 VCC(由外部上拉电阻决定)。
3. I2C 协议通信时序详解
一次完整的 I2C 数据传输遵循严格的时序,由主设备(Master)发起和控制。
3.1 起始(START)与停止(STOP)条件
- 起始条件(S):在 SCL 为高电平期间,SDA 线上产生一个由高到低的下降沿。这标志着一次传输的开始,并唤醒总线上所有从设备。
- 停止条件(P):在 SCL 为高电平期间,SDA 线上产生一个由低到高的上升沿。这标志着一次传输的结束,总线进入空闲状态。
3.2 数据传输与应答
数据传输以字节(8 位)为单位,高位(MSB)先发。每个字节传输后,接收方必须发送一个应答(ACK)或非应答(NACK)位。
- 数据位传输:主设备在 SCL 低电平时改变 SDA 数据,在 SCL 高电平时,SDA 数据必须保持稳定,供接收方采样。
- 应答位(ACK/NACK):在第 9 个时钟脉冲(即字节传输后的第一个时钟)期间,发送方释放 SDA 线(输出高)。接收方若成功接收该字节,则在此周期内将 SDA 拉低,作为应答(ACK);若接收失败或希望终止传输,则保持 SDA 为高,作为非应答(NACK)。主设备在发送数据后,需要检测从设备的 ACK;从设备在接收主设备发送的数据后,也需要发送 ACK。
4. I2C 设备寻址
I2C 采用 7 位或 10 位地址寻址。7 位地址是最常用的模式,可寻址 112 个设备(地址 0x00 到 0x07 和 0x78 到 0x7F 为保留地址)。
- 7 位地址帧格式:主设备在起始条件后,立即发送一个字节。这个字节的高 7 位是从设备地址,最低位(LSB)是读写位(R/W#)。
- 0:表示主设备将要向从设备写入数据(Write)。
- 1:表示主设备将要从从设备读取数据(Read)。
例如,向地址为 0x50(二进制 1010000)的设备写入数据,主设备发送的地址字节为0xA0(1010000 + 0 = 10100000)。
从地址为 0x50 的设备读取数据,主设备发送的地址字节为0xA1(1010000 + 1 = 10100001)。
5. 典型通信流程示例
5.1 主设备向从设备写入数据
- 主设备发送起始条件(S)。
- 主设备发送从设备地址 + 写位(0)。
- 从设备返回应答(ACK)。
- 主设备发送数据字节 1。
- 从设备返回应答(ACK)。
- …(重复步骤 4-5,发送更多数据)
- 主设备发送停止条件(P)。
5.2 主设备从从设备读取数据
- 主设备发送起始条件(S)。
- 主设备发送从设备地址 + 读位(1)。
- 从设备返回应答(ACK)。
- 从设备发送数据字节 1。
- 主设备返回应答(ACK)(若还需读)或非应答(NACK)(若读取结束)。
- …(重复步骤 4-5,读取更多数据)
- 主设备发送停止条件(P)。
5.3 复合格式(写入后读取)
常用于先发送寄存器地址,再读取该地址数据的传感器。
- 主设备发送起始条件(S)。
- 主设备发送从设备地址 + 写位(0)。
- 从设备 ACK。
- 主设备发送寄存器地址字节。
- 从设备 ACK。
- 主设备发送重复起始条件(Sr)(即不发送停止条件,直接发起新的起始条件)。
- 主设备发送从设备地址 + 读位(1)。
- 从设备 ACK。
- 从设备发送数据,主设备 ACK/NACK。
- 主设备发送停止条件(P)。
5.4 I2C 通信时序图
为了更直观地理解 I2C 协议的时序,下面用时序图展示一个主设备向从设备写入一个字节数据(地址+数据)的完整过程:
时序图说明:
- IDLE(空闲状态):从 Stop 到 Start 的状态,此时 SCL 和 SDA 均为高电平。
- BUSY(忙状态):从 Start 到 Stop 的状态,表示总线正在进行数据传输。
- Start(起始条件):SCL 为高电平时,SDA 由高电平变成低电平,标志传输开始。
- Stop(停止条件):SCL 为高电平时,SDA 由低电平变成高电平,标志传输结束。
- ACK(应答):接收信息的设备驱动 SDA 为低电平,告知发送设备接收数据正常。
- S-T(Slave-Transmitter):从设备发送信息,主设备接收信息。
- M-T(Master-Transmitter):主设备发送信息,从设备接收信息。
该图清晰地展示了 I2C 协议中起始、停止、数据位传输和应答位的严格时序关系,是理解和调试 I2C 通信的重要参考。
时序图详细讲解:
上图展示了一个典型的 I2C 主设备向从设备写入一个字节数据的完整时序过程。我们可以从左到右,结合时间轴和信号线变化来理解:
空闲状态 (IDLE):在传输开始前,SCL(时钟线)和 SDA(数据线)均被上拉电阻拉至高电平(逻辑1),总线处于空闲、可用的状态。
起始条件 (Start Condition, S):主设备在 SCL 为高电平期间,将 SDA 线从高电平拉低,产生一个下降沿。这个独特的信号组合(SCL高,SDA由高变低)被总线上所有从设备识别为一次传输的开始,并唤醒它们准备接收地址。
地址帧传输 (Address Frame):起始条件后,主设备开始发送第一个字节。这个字节包含7位从设备地址(图中以 A6, A5, …, A0 表示)和1位读写控制位(R/W#)。对于写操作,该位为0。
- 数据有效性:在 SCL 为低电平期间,主设备可以改变 SDA 线上的数据位(置高或拉低)。当 SCL 变为高电平时,SDA 上的数据必须保持稳定,此时从设备会采样 SDA 线上的值。每个数据位都遵循这个“低变高稳”的规则。
- 位顺序:数据传输是高位(MSB)先发,即先发送地址的最高位 A6。
应答位 (Acknowledge Bit, ACK):在发送完8位(7位地址+1位读写位)后,主设备会在第9个时钟周期释放 SDA 线(即输出高电平,由上拉电阻拉高),并将总线控制权暂时交给目标从设备。
- 如果总线上存在地址匹配的从设备,它会在第9个时钟周期内将 SDA 线主动拉低,作为应答信号(ACK),告知主设备“地址已识别,准备就绪”。
- 如果地址不匹配或从设备故障,SDA 线将保持高电平,即非应答(NACK),主设备应终止传输。
数据帧传输 (Data Frame):收到从设备的 ACK 后,主设备继续发送数据字节。图中示例发送了一个8位数据(D7, D6, …, D0)。数据位的传输和应答机制与地址帧完全相同。
再次应答 (ACK for Data):从设备成功接收数据字节后,同样在第9个时钟周期将 SDA 拉低,发出 ACK 信号。
停止条件 (Stop Condition, P):数据传输结束后,主设备需要释放总线。停止条件的定义为:在 SCL 为高电平期间,SDA 线产生一个由低到高的上升沿。此后,SCL 和 SDA 均恢复高电平,总线再次进入空闲状态,等待下一次起始条件。
关键点总结:
- 主从角色:在整个写操作中,SCL 时钟始终由主设备产生和控制。SDA 数据线主要由主设备驱动,但在两个应答位(第9个时钟)期间由接收方(从设备)驱动。
- 同步与采样:数据的变化发生在 SCL 为低时,数据的采样发生在 SCL 为高时,这保证了信号的同步和稳定。
- 握手机制:每个字节后的 ACK/NACK 位是重要的握手机制,确保了通信的可靠性。没有收到 ACK 通常意味着通信失败。
- 总线状态:
Start和Stop条件严格定义了总线“忙”(BUSY)周期的开始与结束。在Start之后、Stop之前,总线处于占用状态。
通过这张时序图,可以清晰地看到 I2C 协议如何通过简单的两根线,实现包括寻址、数据传输和确认在内的完整通信流程,这也是其成为嵌入式系统经典总线协议的原因之一。若想观看更详细的视频讲解,可前往 B 站视频:I2C 通信协议详解。
7. I2C 协议高级特性与注意事项
7.1 时钟拉伸(Clock Stretching)
从设备可以通过在应答位或数据位期间将 SCL 线拉低并保持,来暂停主设备的时钟,从而为自己争取更多的处理时间。主设备必须检测并等待 SCL 被从设备释放后才能继续。这是 I2C 支持不同速度设备共存的关键机制。
7.2 总线仲裁(Arbitration)
当多个主设备同时尝试启动传输时,会进行仲裁。仲裁机制基于“线与”特性:只要有一个设备输出 0,总线就是 0。主设备在发送地址或数据时,会同时监听 SDA 线。如果发现自己发送的是 1,但检测到总线为 0,则说明有其他主设备赢得了总线,该设备应立即退出竞争,转为从设备监听模式。
7.3 通信速率
- 标准模式(Standard-mode):100 kbit/s
- 快速模式(Fast-mode):400 kbit/s
- 快速模式+(Fast-mode Plus):1 Mbit/s
- 高速模式(High-speed mode):3.4 Mbit/s
通信速率由主设备的 SCL 频率决定,所有设备必须支持主设备设定的速率或更低速率。
7.4 注意事项
- 上拉电阻:阻值需根据总线电容和电源电压计算选择,通常在 4.7 kΩ 到 10 kΩ 之间。阻值过大会导致上升沿过慢,通信不可靠;阻值过小会导致功耗增加。
- 总线电容:总线总电容(线缆电容+设备引脚电容)不能超过 400 pF(标准模式),否则信号完整性会变差。
- 地址冲突:设计系统时需注意从设备地址不能冲突,许多设备可通过外部引脚配置部分地址位。
8. 总结
I2C 协议以其极简的硬件连接和灵活的软件控制,成为嵌入式系统内部芯片间通信(Inter-IC Communication)的事实标准。掌握其起始/停止条件、数据/应答时序、7/10 位寻址以及复合传输格式,是进行嵌入式开发和硬件调试的基础。在实际应用中,还需结合具体器件的时序要求和电气特性,并善用逻辑分析仪等工具进行调试,才能构建稳定可靠的 I2C 通信系统。