2. I2C数据传输格式:7位与10位地址模式、读写操作位、ACK/NACK机制

I2C(Inter-Integrated Circuit)总线协议定义了主设备与从设备之间进行数据交换的完整帧格式。理解地址模式、读写控制以及应答机制,是进行I2C控制器驱动移植与中断绑定的基础。本章将深入解析这些核心概念,并结合实际驱动开发场景进行说明。

2.1 I2C总线帧结构概述

一个完整的I2C数据传输帧由以下基本单元组成:起始条件(START)、从设备地址、读写位、数据字节、应答位(ACK/NACK)以及停止条件(STOP)。总线上的所有操作都由主设备发起,从设备根据地址匹配响应。

关键帧结构要素:
  • S(START):SCL高电平时,SDA由高变低,表示传输开始。
  • 地址字节:7位或10位从设备地址,高位在前。
  • R/W:1位读写标志,0表示写操作,1表示读操作。
  • ACK/NACK:每个字节后接收方必须回复的应答位。
  • 数据字节:8位数据,MSB先传,每个字节后跟ACK。
  • P(STOP):SCL高电平时,SDA由低变高,表示传输结束。
I2C基本帧结构时序图 I2C 基本帧结构时序图(7位地址 + 写操作) S 7位从地址 (0x50) W A 数据字节 (8位) A P S=起始条件,A=应答位(ACK),P=停止条件;灰色区域表示主设备驱动SDA,白色区域表示从设备驱动SDA

2.2 7位地址模式

7位地址模式是I2C协议中最常用的寻址方式。在帧结构中,地址字节的高7位为从设备地址,最低位为读写控制位。标准模式下,总线上最多可挂载112个从设备(保留地址除外)。

7位地址帧格式详解
位序 名称 说明
Bit 7 (MSB) A6 地址最高位,通常由器件型号固定
Bit 6 ~ Bit 1 A5 ~ A0 地址位,部分由硬件引脚决定
Bit 0 (LSB) R/W 0=写操作,1=读操作
驱动开发提示:在Linux内核中,7位地址通过 i2c_client.addr 字段传递,驱动中通常使用 I2C_SLAVE 命令设置。注意内核内部地址存储时左移1位,保留R/W位空间。

2.3 10位地址模式

10位地址模式是为了扩展总线容量而设计的,允许挂载更多从设备。其帧结构分为两个阶段:第一个字节的前5位为保留码 11110,后跟地址高2位和R/W位;第二个字节为地址低8位。

10位地址帧结构 10位地址模式帧结构 11110 A9:A8 R/W A 地址低8位 A7:A0 A 数据字节 A 保留码 高2位 读写 低8位地址 10位地址模式:第一个字节高5位固定为11110,后跟地址高2位和R/W位;第二个字节为地址低8位
兼容性注意:并非所有I2C控制器硬件都支持10位地址模式。在移植驱动时,需要检查控制器datasheet中的地址模式支持位。Linux内核通过 I2C_FUNC_10BIT_ADDR 功能标志来检测。

2.4 读写操作位(R/W)

读写操作位位于地址字节的最低位,控制数据传输方向:

  • 写操作(R/W = 0):主设备发送数据到从设备。主设备在发送地址后,继续发送数据字节,从设备每收到一个字节回复ACK。
  • 读操作(R/W = 1):主设备从从设备读取数据。主设备发送地址后,从设备开始发送数据,主设备每收到一个字节回复ACK(最后一个字节回复NACK以表示读取结束)。
组合传输(Combined Transfer):在实际驱动中,经常需要先写寄存器地址再读数据。这通过重复起始条件(Repeated START)实现,无需先发STOP再发START,保证了总线操作的原子性。

2.5 ACK/NACK机制

应答机制是I2C协议可靠性的核心。每个字节(包括地址字节和数据字节)传输完成后,接收方必须在第9个SCL周期释放SDA线并拉低(ACK)或保持高电平(NACK)。

ACK/NACK行为与含义
场景 发送方 接收方 SDA状态 含义
地址匹配 主设备 从设备 低电平(ACK) 从设备存在且地址匹配
地址不匹配 主设备 从设备 高电平(NACK) 无此从设备或设备忙
写数据成功 主设备 从设备 低电平(ACK) 从设备已接收数据
写数据失败 主设备 从设备 高电平(NACK) 从设备无法接收(如缓冲区满)
读数据(中间字节) 从设备 主设备 低电平(ACK) 主设备要求继续发送
读数据(最后一个字节) 从设备 主设备 高电平(NACK) 主设备通知停止发送
ACK/NACK时序细节 ACK/NACK 应答时序细节 D7 D6 D5 D4 D3 D2 D1 D0 ACK ACK:在第9个SCL周期,接收方将SDA拉低;NACK:接收方保持SDA高电平

2.6 驱动开发中的实际应用

在Linux I2C控制器驱动中,上述协议细节直接对应到硬件寄存器操作和中断处理逻辑:

  • 起始/停止条件生成:通过控制I2C控制器的START/STOP位或自动模式实现。
  • 地址发送与匹配检测:硬件自动发送地址并检测ACK,若收到NACK则触发中断或错误标志。
  • 数据收发与应答处理:每字节传输完成后,硬件检查ACK位,驱动通过状态寄存器判断是否继续传输。
  • 重复起始条件:在写寄存器地址后读数据时,驱动需设置重复起始标志,避免总线释放。
中断绑定要点:在中断服务程序中,通常通过读取状态寄存器判断当前传输阶段(地址发送完成、数据发送完成、收到NACK等),然后更新传输状态机并触发DMA或PIO下一笔传输。

2.7 常见问题与调试方法

I2C传输常见问题及排查方向
现象 可能原因 排查方法
地址发送后无ACK 从设备地址错误、设备未上电、总线冲突 使用逻辑分析仪抓取SDA/SCL波形,确认地址位
数据发送后收到NACK 从设备缓冲区满、不支持当前操作 检查从设备datasheet,确认最大传输长度
读数据时主设备未发NACK 驱动未正确设置最后一个字节的NACK 检查控制器NACK自动生成配置
总线挂死(SCL/SDA被拉低) 从设备异常、时钟同步问题 发送9个SCL时钟恢复总线,检查上拉电阻
调试建议:在驱动移植初期,建议使用 i2c-tools 工具集(如 i2cdetect、i2cget、i2cset)验证硬件连接和地址映射,再逐步调试驱动中断处理逻辑。