I2C挂死 I2C 接口进入 Busy 状态不能退出

问题:
       发生在 STM32 或者其它处理器上上。据其工程师讲述:在其产品设计中,使用了 STM32 的一个 I2C 接口与一个 EEPROM 通信。在系统靠性测试中发现,经过长时间运行后,STM32 会 出现不能读写 EEPROM 的现象。通过 NRST 管脚对 STM32 进行复位,复位后该现象依旧存在。关掉电 源,然后重新上电,现象消失。通过进一步测试发现,如果对 STM32 反复做复位操作,会很容易复现 这一现象。
调研:
       修改软件,通过打印监控 I2C 通信程序的流程,及 I2C 接口的各个寄存器的状态。当出 现上述现象时,I2C 接口的状态寄存器 SR2 中的 Busy 位置‘1’,状态寄存器 SR1 中的 ARLO 位置‘1’。用示波器观察 I2C 总线,发现其 SCL 为高电平,SDA 为低电平。将 STM32 的复位脚拉到地,SCL 及 SDA 的状态不变。检查原理图,确认 I2C 总线上只有 STM32 和 EEPROM 两颗器件。
结论:
       EEPROM 驱动 I2C 总线进入了非空闲状态,使得 STM32 在接管总线时发生总线仲裁失败,进而失去对总 线的控制,无法启动数据的传输。EEPROM 的这种状态可能是通信被意外中断造成的。通过对 STM32 进行复位而重现这一现象,在一定程度上吻合了这种猜测。但没有实验和理论依据证实一定是该原因 导致了这一问题,是否还有其它原因在起作用,不得而知。
处理:
       修改软件,加入对 I2C 总线修复的功能。在每次发送起始条件之前首先检测 SR2 中 Busy 位,如果为 ‘1’,则说明总线上有异常。此时,可由 GPIO 的 OD 模式代替 I2C 通信口接管 SCL 及 SDA 两个管 脚。通过翻转 GPIO,向 SCL 信号线上发高电平脉冲,脉冲宽度及间隔匀为 10uS。每发出一个脉冲之 后,检测 SDA 信号是否为高电平。若 SDA 信号为已高电平,则将 SCL 拉高,然后向 SDA 信号线发 出一个 10uS 宽的低电平脉冲。然后将 SCL 及 SDA 两个管脚交还给 I2C 接口,并通过将 CR1 中的 SWRST 位置‘1’后再清‘0’来复位 I2C 接口,使其退出 Busy 状态。如图(一)所示:


       A. 将 SCL 和 SDA 切换成 GPIO 的 OD 模式;
       B. 发送时钟脉冲并等待 SDA 跳变到高电平;
       C. 在 SDA 上发出一个低电平脉冲;
       D. 在 SDA 拉高后,将 SCL 的 SDA 切换回 I2C 接口;
       E. 通过 CR1 中的 SWRST 位复位 I2C 接口;
建议:
       STM32 中的 I2C 接口被设计成为主从自适应接口,并充许多个主机共享一条 I2C 总线。I2C 接口在被使 能之后,会不断的检测 SCL 及 SDA 的电平与跳变。当发现有低脉冲出现在 SCL 或 SDA 上时,则认 为总线进入了 Busy 状态,其 Busy 标志会置‘1’,直到在总线上检测到一个符合要的停止条件之 后,才认为总线回到了空闲状态,这时由硬件清除 Busy 标志。当 I2C 接口认为总处于 Busy 状态且不 是由自己占用时,会拒绝向总线上发送信号,因为它认为此刻 I2C 总线正在被其它的主机所使用。这时 向 I2C 接口发命令,要求产生起始条件,会导致总线仲裁失败。要从这种状态退出,首先要保证总线是 处于空闲状态,即 SCL 和 SDA 都为高电平。然后,通过将 CR1 的 SWRST 置‘1’然后清‘0’来复 位 I2C 接口,以达到清除 Busy 标志回到空闲状态目的。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: I2C(Inter-Integrated Circuit)是一种通信接口协议,用于在多个设备之间进行短距离的串行通信。当I2C接口进入busy状态时,会导致通信不能正常进行。 I2C接口进入busy状态可能有以下几种原因: 1. 主设备未正确发起或接收到终止条件:I2C通信需要主设备负责发起和接收终止条件,如果主设备在通信过程中未正确执行这些操作,就会导致I2C接口进入busy状态。 2. 通信速率过高或时钟信号不稳定:I2C通信速率过高或时钟信号不稳定会导致通信冲突,从而使接口进入busy状态。 3. 总线上存在其他设备故障:如果I2C总线上存在其他设备发生故障或者响应异常,就有可能导致接口进入busy状态。 解决I2C接口进入busy状态的方法如下: 1. 检查主设备的操作:确保主设备正确发起和接收终止条件,并且按照规定的时序进行通信。 2. 降低通信速率:通过降低I2C通信的速率,减少通信冲突的可能性,提高通信的稳定性。 3. 检查时钟信号:确保时钟信号的稳定性,避免因为时钟信号不稳定导致通信异常。 4. 排查其他设备故障:如果有其他设备存在故障或异常响应的情况,需要对这些设备进行修复或替换,以确保整个I2C总线的正常通信。 总之,在I2C接口进入busy状态时,需要仔细排查通信过程中的各个环节,找出故障的原因,并采取相应措施解决问题,以确保通信的正常进行。 ### 回答2: 当I2C接口进入busy状态后,无法及时退出的可能原因有以下几种: 1. 总线冲突:若多个设备同时尝试访问I2C总线,可能导致总线冲突,从而使接口进入busy状态。在这种情况下,需要排查总线上的其他设备是否存在问题,并确保每个设备在访问总线时进行适当的同步与互斥操作。 2. 错误的操作序列:样本手册或设备文档中给出了一系列必须按照特定顺序执行的操作步骤。如果这些操作步骤没有按照规定的顺序执行,可能会导致接口进入busy状态。此时,需要仔细检查操作序列是否正确并按照要求执行。 3. 软件或硬件错误:I2C接口的错误配置、错误的硬件电路连接或驱动程序错误等,都可能导致接口进入busy状态。在这种情况下,需要仔细检查软硬件环境是否正确配置,并对驱动程序进行调试和修复。 解决I2C接口进入busy状态的方法包括: 1. 重置I2C总线:可以通过硬件或软件手段对I2C总线进行复位操作,以清除可能导致接口进入busy状态的错误状态。一般来说,可以使用对应的寄存器位或I2C控制器提供的相关指令进行复位操作。 2. 避免总线冲突:合理规划I2C总线上的设备访问顺序和时间片分配,确保每个设备能够在合适的时机访问总线,避免冲突。此外,可以使用I2C设备的中断机制,让设备在准备好之后再主动请求访问总线。 3. 检查硬件和驱动程序:仔细检查I2C接口的硬件电路连接是否正确,检查驱动程序是否配置正确,并进行必要的调试和修复。 最后,需要注意的是,在解决问题时应综合考虑硬件、软件以及I2C设备本身的特性,以找到最适合的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值