4. I2C 总线速率模式详解

I2C 总线协议在演进过程中定义了多种速率模式,以满足不同外设对通信速度的需求。从最初的标准模式到如今的超快速模式,每种模式在时序参数、驱动能力和应用场景上都有显著差异。作为驱动开发者,理解这些速率模式是正确配置 I2C 控制器、保证通信可靠性的前提。

核心要点: 速率模式的选择并非越高越好,必须同时考虑总线电容、上拉电阻、从设备支持能力以及信号完整性。高速模式(3.4 MHz)和超快速模式(5 MHz)对 PCB 布局和驱动电路有严格要求。

4.1 四种速率模式对比总览

下表从时钟频率、传输模式、最大总线电容、驱动电流要求以及典型应用场景五个维度,对四种标准速率模式进行横向对比:

速率模式 时钟频率 传输模式 最大总线电容 驱动电流要求 典型应用
标准模式 (Sm) 100 kHz 双向半双工 400 pF 3 mA 低速传感器、EEPROM、RTC
快速模式 (Fm) 400 kHz 双向半双工 400 pF 6 mA 音频编解码器、显示控制器
高速模式 (Hs-mode) 3.4 MHz 双向半双工(需主从握手) 100 pF 20 mA 高分辨率图像传感器、高速 ADC
超快速模式 (UFm) 5 MHz 单向推挽(仅发送) 100 pF 20 mA LED 驱动器、电源管理芯片
驱动开发提示: 在 Linux 内核中,I2C 控制器驱动通过 struct i2c_adapter 的 quirks 字段声明支持的速率模式。设备树中通常使用 clock-frequency 属性指定总线速率,例如 clock-frequency = <400000>; 表示快速模式。

4.2 标准模式 (Standard-mode, 100 kHz)

标准模式是 I2C 总线最原始的工作模式,时钟频率为 100 kHz,最大数据传输速率约为 100 kbit/s。该模式对总线时序要求最宽松,兼容性最好,几乎所有 I2C 设备都支持此模式。

  • 时序参数: SCL 低电平时间 ≥ 4.7 μs,高电平时间 ≥ 4.0 μs;上升时间 ≤ 1000 ns,下降时间 ≤ 300 ns。
  • 上拉电阻: 在 5V 供电、总线电容 400 pF 条件下,典型上拉电阻值为 4.7 kΩ ~ 10 kΩ。
  • 驱动能力: 标准开漏输出,3 mA 灌电流即可满足时序要求。
  • 应用场景: 温湿度传感器(如 SHT20)、实时时钟(如 DS1307)、低速 EEPROM(如 AT24C02)。
常见误区: 即使所有从设备都支持快速模式,如果总线走线过长或电容过大,强行使用 400 kHz 可能导致信号畸变。此时降回标准模式是保证通信可靠性的有效手段。

4.3 快速模式 (Fast-mode, 400 kHz)

快速模式将时钟频率提升至 400 kHz,是当前嵌入式系统中最常用的 I2C 速率模式。它向下兼容标准模式,所有快速模式设备必须能在 0 ~ 400 kHz 范围内正常工作。

  • 时序参数: SCL 低电平时间 ≥ 1.3 μs,高电平时间 ≥ 0.6 μs;上升时间 ≤ 300 ns,下降时间 ≤ 300 ns。
  • 驱动电流: 从设备需提供 6 mA 灌电流,以保证在更短的时间内完成电平转换。
  • 上拉电阻: 推荐使用 1.5 kΩ ~ 2.2 kΩ(3.3V 供电),以加快上升沿。
  • Linux 配置: 设备树中设置 clock-frequency = <400000>;,内核 I2C 子系统自动适配时序。
// 设备树示例:I2C 控制器配置为快速模式
&i2c1 {
    status = "okay";
    clock-frequency = <400000>;  // 400 kHz 快速模式
    pinctrl-0 = <&i2c1_pins>;

    audio_codec: wm8960@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
    };
};

4.4 高速模式 (High-speed Mode, 3.4 MHz)

高速模式(Hs-mode)将 I2C 总线速率提升至 3.4 MHz,是标准 I2C 协议中速率最高的双向通信模式。它引入了主从握手机制和专用的 Hs 模式传输阶段,对硬件设计和驱动实现提出了更高要求。

4.4.1 高速模式传输流程

高速模式传输分为三个阶段:启动阶段(主设备发送 Hs 模式主控码)、高速传输阶段(SCL 提升至 3.4 MHz)、结束阶段(返回 F/S 模式)。下图展示了完整的传输流程:

高速模式(Hs-mode)传输流程 阶段 1:启动 主设备发送 START + 主控码 阶段 2:握手 从设备 ACK + 切换 Hs 模式 阶段 3:高速传输 SCL = 3.4 MHz 传输数据 时序关键参数 • 主控码:8 位(0000 1xxx),由主设备在 START 后发送 • 从设备 ACK 后,SCL 在 1 μs 内从 400 kHz 切换到 3.4 MHz • 高速传输阶段:SCL 低电平 ≥ 160 ns,高电平 ≥ 60 ns • 传输结束后,主设备发送 STOP 或重复 START 退出 Hs 模式 • 总线电容必须 ≤ 100 pF,否则信号上升沿无法满足时序

4.4.2 高速模式驱动注意事项

  • 硬件要求: 总线电容 ≤ 100 pF,上拉电阻通常 ≤ 1 kΩ,PCB 走线长度应尽量短。
  • 从设备支持: 并非所有 I2C 设备都支持 Hs-mode,驱动中需通过设备树或平台数据明确声明。
  • Linux 内核支持: 部分 I2C 控制器(如 i.MX6 的 I2C IP)原生支持 Hs-mode,驱动中需实现 master_xfer_atomic 回调并配置高速时序寄存器。
// Linux 内核中 I2C 控制器驱动配置高速模式示例
static const struct i2c_adapter_quirks imx_i2c_quirks = {
    .flags = I2C_AQ_COMB | I2C_AQ_NO_ZERO_LEN,
    .max_read_len = 512,
    .max_write_len = 512,
    .max_comb_1st_len = 32,
    .max_comb_2nd_len = 512,
    // 声明支持高速模式
    .max_speed_hs = 3400000,
};

static int imx_i2c_set_speed(struct imx_i2c_struct *i2c_imx, unsigned int speed)
{
    unsigned int div, pres, reg;

    if (speed >= 3400000) {
        // 配置高速模式分频系数
        pres = 0;  // 预分频 1
        div = 6;   // 分频系数 6,得到 3.4 MHz
        i2c_imx->ifdr = (pres << 6) | div;
        i2c_imx->speed_hs = true;
    } else if (speed >= 400000) {
        // 配置快速模式
        // ...
    }
    return 0;
}

4.5 超快速模式 (Ultra Fast-mode, 5 MHz)

超快速模式(UFm)是 I2C 总线规范中速率最高的模式,时钟频率达到 5 MHz。与前三者不同,UFm 采用 单向推挽输出,仅支持主设备向从设备发送数据,不支持从设备回传数据或 ACK 应答。这使得 UFm 在时序上更接近 SPI 的单向传输特性。

4.5.1 UFm 模式特性

特性 描述
传输方向 单向(主 → 从),从设备不发送数据
输出结构 推挽输出(Push-Pull),非开漏
应答机制 无 ACK/NACK,从设备不拉低 SDA
最大速率 5 MHz(约 5 Mbit/s)
总线电容 ≤ 100 pF
典型应用 LED 驱动、电源管理 IC、单色显示屏

4.5.2 UFm 与标准 I2C 的差异

由于 UFm 采用推挽输出,不再需要上拉电阻,总线电平切换速度更快,但也失去了 I2C 总线原有的仲裁和时钟拉伸能力。驱动开发时需注意:

  • 无需上拉电阻: 主设备 SDA/SCL 引脚配置为推挽输出模式。
  • 无应答检测: 驱动中不应等待 ACK,直接连续发送数据即可。
  • 从设备地址: 仍使用 7 位或 10 位地址格式,但地址仅用于片选,不参与应答。
  • Linux 支持: 目前主流 SoC 的 I2C 控制器对 UFm 支持有限,通常需要 GPIO 模拟或专用 IP 核。
// UFm 模式下的数据传输示例(GPIO 模拟)
static void ufm_write_byte(struct gpio_i2c *i2c, uint8_t data)
{
    int i;
    for (i = 7; i >= 0; i--) {
        // SCL 低电平,设置 SDA
        gpio_set_value(i2c->scl, 0);
        gpio_set_value(i2c->sda, (data >> i) & 0x01);
        // SCL 高电平,从设备采样
        gpio_set_value(i2c->scl, 1);
        udelay(100);  // 5 MHz 对应 200 ns 周期,此处为演示放大延时
    }
    // UFm 模式下无需 ACK 检测,直接返回
    gpio_set_value(i2c->scl, 0);
}

4.6 速率模式选择决策流程

在实际项目中选择 I2C 总线速率时,建议遵循以下决策流程:

I2C 总线速率选择决策流程 确定总线负载与从设备 所有从设备支持快速模式? 是 总线电容 ≤ 100 pF? 是 需要双向通信? 是 高速模式 3.4 MHz 否 标准模式 100 kHz 否 快速模式 400 kHz 否 UFm 5 MHz

4.7 速率模式在 Linux 内核中的配置

在 Linux 内核中,I2C 总线速率通过设备树或平台数据配置,控制器驱动根据配置值自动选择对应的时序寄存器参数。以下是常见的配置方式:

// 设备树配置示例(不同速率模式)
// 标准模式
&i2c0 {
    clock-frequency = <100000>;  // 100 kHz
};

// 快速模式
&i2c1 {
    clock-frequency = <400000>;  // 400 kHz
};

// 高速模式(需控制器支持)
&i2c2 {
    clock-frequency = <3400000>; // 3.4 MHz
    // 部分控制器需要额外属性启用 Hs 模式
    i2c-sda-hold-time-ns = <300>;
};

// 超快速模式(通常需专用驱动或 GPIO 模拟)
&i2c3 {
    clock-frequency = <5000000>; // 5 MHz
    // UFm 模式下需配置推挽输出
    drive-strength = <8>;
};
调试建议: 使用 i2cget、i2cset 和逻辑分析仪验证实际总线速率。在 /sys/kernel/debug/i2c-<bus>/ 下可以查看当前适配器的速率配置。如果出现通信失败,首先检查时序参数是否匹配所选速率模式。

4.8 本章小结

I2C 总线的四种速率模式——标准模式(100 kHz)、快速模式(400 kHz)、高速模式(3.4 MHz)和超快速模式(5 MHz)——分别对应不同的应用场景和硬件要求。驱动开发者需要根据从设备规格、总线电容、PCB 布局以及是否需要双向通信等因素综合选择。在 Linux 内核中,通过设备树的 clock-frequency 属性即可完成速率配置,但底层时序寄存器的正确计算依赖于控制器驱动对每种模式时序参数的精确实现。