电子产业一站式赋能平台

PCB联盟网

搜索
查看: 77|回复: 0
收起左侧

如何检测和解决I2C通信死锁

[复制链接]

1001

主题

1001

帖子

8807

积分

高级会员

Rank: 5Rank: 5

积分
8807
发表于 2025-4-11 08:01:00 | 显示全部楼层 |阅读模式

k1shsxsr33r64042667020.gif

k1shsxsr33r64042667020.gif
* i! `% Q5 I# ~6 p  M# S! M6 U
点击上方蓝色字体,关注我们
5 @. Y0 P8 U/ R- Y4 |0 @; X
) `. J2 i6 r# S
4 D6 z/ e9 V/ MI2C 死锁是指总线被卡住,无法继续通信的情况,通常由从设备意外拉低 SDA 或 SCL 线引起,导致主设备无法发起新的事务。
2 l- X( }- I8 k, o, l) D, S0 e) G7 b6 {0 o

d5mhts4gmqm64042667120.png

d5mhts4gmqm64042667120.png

5 X: l. a6 x- l1 t8 @7 g
* A) C. k; D  {! O死锁的常见成因包括:
1 G9 E- |- h0 y4 ]7 x
  • 噪声或干扰:外部电磁干扰可能导致 SCL 的时钟边沿丢失或 SDA 数据错误。例如,噪声可能使从设备误认为通信仍在进行,从而保持 SDA 低电平。
  • 启动时的毛刺:系统上电或复位时,I/O 信号可能出现短暂脉冲,导致从设备误判状态,卡住总线。
  • 软件问题:如在事务中间断点调试或软件崩溃,主设备可能未正确结束通信,从设备仍等待时钟脉冲。
    " v# q4 |6 e6 g  D/ D) W# x例如,若主设备在读取数据过程中重启,而从设备仍在传输模式,SDA 线可能被持续拉低,形成死锁。* F; k8 B7 A4 k$ T9 U7 e0 U" d

    9 G* N) \& L8 W% K. o- R0 i

    eeeeuhpkgo464042667220.png

    eeeeuhpkgo464042667220.png
    ( \( I6 s' N9 |, B4 F. N. |
    1
    - N; i2 @+ Z/ Y; O8 R死锁的检测方法
    + C6 l- L- ~/ |# o) B% u) b检测 I2C 死锁的主要方法是使用超时机制。在 I2C 通信过程中,设置一个定时器,若总线访问或数据传输未在预期时间内完成,则触发死锁检测。& _3 U" g; [- ~- e

    2 J- w4 g# ^2 g2 g* O) g具体实现可以是:/ {3 k# o7 m- C
  • 在每次 I2C 事务开始时启动定时器。
  • 若事务超时(例如 35 ms,参考 SMBus 建议),则认为总线可能被卡住。9 Z1 b" L5 M: t0 J
      i! e1 h" w# S: G* O) V
    这种方法在软件层面实现,无需额外硬件支持。证据倾向于这种方法在实时系统中效果显著,尤其是在检测从设备卡住时。, }% [3 E# E; r/ F: g. ~
    2
    + x5 S& S; y4 L8 l7 Y1 l死锁的预防措施
    0 n3 U6 K+ S4 Q& T4 W3 I预防 I2C 死锁的硬件和软件措施包括:- z# g; Q3 e0 v
    1 t7 S( A6 K7 R+ \
    硬件设计/ E/ F; o/ }9 u# u, |* V
  • 使用强拉电阻:推荐 4.7kΩ 的拉电阻,加速 SDA 和 SCL 的上升沿,减少噪声影响。
  • 确保主设备 I/O 默认高电平:复位后通过拉电阻保持高电平,避免启动毛刺。
  • 使用 I2C 开关:将总线分成多个分支,若某分支挂起,可通过开关隔离故障设备。例如,NXP 的 PCA9540(2 通道)或 PCA9548(8 通道)支持动态分支管理。" f3 Y9 y( C- g( m" n+ G. J

    54x4x01vby064042667320.png

    54x4x01vby064042667320.png
    ) o- J: ~3 n; {! _% a  L

    # \+ _' [9 y& n- c% t7 t软件设计, U8 G6 R$ _6 O  l2 K
  • 避免在事务中途中断主设备程序。
  • 在系统启动时执行恢复序列,清除可能的初始死锁。
    0 H# @; ~! z  F) Z& e4 z

    5 n3 M8 e- v& A3 L1 \

    plpfjcnu2ew64042667420.png

    plpfjcnu2ew64042667420.png
    7 y% @4 F& z: }2 N7 m8 Z
    3
    & X. F. e/ Q- l' b; i死锁的解决策略/ s9 z$ s4 [3 v- A/ i
    解决 I2C 死锁的方法分为软件和硬件两种。
    # E& Z- ?: ^4 r' ^  R2 q$ B' [
    ) i" w7 n- a" i) ~软件方法9 r8 f, _* `/ k0 ]0 F2 x# n4 }" Y! V
    通过主设备手动生成至少10个时钟脉冲,强制从设备释放总线。这是基于 I2C 规范的恢复机制,通常需要9个时钟脉冲传输一个字节数据,额外一个脉冲确保释放。
    8 @+ I) `6 R2 S2 _; D: ]5 X; |* ?' J. l. |' H- L3 I) G
  • #define I2C_RECOVER_NUM_CLOCKS 10U#define I2C_RECOVER_CLOCK_FREQ 50000U#define I2C_RECOVER_CLOCK_DELAY_US (1000000U / (2U * I2C_RECOVER_CLOCK_FREQ))void i2c_recover(void) {    // 将 SCL 配置为 GPIO 输出    // 初始化 SCL 为高电平    for (uint32_t i = 0; i         // 将 SCL 拉低        delay_us(I2C_RECOVER_CLOCK_DELAY_US);        // 将 SCL 拉高        delay_us(I2C_RECOVER_CLOCK_DELAY_US);    }    // 重新配置 SCL 为 I2C 模式}; l5 X5 t0 N; @* |8 y

    34scsn4y5g464042667520.png

    34scsn4y5g464042667520.png
    6 X9 K7 `* Y7 x- p( D3 r

    3 u, k5 t5 v7 d/ }' R7 f" \硬件方法+ O" ?; r# ~  m) M
    若从设备有复位引脚,可通过硬件信号重置设备,恢复通信。
    : r/ L, d" b: a/ n+ Y) Q8 M* H0 V( E使用 I2C 开关隔离故障分支,保持其他分支正常工作。例如,若某分支的从设备挂起,可通过 PCA9540 编程关闭该分支。
    6 f6 y9 L, m  p9 E0 f% z# z" d0 o7 {! S- t. v  N

    cqnf025r4ov64042667621.png

    cqnf025r4ov64042667621.png
    ) [, y6 F, ^; g0 ~1 @2 o  N
    % I5 Y" z! f. _
    I2C 死锁虽然可能发生,但通过超时检测、强拉电阻预防以及时钟脉冲恢复,可以有效解决。硬件隔离(如 I2C 开关)进一步提升系统可靠性,适合复杂嵌入式应用。掌握这些方法,可显著提高嵌入式系统的稳定性和用户体验。
    1 |$ ]! f! B, }

    b4drlp3jbwl64042667721.jpg

    b4drlp3jbwl64042667721.jpg

    2 c$ c7 N2 s7 T2 K/ s% Z

    el3aynbob3f64042667821.gif

    el3aynbob3f64042667821.gif
    $ f; t( @$ j- P6 B2 t
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表