1. I2C总线概述

I2C(Inter-Integrated Circuit)总线是由Philips公司(现NXP)在1980年代推出的一种同步、多主从、串行通信总线。它仅需两根信号线——串行数据线(SDA)和串行时钟线(SCL),即可实现芯片间的短距离通信,是嵌入式系统中使用最广泛的板级总线之一。

1.1 物理层特性

参数 标准模式 (Standard) 快速模式 (Fast) 高速模式 (High-Speed)
最高时钟频率 100 kHz 400 kHz 3.4 MHz
总线最大电容 400 pF 400 pF 100 pF
最大从设备数量 受限于地址空间(7位:127个) 受限于地址空间 受限于地址空间
输出级 开漏 开漏 开漏 + 电流源

1.2 电气连接与上拉电阻

I2C总线采用开漏(Open-Drain)结构,所有设备的SDA和SCL引脚内部为MOS管漏极开路输出。总线空闲时,两根线均被外部上拉电阻拉至高电平(VDD)。

  • 上拉电阻阻值选择:取决于总线电容和通信速率。典型值在1 kΩ ~ 10 kΩ之间。
  • 逻辑电平:低电平为0V,高电平为VDD(通常为1.8V、3.3V或5V)。
  • 线与特性:多个设备可以同时将总线拉低,实现仲裁和时钟同步。
驱动开发提示:在Linux设备树中,上拉电阻通常由硬件设计决定,驱动无需配置。但需注意I2C控制器IP的电气特性是否支持标准/快速/高速模式,这直接影响时钟频率的设定。

1.3 SDA/SCL信号时序

I2C总线的数据传输以起始条件(START)开始,以停止条件(STOP)结束。数据在SCL时钟高电平时采样,低电平时变化。

  • 空闲状态:SCL = 1,SDA = 1。
  • 起始条件(S):SCL = 1 时,SDA 从 1 跳变到 0。
  • 数据位传输:SCL 低电平时 SDA 变化,SCL 高电平时 SDA 被采样。
  • 停止条件(P):SCL = 1 时,SDA 从 0 跳变到 1。
  • 应答位(ACK):每传输8位数据后,接收方在第9个时钟周期将SDA拉低表示应答。
关键时序参数(标准模式):tHD;STA ≥ 4.0 μs(起始保持时间),tSU;STO ≥ 4.0 μs(停止建立时间),tLOW ≥ 4.7 μs(时钟低电平时间),tHIGH ≥ 4.0 μs(时钟高电平时间)。
I2C总线信号时序图(标准模式) SCL SDA S 起始 P 停止 MSB (D7) D6 D5 D4 D3 D2 D1 ACK 时序要点 • 数据在SCL高电平时采样,低电平时允许SDA变化 • 起始条件:SCL高电平期间SDA由高→低;停止条件:SCL高电平期间SDA由低→高

1.4 I2C协议基础

I2C协议定义了完整的通信帧格式,包括地址、读写方向、数据和应答机制。

1.4.1 帧格式

| S | 7位从设备地址 | R/W | ACK | 8位数据字节 | ACK | ... | 8位数据字节 | ACK/NACK | P |
  • S:起始条件
  • 7位从设备地址:高7位为设备地址,最低位为读写位(0=写,1=读)
  • R/W:读写方向位
  • ACK:从设备应答(低电平有效)
  • 数据字节:MSB优先,每字节后跟ACK
  • P:停止条件

1.4.2 读写操作流程

写操作流程:主机发送起始条件 → 发送从设备地址+写位(0) → 等待ACK → 发送寄存器地址 → 等待ACK → 发送数据字节 → 等待ACK → ... → 发送停止条件。
读操作流程:主机发送起始条件 → 发送从设备地址+写位(0) → 等待ACK → 发送寄存器地址 → 等待ACK → 发送重复起始条件(Sr) → 发送从设备地址+读位(1) → 等待ACK → 读取数据字节 → 主机发送NACK → 发送停止条件。

1.4.3 10位地址与扩展

7位地址空间最多支持127个从设备(0x00为广播地址,0x01~0x7F可用)。I2C规范也支持10位地址模式,通过保留地址0xF0~0xF7作为前缀来扩展地址空间。

地址类型 地址范围 最大设备数 常见用途
7位地址 0x01 ~ 0x7F 127 大多数传感器、EEPROM、ADC/DAC
10位地址 0x000 ~ 0x3FF 1024 复杂外设、多路复用器
保留地址 0x00, 0xF0~0xFF — 广播、10位前缀、特殊命令
I2C协议通信帧结构(写操作示例) S 从设备地址 W ACK 寄存器地址 ACK 数据字节 ACK P 协议关键点 • 每个字节(8位)传输后,接收方必须在第9个SCL周期发送ACK(低电平)或NACK(高电平) • 读操作需在发送寄存器地址后,发送重复起始条件(Sr)并切换为读方向 • 主机作为接收方时,在最后一个字节发送NACK以通知从设备停止发送 • 时钟同步与仲裁:多个主机同时驱动总线时,低电平优先,实现无损仲裁

1.5 I2C总线在嵌入式系统中的角色

在Linux嵌入式系统中,I2C总线主要用于连接低速外设,如:

  • 传感器:温度传感器(LM75)、湿度传感器(SHT20)、加速度计(MPU6050)
  • 存储设备:EEPROM(AT24Cxx)、铁电存储器(FM24CLxx)
  • 接口扩展:GPIO扩展器(PCA9535)、ADC/DAC(ADS1115)
  • 多媒体:音频编解码器(WM8731)、HDMI接口(TDA998x)
驱动开发注意事项:I2C从设备地址通常由硬件引脚(如A0/A1/A2)决定,同一总线上不能出现地址冲突。在设备树中通过 reg = <0x48>; 属性指定,驱动通过 i2c_client->addr 获取。

1.6 本章小结