繁体   English   中英

STM32 I2C中断方法需要阻塞while循环?

[英]STM32 I2C interrupt method requires a blocking while loop?

我有一个 Nucleo-F446RE,我正在尝试让 I2C 与我拥有的 IMU (LSM6DS33) 一起工作。 我正在使用 STM32CubeMX 并检查了与 I2C 相关的我的板的所有示例代码。 具体来说,我将讨论他们的“I2C_TwoBoards_ComIT”示例,但他们所有使用中断方法的示例都有同样的怪癖。 这是他们从 main.c 中截取的代码:

  /* The board sends the message and expects to receive it back */
  do
  {
    /*##-2- Start the transmission process #####################################*/  
    /* While the I2C in reception process, user can transmit data through 
    "aTxBuffer" buffer */
    if(HAL_I2C_Master_Transmit_IT(&I2cHandle, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
    {
      /* Error_Handler() function is called in case of error. */
      Error_Handler();
    }

    /*##-3- Wait for the end of the transfer ###################################*/  
    /*  Before starting a new communication transfer, you need to check the current   
    state of the peripheral; if it’s busy you need to wait for the end of current
    transfer before starting a new one.
    For simplicity reasons, this example is just waiting till the end of the 
    transfer, but application may perform other tasks while transfer operation
    is ongoing. */ 
    while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
    {
    }

    /* When Acknowledge failure occurs (Slave don't acknowledge its address)
    Master restarts communication */
  }
  while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF); 

在评论 ##-3- 他们解释说,除非我们等待 I2C 状态再次准备好,否则在发送命令后,下一个命令将覆盖前一个命令,因此他们使用等待 I2C 状态的 while 循环在继续之前“准备好”。

这不是使用中断的一种非常低效的方式,与使用标准轮询方法没有区别吗? 两者都阻塞了主代码,那么中断的目的是什么?

在我个人的示例中,我想以 IMU 能够达到的 1.66 kHz 速率收集加速度计/陀螺仪数据。 我使用 2kHz 定时器发送 I2C 命令以读取 acc/gyr 数据就绪寄存器,如果数据已为任一传感器准备好,我读取它们的 6 个字节以获取 x/y/z 平面信息。 使用轮询方法太慢了,因为以 2kHz 的速率阻塞代码并不是低效的,但是中断方法似乎并没有更快,因为我仍然需要在上述 while 循环期间挂起系统以检查 I2C 是否准备好接受另一个命令。 我在这里想念什么?

这(您提供的示例)是一种有效的做事方式吗? 不,可以避免阻塞部分吗? 是的。 这只是一个小例子,一个概念证明,所以那里有一些障碍。 您应该更深入地了解它存在的原因以及如何在不阻塞的情况下实现它的功能。

该阻塞部分的要点是在另一个 I2C 通信正在进行时不启动 I2C 通信。 问题是,虽然您通过 I2C 发送内容的代码行已经执行,但数据仍在物理上通过线路发送,只是因为您的 MCU 比 I2C 快得多。 您需要等到 I2C 线路空闲且可用于传输。

如何通过中断而不浪费周期和处理时间来实现这一点? 在您的情况下,您可以轻松估计每次传输的数据量,没有问题可以估计在您的 I2C 速度下每次传输将花费多少时间。 由于您巧妙且正确地使用计时器来安排定期传输,因此您应该能够设置计时器,以便在下一个将发送数据的计时器中断时,您之前的通信已经结束。

例如,如果您将定时器设置为 1Hz 开始传输,您显然可以确定到下一次中断时所有通信都已发生。 你根本不需要投票。

如果它以 1.6kHz 产生数据,我认为以 2kHz 的频率对 IC 进行 I2C 轮询没有多大意义。 样本之间的时间段会不均匀,一些数据会非常新鲜,而一些数据会延迟很少,另外还会有没有准备好数据的通信。 最好以 1.5-1.6kHz 的频率对其进行轮询,并期望数据始终存在。 当然,鉴于通信适合 1.5kHz 周期,这需要一些餐巾数学。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM