重中断负载下I2C读/写失败


10

在我的系统中,我正在使用I2C,并且我意识到在繁重的中断负载(来自其他来源)下,I2C通信很容易中断。这是I2C的预期行为吗?我本来希望尽管有中断负载,但仍然可以,因为I2C并非完全是时间紧迫的接口,时钟随数据一起提供。

更新:

处理器是STM32。中断是由于ADC引起的,因此我无法在读取事件期间禁用中断,因此我必须找到一种可以使i2c通信更加稳定的解决方案。STM32是主设备,从设备是另一个设备(加速度计)。

更新2:

当我用一根小的飞行电缆将逻辑分析仪连接到时钟时,问题就消失了。有趣的是,没有中断加载,读写工作良好,有中断加载却没有。但是,如果我将探针连接到时钟上,则在中断负载下也可以进行读写操作。我认为某个地方存在电容问题。


1
您的问题非常笼统,因为这完全取决于系统的设计。I2C的处理方式实际上取决于总线上的设备。您可以忽略它们,然后再讨论吗?在FPGA中,您可以设计逻辑来为您处理很多事情并避免这种情况。同样,我们需要有关微控制器以及您所拥有的其他东西的更多信息。通常,这里的一个好的解决方案是使用RTOS并正确设计任务。
Gustavo Litovsky

有两件事情需要寻找,上拉电阻或i2c主从电源上的电压骤降,或者emi或电容问题。至于中断负载,您是说您的主机正在停止处理中断吗?有些芯片不允许无限的时钟延长。
路人2013年

@GustavoLitovsky,您是对的,但是80%的CPU周期正在处理ADC中断,并且没有足够的时间在非ISR窗口内执行读取周期。因此,无论我对OS系统的设计如何,读取都会中断。
Ktc

@Passerby,您可能是正确的。当我将逻辑分析仪的探头连接到时钟线上时,问题消失了。
Ktc

您现在的上拉值是多少?您是否尝试过将它们更改为其他值?(尝试首次尝试10k或4k7或2k)
Tom L.

Answers:


9

这是一个软件问题,您花费太多时间为中断服务,并且您的I2C例程无法处理中断(因此这是两件事,这是不对的)。我经历过几种类似的情况。

第一:您需要在中断中做尽可能少的事情,只读取和存储数据,不做在ISR之外可以做的任何处理,数学可能会占用很多CPU周期,而CPU无法做其他任何事情在那个中断中。

第二:研究DMA以使事情自动化,因此中断几乎变成了后台自动化过程。

第三:如果I2C很重要,请将THAT也置于中断中,但请确保确定优先级!

第四:弄清楚为什么您的I2C例程失败,I2C本身可以承受非常间歇的时间,暂停和等待等,因此您的例程可能需要修改以允许这样做。

第五:看看是否可以“链接”中断,您可能会发现可以更有效地服务ADC读数,或者将ADC置于其他模式,在中断之前它会为您做更多的工作(例如,EG等待所有读数可用,然后一次读取所有内容,而不是8个单独的ADC通道读取的8个单独的中断)。

第六:使用示波器或逻辑分析仪以及板上的备用IO引脚,以跟踪您花费在每一位代码上的时间,以查看是否可以加快速度。(进入功能/ ISR时将引脚设置为高电平,退出时再次将其设置为低电平)。

第七点:确定您是否真的需要阅读大量ADC资料,变慢会使情况变得更糟吗?这是违反直觉的,但有时运行速度较慢实际上会带来更好的结果,为您平均信号并减少可能引起问题或需要额外处理才能消除的尖峰/瞬变。我们通过简单地以1/4的速度运行改进了电动机控制PID例程,从而释放了过程中的CPU时间。


感谢您的建议。问题以某种方式指向硬件。
Ktc

4

忙于其他事情的总线从站能够通过时钟延长时间来购买时间,直到它能够继续进行通信。它通过不立即发送ACK / NACK时钟脉冲来做到这一点,将通信保持在中间状态,直到准备好应答为止。

时钟延长是处理此类情况的适当方法。无法伸展并执行其他不良操作(总线挂起/重新启动,NACK有效地址或命令等)的设备可能会出现问题,并给主机带来额外负担,使设备无法整理(必须重复执行命令) ,跟踪NACK等)


您说得对,但问题出在房东。主机忙于其他事情,而不是奴隶。所以不确定我是否可以延长时钟时间。
Ktc

您是使用板载I2C硬件还是将协议从GPIO线中逐位跳出?标准中没有定义特定的I2C超时间隔,因此从机应无限期地等待主机完成数据包。
亚当劳伦斯

我使用STM32 IC2 API。请查看更新,它看起来像是电容问题。
Ktc

1

根据STM32的功能(我从未使用过),您可以尝试以下方法之一。如果您可以提供有关您要执行的操作的更多详细信息,并且有说服力的论据说明为什么每个中断都必须以您现在拥有的形式来使用,那么可以考虑一个更具体的答案。但是,具体而言,对于您的情况,I2C足够慢,因此对于编写良好的中断例程而言,这不会成为问题。

  • 通常可以禁用任何中断。在任何通常的控制器中最多有一个或两个不可屏蔽的中断,其中之一被复位。如果不需要中断驱动的控制(在您的情况下为ADC或I2C),则将该外设代码转换为不使用中断的代码,然后禁用中断。

  • 中断处理程序不应太长。尝试从中断向量本身做尽可能少的事情。极简的中断方法是在中断处理程序例程中简单地设置一个标志,然后说让主循环从那里开始进行所有繁重的工作。您的特定应用程序和固件体系结构所需要的可能不像这样做,但确实值得付出努力,以查看中断中必须实际执行的工作量。

  • 如果您有外设DMA,请使用它而不是在每个字节处进行中断。通常,与I2C相比,将ADC置于DMA上更为容易,但是不同的芯片具有不同的实现。如果也有一种将I2C交换与DMA隔离的干净方法,我也不会感到惊讶。DMA使您减少了中断次数,并使处理器内核不必处理每个数据块。

  • 尝试确定您看到数据损坏的特定实例,以及发生数据损坏的机制。这很难做,但是创造性地使用现代示波器/逻辑分析仪,您可能会发现一些问题。具体来说,请确保问题与定时有关,而不与内存有关(这可能是可怕的代码和自由编译器的组合)

编辑:从您对问题的评论中,可以看到与此问题实例有关的一些具体说明:

  • 通常没有80%的CPU用于读取ADC。如果您无法采取行动,甚至无法保存数据,则收集数据将毫无用处。
  • 即使您以某种方式收集(有用)大量数据,ADC中断的时间也不应长到足以完全抑制I2C外设一段时间,以使其丢失数据。I2C的最高频率为100 / 400KHz。您需要一个非常长的中断来中断足够长的时间,以使其看起来比I2C上的时钟抖动更为严重。

谢谢。我们的系统需要这种类型的复杂且较长的ISR,这是一个很长的故事。没错,即使在这种中断负载下,I2C也必须维持,但事实并非如此。我怀疑问题出在硬件上,请参阅更新。
Ktc

以我的经验,就其价值而言,大多数似乎需要极长的ISR的用例实际上都是值得使用RTOS的用例。是的,根据您的最新编辑,它似乎确实是硬件问题。尝试在逻辑分析仪所在的线路上插入一个小电容器,可能会没事的。但是,为什么有必要这样做却很难回答。我将检查I2C上拉电阻(对于总线电容而言可能太低),并检查您可能使用的任何I2C缓冲器/中继器的数据表。
Chintalagiri Shashank

0

在给定的系统中,可能会有噪声进入时钟和数据总线。您的逻辑分析仪消除了问题的事实表明了这一点。为了实现实用和快速的实施,只需遵循观察到的提示即可。基于类似的观察,在以400kbits / sec实现的i2c总线上,我从时钟和数据点将与12pf并联的2M连接到地面,发现问题已解决。这样可以去除/过滤特定i2c通信所需的感兴趣频段之外的噪声。请尝试并提出建议。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.