电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

987

主题

987

帖子

8520

积分

高级会员

Rank: 5Rank: 5

积分
8520
发表于 5 天前 | 显示全部楼层 |阅读模式

k1shsxsr33r64042667020.gif

k1shsxsr33r64042667020.gif
, ?+ Y9 g) v1 [0 ]- F
点击上方蓝色字体,关注我们& R. [' q$ Q/ n& f' `2 N
2 I- |9 P) q* R! X* H4 n( G

0 C$ V$ I8 A3 ^1 v4 ^  g# E! nI2C 死锁是指总线被卡住,无法继续通信的情况,通常由从设备意外拉低 SDA 或 SCL 线引起,导致主设备无法发起新的事务。* i( |* p# Z( W* k# o$ @# }

4 W, s+ r2 q& C/ P0 ]. Y! U/ ^

d5mhts4gmqm64042667120.png

d5mhts4gmqm64042667120.png
! I; V& k! f( M8 F; F+ t
: z6 G. Z8 |/ F$ }& Y$ `
死锁的常见成因包括:' z0 m6 E8 B  G  [  w  f
  • 噪声或干扰:外部电磁干扰可能导致 SCL 的时钟边沿丢失或 SDA 数据错误。例如,噪声可能使从设备误认为通信仍在进行,从而保持 SDA 低电平。
  • 启动时的毛刺:系统上电或复位时,I/O 信号可能出现短暂脉冲,导致从设备误判状态,卡住总线。
  • 软件问题:如在事务中间断点调试或软件崩溃,主设备可能未正确结束通信,从设备仍等待时钟脉冲。% S* Q) u$ Q, w1 R( J
    例如,若主设备在读取数据过程中重启,而从设备仍在传输模式,SDA 线可能被持续拉低,形成死锁。  v# t- T& A5 t5 y
    - S2 m7 j) `0 E, x9 r

    eeeeuhpkgo464042667220.png

    eeeeuhpkgo464042667220.png
    9 q) ]; g" D% D
    1
    - r+ r/ g! F, c! e死锁的检测方法4 j( H! N2 C+ P: j/ d7 H
    检测 I2C 死锁的主要方法是使用超时机制。在 I2C 通信过程中,设置一个定时器,若总线访问或数据传输未在预期时间内完成,则触发死锁检测。7 p" Y. k; }& L/ `9 e2 a8 S$ ~

    % l; S1 s7 `) q# ^3 t8 o0 i具体实现可以是:- j! a7 E4 S4 G# Y  N; L0 G
  • 在每次 I2C 事务开始时启动定时器。
  • 若事务超时(例如 35 ms,参考 SMBus 建议),则认为总线可能被卡住。
    : V. p+ u0 a% t/ ~

    - [: V% t: c, M3 s* U0 s这种方法在软件层面实现,无需额外硬件支持。证据倾向于这种方法在实时系统中效果显著,尤其是在检测从设备卡住时。; f$ v; q0 m6 Q7 B9 p4 R
    2
    , c% f( n& Q% P; |4 j9 |死锁的预防措施
    + y& P, q: p) x- a+ x3 c预防 I2C 死锁的硬件和软件措施包括:
    6 d' \1 }  R" x" I" W
    - O0 u( z- s4 s& Y, L4 ^硬件设计* R5 C) N; s8 @
  • 使用强拉电阻:推荐 4.7kΩ 的拉电阻,加速 SDA 和 SCL 的上升沿,减少噪声影响。
  • 确保主设备 I/O 默认高电平:复位后通过拉电阻保持高电平,避免启动毛刺。
  • 使用 I2C 开关:将总线分成多个分支,若某分支挂起,可通过开关隔离故障设备。例如,NXP 的 PCA9540(2 通道)或 PCA9548(8 通道)支持动态分支管理。
    - _# D5 P4 X2 ]4 p. D$ Z' @: U2 \

    54x4x01vby064042667320.png

    54x4x01vby064042667320.png

    0 k7 @/ [& m& \$ f/ `4 e" w. e% R0 w
    : k( X8 o) r4 }7 \" a软件设计
    2 z7 ?# a7 o6 a) q
  • 避免在事务中途中断主设备程序。
  • 在系统启动时执行恢复序列,清除可能的初始死锁。( _# N7 q6 H) f" Q

    ; g3 V1 N2 s8 I) N/ i' Q: P

    plpfjcnu2ew64042667420.png

    plpfjcnu2ew64042667420.png
    ; U9 s7 ^& W) @: K' x  V
    3
    . b# S/ |% v/ N. j- S/ x: c: p  q死锁的解决策略
    * @3 @1 t: _$ N1 t解决 I2C 死锁的方法分为软件和硬件两种。
    ) K2 C& a5 ~2 A* ]& X9 O# Z0 S5 Z! {3 u: Q
    软件方法6 l8 k2 Y' D6 V" u/ w. v
    通过主设备手动生成至少10个时钟脉冲,强制从设备释放总线。这是基于 I2C 规范的恢复机制,通常需要9个时钟脉冲传输一个字节数据,额外一个脉冲确保释放。
    & h$ P: a. p; s. I3 o
    5 o: Q7 O9 L0 C& C5 H% ?: r
  • #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 模式}
    , Q" b- _; b* Q* w' t; z5 o

    34scsn4y5g464042667520.png

    34scsn4y5g464042667520.png
      g; S5 n5 z" {0 e; q
    % n3 _) T, F: g9 P
    硬件方法" e% `8 v. M( s7 B0 [9 H: Y+ B
    若从设备有复位引脚,可通过硬件信号重置设备,恢复通信。
    , D0 E3 \+ I6 j" q2 `( g" b使用 I2C 开关隔离故障分支,保持其他分支正常工作。例如,若某分支的从设备挂起,可通过 PCA9540 编程关闭该分支。8 s. t, c# i" K( `& U8 i

    " B1 ^( {9 |; x- B+ ]/ V

    cqnf025r4ov64042667621.png

    cqnf025r4ov64042667621.png
    3 [7 u2 A7 R# f3 Y: D! C

    5 C1 I2 v& o! E" f# @4 K, D# LI2C 死锁虽然可能发生,但通过超时检测、强拉电阻预防以及时钟脉冲恢复,可以有效解决。硬件隔离(如 I2C 开关)进一步提升系统可靠性,适合复杂嵌入式应用。掌握这些方法,可显著提高嵌入式系统的稳定性和用户体验。
    - v- v% c0 t: Q- f. x! ]

    b4drlp3jbwl64042667721.jpg

    b4drlp3jbwl64042667721.jpg

    9 x" L6 @3 p: F3 `

    el3aynbob3f64042667821.gif

    el3aynbob3f64042667821.gif

    9 O7 {* \0 }+ W5 A2 K点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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