4. I2C总线时序分析:标准模式、快速模式与高速模式

I2C总线时序是驱动开发中最核心的硬件基础。不同速率模式下,SCL时钟频率、上升/下降时间、数据建立/保持时间等参数差异显著。本章从物理层时序参数出发,逐模式分析标准模式(100kHz)、快速模式(400kHz)和高速模式(3.4MHz)的时序要求,并给出驱动开发中的实测与配置要点。

时序参数决定驱动兼容性: 同一I2C器件可能同时支持标准模式和快速模式,但高速模式需要主控制器和从器件双方都支持,且总线电容、上拉电阻等硬件设计必须满足对应时序约束。

4.1 I2C总线时序基础框架

I2C总线由SCL(时钟线)和SDA(数据线)构成,所有时序参数均围绕这两条线的电平变化定义。下图展示了I2C单次数据传输的完整时序框架,包含起始条件、数据字节传输、应答位和停止条件。

I2C总线单次传输时序框架 起始 S 停止 P 8位数据字节(MSB先行) ACK t_SCL (周期) SCL SDA

一次完整的I2C传输包含以下阶段:

  1. 起始条件(S): SDA在SCL高电平时从高到低跳变,表示传输开始。
  2. 从设备地址发送: 主设备发送7位或10位从设备地址,后跟读写位(R/W)。
  3. 应答位(ACK): 从设备在第9个SCL周期将SDA拉低,表示应答。
  4. 数据字节传输: 每字节8位,MSB先行,后跟应答位。
  5. 停止条件(P): SDA在SCL高电平时从低到高跳变,表示传输结束。

4.2 标准模式(100kHz)时序参数

标准模式是I2C总线最基础的速率模式,兼容性最广。下表列出了标准模式下的关键时序参数及其最小/最大值要求。

参数符号 参数名称 最小值 最大值 单位
f_SCL SCL时钟频率 0 100 kHz
t_HD;STA 起始条件保持时间 4.0 — μs
t_LOW SCL低电平时间 4.7 — μs
t_HIGH SCL高电平时间 4.0 — μs
t_SU;STA 重复起始条件建立时间 4.7 — μs
t_HD;DAT 数据保持时间 0 3.45 μs
t_SU;DAT 数据建立时间 250 — ns
t_r SCL/SDA上升时间 — 1000 ns
t_f SCL/SDA下降时间 — 300 ns
t_SU;STO 停止条件建立时间 4.0 — μs
t_BUF 停止与起始条件间总线空闲时间 4.7 — μs
驱动开发提示: 标准模式下,SCL低电平时间(t_LOW)要求≥4.7μs,高电平时间(t_HIGH)要求≥4.0μs。在Linux I2C适配器驱动中,这些参数通过时钟分频寄存器配置。若使用GPIO模拟I2C,需在延时函数中精确控制电平持续时间。

4.3 快速模式(400kHz)时序参数

快速模式将时钟频率提升至400kHz,时序要求比标准模式更严格,尤其是上升/下降时间和建立时间。下表对比快速模式与标准模式的关键差异参数。

参数符号 参数名称 标准模式 快速模式 单位
f_SCL SCL时钟频率 0~100 0~400 kHz
t_LOW SCL低电平时间 4.7 1.3 μs
t_HIGH SCL高电平时间 4.0 0.6 μs
t_HD;STA 起始条件保持时间 4.0 0.6 μs
t_SU;DAT 数据建立时间 250 100 ns
t_r SCL/SDA上升时间 1000 300 ns
t_f SCL/SDA下降时间 300 300 ns
t_BUF 总线空闲时间 4.7 1.3 μs

快速模式相比标准模式的主要变化:

  • SCL低电平时间从4.7μs缩短至1.3μs,高电平时间从4.0μs缩短至0.6μs。
  • 数据建立时间从250ns收紧至100ns,要求数据在SCL上升沿前更早稳定。
  • 上升时间从1000ns收紧至300ns,对总线电容和上拉电阻提出更高要求。
  • 总线空闲时间从4.7μs缩短至1.3μs,允许更快的连续传输。
硬件设计注意: 快速模式下,总线电容应控制在≤200pF。上拉电阻值需根据总线电容计算,典型值在1.5kΩ~4.7kΩ之间。若电容过大或上拉电阻过高,会导致上升时间超标,造成数据采样错误。

4.4 高速模式(3.4MHz)时序参数

高速模式(Hs-mode)将I2C总线速率提升至3.4MHz,是标准I2C速率的34倍。高速模式引入了特殊的传输协议:主设备先以标准模式或快速模式发送高速模式使能码(00001XXX),然后切换到高速模式传输数据。

高速模式(Hs-mode)传输流程 起始条件 (S) 标准/快速模式 使能码 00001XXX 主设备发送 高速模式传输 SCL = 3.4MHz 开漏→电流源驱动 停止条件 (P) 返回标准/快速模式 说明: 高速模式使能码(00001XXX)中的XXX为3位保留位,通常由主设备发送000。从设备在接收到使能码后, 必须切换到高速模式,并准备接收后续的高速传输。高速模式下,SCL由主设备的电流源驱动,而非开漏输出。 标准/快速模式 使能码阶段 高速模式传输 停止条件

高速模式的关键时序参数如下表所示:

参数符号 参数名称 最小值 最大值 单位
f_SCL SCL时钟频率(高速模式) 0 3.4 MHz
t_LOW SCL低电平时间 160 — ns
t_HIGH SCL高电平时间 60 — ns
t_HD;STA 起始条件保持时间 160 — ns
t_SU;DAT 数据建立时间 10 — ns
t_HD;DAT 数据保持时间 0 70 ns
t_r SCL/SDA上升时间 — 40 ns
t_f SCL/SDA下降时间 — 40 ns
t_SU;STO 停止条件建立时间 160 — ns
t_BUF 总线空闲时间 160 — ns
高速模式驱动要点:
  • 高速模式下,SCL由主设备的电流源驱动(典型电流源为3mA),而非开漏输出加外部上拉电阻。
  • 数据建立时间仅需10ns,对主设备输出延迟和从设备输入采样窗口要求极高。
  • 上升/下降时间必须控制在40ns以内,总线电容应≤100pF。
  • 高速模式传输结束后,必须发送停止条件,使总线返回标准/快速模式。

4.5 三种模式时序参数对比总表

下表汇总了标准模式、快速模式和高速模式的核心时序参数,便于驱动开发时快速查阅和对比。

参数 标准模式 (100kHz) 快速模式 (400kHz) 高速模式 (3.4MHz) 单位
SCL频率 100 400 3400 kHz
SCL周期 10 2.5 0.294 μs
t_LOW 4.7 1.3 0.16 μs
t_HIGH 4.0 0.6 0.06 μs
t_SU;DAT 250 100 10 ns
t_HD;DAT 0~3.45 0~0.9 0~0.07 μs
t_r 1000 300 40 ns
t_f 300 300 40 ns
总线电容 ≤400 ≤200 ≤100 pF
驱动方式 开漏+上拉 开漏+上拉 电流源+开漏 —

4.6 驱动开发中的时序配置实践

在嵌入式Linux驱动开发中,I2C时序配置通常通过I2C适配器驱动中的时钟分频寄存器实现。以下是一个典型的I2C时序配置代码示例,展示如何根据目标速率计算分频系数。

/*
 * I2C时序配置示例:计算SCL分频系数
 * 假设I2C控制器输入时钟为50MHz
 */

#include <linux/i2c.h>
#include <linux/delay.h>

/* 根据目标速率计算分频系数 */
static u32 i2c_calc_divider(u32 input_clk_hz, u32 target_rate_hz)
{
    u32 divider;
    
    /* 标准模式:100kHz */
    if (target_rate_hz <= 100000)
        divider = input_clk_hz / (2 * 100000);
    /* 快速模式:400kHz */
    else if (target_rate_hz <= 400000)
        divider = input_clk_hz / (2 * 400000);
    /* 高速模式:3.4MHz */
    else if (target_rate_hz <= 3400000)
        divider = input_clk_hz / (2 * 3400000);
    else
        return -EINVAL;
    
    /* 确保分频系数在有效范围内 */
    if (divider < 2)
        divider = 2;
    if (divider > 0xFFFF)
        divider = 0xFFFF;
    
    return divider;
}

/* 设置I2C时序寄存器 */
static int i2c_set_timing(struct i2c_adapter *adap, u32 rate)
{
    u32 divider;
    u32 reg_val;
    
    divider = i2c_calc_divider(50000000, rate);
    if (divider < 0)
        return -EINVAL;
    
    /* 写入时钟分频寄存器(假设寄存器偏移为0x00) */
    reg_val = readl(adap->base + 0x00);
    reg_val &= ~0xFFFF;
    reg_val |= (divider & 0xFFFF);
    writel(reg_val, adap->base + 0x00);
    
    /* 设置上升时间补偿(快速模式需要) */
    if (rate > 100000) {
        reg_val = readl(adap->base + 0x04);
        reg_val |= (1 << 8);  /* 使能上升时间补偿 */
        writel(reg_val, adap->base + 0x04);
    }
    
    dev_dbg(&adap->dev, "I2C rate set to %u Hz, divider = %u\n", rate, divider);
    return 0;
}
实测验证建议: 配置完成后,使用示波器测量SCL引脚的实际频率和占空比。标准模式下,占空比应接近50%(t_LOW≈4.7μs,t_HIGH≈4.0μs)。快速模式下,由于上升时间占比增大,实际占空比可能偏离50%,但只要t_LOW≥1.3μs且t_HIGH≥0.6μs即可满足规范。

4.7 时序违规的常见问题与排查

驱动开发中,时序违规是导致I2C通信失败的常见原因。下表列出了典型时序问题及其排查方法。

问题现象 可能原因 排查方法
从设备无应答(NACK) SCL频率过高,从设备无法响应 降低SCL频率至标准模式测试;检查从设备数据手册支持的速率
数据采样错误(CRC/校验失败) 数据建立时间不足,SDA在SCL上升沿未稳定 增加t_SU;DAT延时;检查总线电容是否过大导致上升沿变缓
起始条件无法识别 t_HD;STA过短,SDA跳变后SCL未及时拉低 增加起始条件保持时间;检查主设备驱动中起始条件时序实现
总线卡死(SDA一直被拉低) 从设备未释放SDA,或时钟拉伸超时 检查从设备是否处于异常状态;增加时钟拉伸超时处理
高速模式无法进入 使能码发送失败,或从设备不支持高速模式 用示波器捕获使能码波形;确认从设备Hs-mode使能条件
调试工具推荐: 使用逻辑分析仪(如Saleae、PulseView)捕获I2C总线波形,可直接测量t_LOW、t_HIGH、t_r、t_f等时序参数。Linux下可使用i2c-tools工具包中的i2cget、i2cset命令进行基本通信测试,配合内核调试选项CONFIG_I2C_DEBUG_BUS可输出详细的时序调试信息。

4.8 本章小结

I2C总线时序分析是驱动开发的基础技能。标准模式(100kHz)兼容性最好,时序裕量大;快速模式(400kHz)是嵌入式系统中最常用的速率,需注意上升时间和建立时间;高速模式(3.4MHz)需要特殊的电流源驱动和严格的PCB布局。驱动开发中,应根据从设备数据手册选择匹配的速率模式,并通过示波器或逻辑分析仪验证实际时序是否满足规范要求。