2. I2C协议基础:起始条件、停止条件、数据有效性、字节格式、应答机制(ACK/NACK)
I2C(Inter-Integrated Circuit)总线协议由Philips(现NXP)公司开发,是一种同步、多主从、串行通信总线。它仅需两根线——串行数据线(SDA)和串行时钟线(SCL)——即可实现设备间的数据交换。理解其底层信号时序是驱动开发和寄存器配置的基石。本节将逐一解析I2C协议的核心要素。
2.1 总线空闲状态与电气特性
在I2C总线空闲时,主设备必须将SCL和SDA线都释放为高阻态,由上拉电阻拉至高电平(Vdd)。这意味着总线处于“空闲”状态时,两根线均为高电平。
- SDA:数据线,用于传输地址和数据。
- SCL:时钟线,由主设备驱动,用于同步数据传输。
- 上拉电阻:通常为4.7kΩ或10kΩ,确保总线在空闲时处于确定的高电平状态。
驱动提示:在配置I2C控制器寄存器时,需确保GPIO引脚配置为开漏输出(Open-Drain),并正确使能内部或外部上拉电阻。错误的电气配置会导致总线锁死或通信失败。
2.2 起始条件(START Condition)与停止条件(STOP Condition)
所有I2C通信事务都以起始条件开始,以停止条件结束。这两个条件是总线上的特殊信号,用于界定一次完整的传输。
- 起始条件(S):当SCL为高电平时,SDA从高电平切换到低电平。
- 停止条件(P):当SCL为高电平时,SDA从低电平切换到高电平。
关键规则:起始条件和停止条件只能由主设备产生。在驱动中,通常通过操作控制寄存器中的
START 和 STOP 位来生成这些信号。
2.3 数据有效性(Data Validity)
I2C协议规定,在SCL时钟的高电平周期内,SDA线上的数据必须保持稳定。只有在SCL为低电平时,SDA上的数据才允许发生变化。
- 数据采样:从设备在SCL的上升沿或高电平期间对SDA进行采样。
- 数据变化:SDA的状态变化必须在SCL为低电平时完成。
2.4 字节格式(Byte Format)
I2C总线上的数据以字节(8位)为单位进行传输。每个字节传输完成后,必须跟随一个应答位(ACK/NACK)。数据传输时,高位(MSB)在前,低位(LSB)在后。
- MSB First:总是先传输最高有效位(bit 7)。
- 字节数:每次传输的字节数没有限制,但每个字节后都需要一个应答位。
- 地址字节:起始条件后的第一个字节通常是7位从设备地址加1位读写标志位(R/W)。
| 位序 | Bit 7 (MSB) | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 (LSB) | 应答位 |
|---|---|---|---|---|---|---|---|---|---|
| 地址字节 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | R/W | ACK |
| 数据字节 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | ACK |
驱动实现:在ARM平台的I2C控制器中,发送数据时需将数据写入发送数据寄存器(I2C_TXDR),硬件会自动按MSB顺序移位输出。接收数据时,从接收数据寄存器(I2C_RXDR)读取的字节也是MSB对齐的。
2.5 应答机制(ACK/NACK)
应答机制是I2C协议可靠性的核心。每传输完一个字节(8位数据),接收方必须在第9个SCL时钟周期内将SDA线拉低(ACK)或保持高电平(NACK),以告知发送方是否成功接收数据。
- ACK(应答):接收方在第9个时钟周期将SDA拉低,表示“已收到,请继续发送下一个字节”。
- NACK(非应答):接收方在第9个时钟周期保持SDA为高电平,表示“未准备好/传输结束/错误”。
常见错误:如果从设备未应答(NACK),主设备必须产生停止条件终止传输。在驱动中,应检查状态寄存器中的
ACK_FAIL 或 NACK 标志位,并执行相应的错误处理流程,否则总线可能被挂起。
2.6 完整数据传输流程
一个典型的I2C写操作流程如下:
- 主设备产生起始条件(S)。
- 主设备发送7位从设备地址 + 写标志位(0)。
- 从设备应答(ACK)。
- 主设备发送寄存器地址字节。
- 从设备应答(ACK)。
- 主设备发送数据字节。
- 从设备应答(ACK)。
- 主设备产生停止条件(P)。
总结:起始条件、停止条件、数据有效性、字节格式和应答机制共同构成了I2C协议的物理层基础。在ARM平台的I2C驱动开发中,寄存器配置(如控制寄存器、状态寄存器、数据寄存器)正是围绕这些时序规则设计的。理解这些底层细节,是正确配置I2C控制器和调试通信问题的前提。