4、I2C工作模式详解:主机模式、从机模式、多主机模式下的仲裁与同步

I2C 总线协议定义了三种核心工作模式:主机模式(Master Mode)、从机模式(Slave Mode)以及多主机模式(Multi-Master Mode)。理解这三种模式的状态机、信号驱动方式以及总线冲突解决机制,是进行 XMC 系列 MCU 多设备调试的基础。

4.1 主机模式(Master Mode)

主机模式是 I2C 通信的发起方。在 XMC 系列中,主机负责产生串行时钟(SCL)、发起起始条件(S)、发送从机地址以及读/写位,并最终产生停止条件(P)。

主机职责 信号控制 XMC 寄存器配置要点
时钟产生 SCL 线由主机驱动高低电平 配置 CCR(时钟控制寄存器)设定标准模式(100kHz)或快速模式(400kHz)
起始条件 SCL 高电平时,SDA 由高变低 设置 I2C_CON 寄存器的 START 位
地址发送 发送 7 位地址 + R/W 位,等待 ACK 写入 I2C_ADD 寄存器,检查 ACKSTAT
数据传输 每字节后由从机产生 ACK 使用 TX/RX FIFO 或中断方式处理
停止条件 SCL 高电平时,SDA 由低变高 设置 I2C_CON 寄存器的 STOP 位
实战提示: 在 XMC 主机模式下,务必在发送起始条件前检查总线是否空闲(BUSY 标志位为 0)。若总线被占用,主机应等待或重试,避免破坏正在进行的通信。

4.2 从机模式(Slave Mode)

从机模式是被动响应模式。从机不产生时钟,而是监听 SCL 和 SDA 线。当检测到起始条件且接收到的地址与自身地址匹配时,从机参与通信。

  • 地址识别: 从机将接收到的 7 位地址与自身地址寄存器(I2C_OWN_ADD)比较。XMC 支持多个自身地址,可用于多地址响应。
  • ACK/NACK 响应: 地址匹配后,从机在第 9 个 SCL 周期拉低 SDA 产生 ACK;若不匹配或无法处理,则释放 SDA 产生 NACK。
  • 数据收发: 根据 R/W 位,从机进入发送模式(将数据写入 SDA)或接收模式(从 SDA 读取数据)。
  • 停止条件检测: 从机检测到停止条件后,复位内部状态机,等待下一次起始条件。
调试要点: 从机模式下常见的故障是地址不匹配。使用逻辑分析仪抓取 SDA 线上的地址字节,并与 XMC 的 I2C_OWN_ADD 寄存器值对比。注意 XMC 的地址寄存器默认左对齐,7 位地址需写入高 7 位。

4.3 多主机模式与仲裁(Arbitration)

多主机模式允许多个主机共享同一 I2C 总线。由于 SDA 和 SCL 是开漏结构,当两个主机同时尝试驱动总线时,必须通过仲裁机制决定谁获得总线控制权。

4.3.1 仲裁原理

仲裁发生在 SDA 线上。当多个主机同时发送起始条件并开始输出时钟时,它们会逐位比较 SDA 电平。如果某个主机试图输出高电平(释放 SDA),但检测到 SDA 被另一个主机拉低,则该主机失去仲裁并立即转为从机模式。

  • 仲裁不丢失数据: 由于仲裁过程只比较地址和数据位,且未赢得仲裁的主机停止驱动 SDA,因此总线上的数据不会损坏。
  • 时钟同步: 多个主机的 SCL 时钟会进行线与,最终 SCL 的低电平时间由最长的低电平决定,高电平时间由最短的高电平决定,实现时钟同步。
关键规则: 仲裁只能在 SDA 上进行,SCL 线不参与仲裁。主机必须在发送起始条件后的第一个字节(地址 + R/W)内完成仲裁。如果两个主机发送完全相同的地址和数据,则它们可以同时完成整个传输而不发生仲裁丢失。

4.3.2 时钟同步(Clock Synchronization)

时钟同步是多主机模式下保证数据完整性的基础。所有主机在 SCL 线上进行线与,使得 SCL 的低电平时间被拉长至所有主机中低电平时间最长的那个,高电平时间被缩短至所有主机中高电平时间最短的那个。

多主机时钟同步与仲裁过程 主机1 SCL 主机2 SCL 同步后 SCL 主机1 SDA 主机2 SDA 仲裁后 SDA 仲裁点:主机2在地址位第3位输出高电平,但SDA被主机1拉低,主机2失去仲裁

4.4 多主机模式下的状态切换与中断处理

在 XMC 系列中,多主机模式需要软件配合硬件状态机进行处理。当主机失去仲裁时,硬件会自动执行以下操作:

  1. 释放总线: 停止驱动 SDA 和 SCL,转为从机模式。
  2. 设置仲裁丢失标志: I2C_STATUS 寄存器中的 ARL(Arbitration Lost)位被置 1。
  3. 触发中断: 如果使能了仲裁丢失中断,CPU 会收到中断请求。
软件处理流程: 在中断服务函数中,检查 ARL 位。如果仲裁丢失,软件应清除 ARL 位,重置发送缓冲区指针,并等待总线空闲后重新尝试发送起始条件。切勿在仲裁丢失后继续发送数据,否则会破坏总线状态。

4.5 三种模式对比总结

特性 主机模式 从机模式 多主机模式
时钟产生 是 否 多个主机共同产生(线与)
起始/停止条件 由主机产生 检测 由赢得仲裁的主机产生
地址发送 发送 接收并匹配 发送并参与仲裁
总线冲突 无(单主机) 无 通过仲裁解决
XMC 典型应用 读取传感器、控制外设 响应主机请求 多 MCU 数据交换

4.6 调试实战:多主机仲裁测试

在 XMC 开发板上进行多主机仲裁测试时,建议按以下步骤操作:

  • 步骤 1: 将两块 XMC 开发板的 SDA 和 SCL 引脚短接,并各接 4.7kΩ 上拉电阻到 3.3V。
  • 步骤 2: 配置两块板卡为主机模式,设置相同的时钟频率(如 100kHz)。
  • 步骤 3: 编写测试代码,使两块板卡同时向同一从机地址(如 0x50)发送起始条件。
  • 步骤 4: 使用逻辑分析仪抓取 SDA 和 SCL 波形,观察仲裁过程。
  • 步骤 5: 检查两块板卡的 ARL 标志位,确认仲裁丢失的一方是否正确转为从机模式。
// XMC 多主机仲裁丢失中断处理示例
void I2C0_IRQHandler(void)
{
    uint32_t status = I2C0->STATUS;
    
    if (status & I2C_STATUS_ARL_MASK) {
        // 仲裁丢失
        I2C0->STATUS = I2C_STATUS_ARL_MASK;  // 清除标志
        I2C0->CON = 0;                        // 复位控制寄存器
        // 等待总线空闲后重试
        while (I2C0->STATUS & I2C_STATUS_BUSY_MASK);
        I2C0->CON = I2C_CON_MASTER_MASK | I2C_CON_START_MASK;
    }
    
    // 其他中断处理...
}
经验总结: 多主机仲裁调试中,最容易忽略的是上拉电阻的匹配。如果两个主机的上拉电阻差异过大,会导致 SDA 上升沿时间不一致,增加仲裁失败的概率。建议使用相同阻值的上拉电阻,并确保总线电容在允许范围内。