1. I2C总线协议基础

I2C(Inter-Integrated Circuit)总线是由Philips公司(现NXP)开发的一种同步、多主从、串行通信总线。它仅需两根信号线即可完成设备间的数据交换,是嵌入式系统中连接传感器、EEPROM、ADC/DAC、实时时钟等外设最常用的总线之一。理解I2C总线的物理层特性、信号时序和拓扑结构,是编写正确、健壮的Linux I2C设备驱动的前提。

学习提示: I2C总线协议虽然简单,但物理层细节(如上拉电阻选择、总线电容限制、电平标准)直接影响驱动稳定性和通信速率。在驱动调试中,超过70%的I2C通信故障源于物理层配置不当,而非软件逻辑错误。

1.1 I2C总线物理层特性

I2C总线使用两根双向开漏(Open-Drain)信号线:串行数据线(SDA)和串行时钟线(SCL)。所有设备通过开漏输出连接到总线,并通过外部上拉电阻将总线拉至高电平。

特性 说明 典型值/范围
信号线数量 SDA(数据)、SCL(时钟) 2根
输出类型 开漏(Open-Drain) —
上拉电阻 外部上拉至VDD 1kΩ ~ 10kΩ(取决于总线电容和速率)
逻辑电平 低电平=GND,高电平=VDD 1.8V / 3.3V / 5V(需兼容)
最大总线电容 限制从设备数量和布线长度 标准模式400pF,快速模式550pF
最大从设备数量 受限于7位或10位地址空间 7位地址:最多112个(保留地址除外)
通信速率 标准模式 / 快速模式 / 高速模式 100kHz / 400kHz / 3.4MHz
工程注意: 上拉电阻的选择需权衡功耗和信号上升时间。电阻过小会导致低电平电流过大,增加功耗;电阻过大会使上升沿变缓,限制通信速率。对于400kHz快速模式,3.3V系统通常选用4.7kΩ上拉电阻。

1.2 SDA与SCL信号

SDA和SCL信号在I2C总线中承担不同角色,两者配合完成数据帧的传输。SCL由主设备产生,用于同步数据传输;SDA用于传输地址、读写标志、数据和应答信号。

I2C总线的信号定义遵循以下规则:

  • 数据有效性: 在SCL高电平期间,SDA上的数据必须保持稳定;SCL低电平期间,SDA允许变化。
  • 起始条件(START): SCL为高电平时,SDA从高电平切换到低电平。
  • 停止条件(STOP): SCL为高电平时,SDA从低电平切换到高电平。
  • 应答(ACK): 每传输8位数据后,接收方在第9个SCL周期将SDA拉低,表示应答。
  • 非应答(NACK): 接收方在第9个SCL周期保持SDA为高电平,表示非应答。
I2C 总线信号时序图(单字节写操作) SCL SDA START STOP D7 D6 D5 D4 D3 D2 D1 D0 ACK 时序说明: 1. SCL高电平期间,SDA数据必须稳定(数据采样窗口)。 2. SCL低电平期间,SDA允许变化(数据切换窗口)。 3. 每字节后跟一个ACK/NACK位,由接收方控制SDA。

1.3 I2C总线拓扑结构

I2C总线采用多主从总线拓扑结构。所有设备通过SDA和SCL两条线并联连接,每个设备都有一个唯一的地址。主设备(Master)负责产生时钟、发起通信和终止通信;从设备(Slave)监听总线地址,响应主设备的请求。

I2C总线拓扑的关键特征:

  • 多主设备支持: 多个主设备可以共享同一总线,通过仲裁机制决定总线控制权。
  • 地址唯一性: 每个从设备必须拥有唯一的7位或10位地址,地址冲突会导致通信混乱。
  • 总线长度限制: 受总线电容限制,标准模式总线长度一般不超过1米(400pF电容限制)。
  • 设备数量限制: 7位地址模式下,除去保留地址(0x00~0x07、0x78~0x7F),最多可挂载112个从设备。
I2C 总线拓扑结构图 Rₚ Rₚ VDD VDD SDA SCL 主设备 (Master) 从设备1 (0x50 EEPROM) 从设备2 (0x48 温度传感器) 从设备3 (0x3C OLED) 拓扑要点: • 所有设备SDA/SCL引脚并联到总线上 • 每个从设备必须有唯一地址

1.4 I2C总线通信流程

一次完整的I2C通信流程包含以下步骤:

  1. 主设备发送起始条件(START): SCL高电平时,SDA从高变低。
  2. 主设备发送从设备地址和读写位: 7位地址 + 1位读写标志(0=写,1=读),共8位。
  3. 从设备应答(ACK): 地址匹配的从设备在第9个SCL周期拉低SDA。
  4. 数据传输: 主设备(写操作)或从设备(读操作)逐字节发送数据,每字节后跟ACK。
  5. 主设备发送停止条件(STOP): SCL高电平时,SDA从低变高,释放总线。
驱动开发要点: 在Linux内核中,I2C通信流程被封装在 struct i2c_msg 结构体和 i2c_transfer() 函数中。驱动开发者无需手动操作SDA/SCL时序,只需构造消息数组并调用传输接口。但理解底层时序对调试通信异常(如ACK丢失、时钟拉伸)至关重要。

1.5 I2C地址与速率模式

参数 7位地址模式 10位地址模式
地址范围 0x00 ~ 0x7F 0x000 ~ 0x3FF
可用地址数 112(保留16个) 1024
地址帧长度 1字节(地址+读写位) 2字节(首字节1111 0XX + 第二字节)
兼容性 所有设备支持 仅10位地址设备支持
Linux驱动支持 完全支持 支持(需设置I2C_M_TEN标志)

I2C总线支持多种速率模式,驱动开发中需根据从设备数据手册选择正确的速率:

  • 标准模式(Standard-mode, Sm): 100kHz,兼容性最好,适用于大多数低速传感器。
  • 快速模式(Fast-mode, Fm): 400kHz,常用速率,需注意总线电容和上拉电阻。
  • 快速模式+(Fast-mode Plus, Fm+): 1MHz,需要更强的驱动能力和更小的上拉电阻。
  • 高速模式(High-speed mode, Hs-mode): 3.4MHz,需特殊硬件支持,驱动中需处理高速模式切换。
速率选择警告: 在Linux设备树中,通过 clock-frequency 属性设置I2C控制器速率。切勿将速率设置得高于从设备支持的最大值,否则可能导致通信失败或数据损坏。对于未知设备,优先使用100kHz标准模式进行调试。