2. I2C数据传输机制:起始条件、停止条件、数据有效性、应答与非应答、字节传输格式
I2C(Inter-Integrated Circuit)总线协议的核心在于其精确定义的时序与握手规则。本章深入剖析I2C数据传输的五个基本要素:起始条件、停止条件、数据有效性、应答/非应答机制以及字节传输格式。理解这些底层机制是后续进行中断处理与DMA调优的基础。
2.1 起始条件与停止条件
I2C总线在空闲状态时,SCL(时钟线)和SDA(数据线)均为高电平。主控制器通过特定的电平跳变来标志一次传输的开始与结束。
- 起始条件(S):当SCL为高电平时,SDA从高电平切换到低电平。此信号由主控制器产生,表示总线从空闲状态进入活跃状态,所有从设备必须监听后续的地址信息。
- 停止条件(P):当SCL为高电平时,SDA从低电平切换到高电平。此信号由主控制器产生,表示本次传输结束,总线恢复空闲状态。
驱动开发提示:在嵌入式Linux驱动中,起始与停止条件的产生通常由I2C控制器硬件自动完成。但在某些低功耗或GPIO模拟I2C的场景下,驱动开发者需要手动控制GPIO电平并严格遵循时序要求,特别是在高频率下需注意GPIO的翻转速率。
关键时序参数:起始条件建立时间(tSU;STA)和保持时间(tHD;STA)在标准模式下通常要求大于4.7μs和4.0μs,快速模式下则缩短至0.6μs和0.6μs。
2.2 数据有效性
I2C协议对数据线上的电平采样有严格规定,以确保数据在传输过程中的完整性。
- 数据稳定期:在SCL时钟的高电平期间,SDA上的数据必须保持稳定。此时从设备或主设备对SDA进行采样。
- 数据变化期:只有在SCL为低电平时,SDA上的数据才允许发生变化。这为下一次数据位的传输做准备。
常见错误:如果驱动在SCL高电平时错误地改变了SDA状态,总线上的其他设备会将其误解为起始或停止条件,导致总线混乱。在中断服务程序中操作I2C寄存器时,务必确认硬件状态机是否处于正确的相位。
2.3 应答与非应答机制
I2C总线使用应答位(ACK)和非应答位(NACK)来实现接收方对发送方的反馈,这是保证数据可靠传输的握手信号。
| 信号类型 | SDA电平(第9个SCL脉冲) | 含义 | 典型场景 |
|---|---|---|---|
| 应答 (ACK) | 低电平 | 接收方已成功接收上一个字节,准备接收下一个字节 | 从设备确认地址匹配;从设备确认数据写入成功 |
| 非应答 (NACK) | 高电平 | 接收方未成功接收或不再接收数据 | 从设备地址不存在;从设备忙;主设备读操作结束 |
驱动中的NACK处理:在Linux I2C核心层中,当检测到NACK时,通常会返回
-EREMOTEIO 或 -EIO 错误码。驱动开发者应在中断处理中检查传输状态寄存器中的NACK标志位,并执行相应的错误恢复流程,如发送停止条件或重试。
2.4 字节传输格式
I2C总线上的数据传输以字节(8位)为单位,每个字节后必须跟随一个应答位。传输顺序为高位在前(MSB first)。
2.4.1 完整传输帧结构
一次完整的I2C传输帧包含以下顺序:
- 起始条件 (S)
- 从设备地址 (7位或10位) + 读写位 (1位):共8位,后跟ACK。
- 数据字节 (8位):一个或多个,每个字节后跟ACK/NACK。
- 停止条件 (P) 或 重复起始条件 (Sr)
2.4.2 读写操作格式对比
| 操作类型 | 帧格式 | 说明 |
|---|---|---|
| 主设备写 | S + 从地址(W) + ACK + 数据1 + ACK + ... + 数据N + ACK/NACK + P | 主设备发送数据到从设备,从设备每字节回复ACK |
| 主设备读 | S + 从地址(R) + ACK + 数据1 + ACK + ... + 数据N + NACK + P | 主设备接收数据,除最后一个字节外回复ACK,最后回复NACK |
| 复合格式 | S + 地址(W) + ACK + 寄存器地址 + ACK + Sr + 地址(R) + ACK + 数据 + NACK + P | 先写寄存器地址,再重复起始条件后读取数据 |
DMA调优切入点:在复合格式传输中,重复起始条件(Sr)打断了连续的DMA传输。驱动开发者需要配置I2C控制器在发送完寄存器地址后,不发送停止条件,而是自动插入重复起始条件,并切换DMA通道方向。这通常需要操作控制器的“主模式控制寄存器”中的“重复起始”位。
2.5 高速模式与DMA的关联
在标准模式(100kHz)和快速模式(400kHz)下,CPU轮询或中断处理通常可以满足需求。但在高速模式(3.4MHz)下,每个字节的传输时间缩短至约2.94μs,频繁的中断响应会消耗大量CPU资源。此时,DMA(直接存储器访问)成为关键优化手段。
- 中断开销:在高速模式下,每传输一个字节(8位数据 + 1位ACK)就需要一次中断,CPU需要频繁保存/恢复上下文。
- DMA优势:DMA控制器可以在无需CPU干预的情况下,自动将数据从内存搬运到I2C发送寄存器,或从接收寄存器搬运到内存,仅在传输完成时产生一次中断。
- 关键配置:启用DMA时,需要正确配置I2C控制器的FIFO阈值、DMA突发传输大小以及传输方向,避免数据溢出或欠载。
性能对比:在3.4MHz高速模式下,传输64字节数据,纯中断方式大约需要64次中断处理,而DMA方式仅需1次完成中断。DMA方式可将CPU占用率从约30%降低至接近0%,释放CPU处理其他任务。