60 秒回答模板

双线总线被从机一直拉低,常见是从机状态机卡在传输中、主机中途复位、时钟丢失或从机在等待继续移位。软件恢复一般先停止控制器传输,确认是 SCL 低还是 SDA 低;如果 SCL 被从机拉低,可能是 clock stretching 或硬件故障,要有超时;如果 SDA 被拉低,常见做法是把引脚临时切到 GPIO/open-drain,释放数据线,手动输出最多 9 个时钟脉冲,让从机把剩余位移出,然后在 SCL 高时产生 STOP 条件,也就是 SDA 从低释放到高。之后恢复引脚复用、重新初始化控制器并重试。若仍不释放,就通过 reset-gpio、电源开关或外设复位处理。整个过程要避免推挽强拉高、避免多个主机同时恢复,并记录错误计数。

考点 故障判定
难度 真实面经题
回答目标 展示自己能按总线电气规则实现安全的挂死恢复流程。

深入解析

01

先判断被谁拉低

SDA 低常见于从机还在输出数据或等待时钟;SCL 低可能是从机时钟拉伸、控制器状态异常或硬件短路。不同线低,恢复策略和风险不同。

02

恢复前先停控制器

要关闭当前传输、清控制器错误状态,并把引脚切到安全的开漏 GPIO 模式。不能在控制器还占用引脚时又用 GPIO 强行翻转,避免状态更乱。

03

手动时钟释放从机

对 SDA 被拉低的常见情况,主机释放 SDA 后手动 toggling SCL,通常最多 9 个周期,让从机完成一个字节和 ACK 位的状态机。随后在 SCL 为高时产生 STOP,通知从机回到空闲。

04

失败后走硬复位

如果脉冲和 STOP 后仍低,说明从机或线路可能更严重异常。应尝试外设复位、断电重上电、切换 mux 通道或上报不可恢复错误,而不是无限重试。

易错点

  • 不区分 SCL 低和 SDA 低,所有情况都盲目发时钟。
  • 用推挽 GPIO 强拉高被从机拉低的线,造成电气冲突。
  • 恢复后不重新初始化控制器和清错误状态。
  • 无限重试软件恢复,不设计从机复位或错误上报。

面试官追问

为什么常说 9 个时钟?

因为一个字节 8 位加 1 个 ACK/NACK 位,给足时钟通常能让从机移完当前状态机并释放数据线。

能不能直接把 SDA 配成推挽输出高电平?

不建议,甚至危险。如果从机正在拉低,主机推高会形成总线争用;应该用开漏释放加上拉让它自然回高。

如果板子上通信不稳定,你会怎么定位?

先用示波器或逻辑分析仪确认电平、时序、速率和帧格式,再对照驱动日志、错误码、重试次数和协议状态机,区分硬件连接、配置参数、总线仲裁和软件缓冲问题。