interrupt - STM32 SPI 在使用中断时丢弃数据

标签 interrupt stm32 spi

我正在尝试使用中断通过 SPI 发送可变大小的字节数组。该系统由两 block nucleo STM32L432板组成。发送器板工作正常,但接收器板有问题。具体来说,我注意到经常会丢失一些字节。除了 CubeMX 提供的默认初始化之外,我的 init 函数中还有以下设置:

// Trigger RXNE when the FIFO is 1/4 full
LL_SPI_SetRxFIFOThreshold(sw.spi_sw2pc,LL_SPI_RX_FIFO_TH_QUARTER);

// Enable RXNE interrupt
LL_SPI_EnableIT_RXNE(sw.spi_sw2pc);

// Enable SPI
if((SPI3->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
{
    // If disabled, I enable it
    SET_BIT(sw.spi_sw2pc->CR1, SPI_CR1_SPE);
}

SPI 设置为以 10 Mbit/s 的速度工作。难道是通讯速度太快了?

以下是 IRQ 处理程序和回调。

IRQ 处理程序

void SPI3_IRQHandler(void)
{
  /* USER CODE BEGIN SPI3_IRQn 0 */
  /* Check RXNE flag value in ISR register */
    if(LL_SPI_IsActiveFlag_RXNE(SPI3))
    {
        /* Call function Slave Reception Callback */
        SW_rx_callback();
    }

  /* USER CODE END SPI3_IRQn 0 */
  /* USER CODE BEGIN SPI3_IRQn 1 */

  /* USER CODE END SPI3_IRQn 1 */
}

回调

void SW_rx_callback(void)
{
    // RXNE flag is cleared by reading data in DR register

    while(LL_SPI_IsActiveFlag_RXNE(SPI3))
        recv_buffer[recv_buffer_index++] = LL_SPI_ReceiveData8(SPI3);

    if(LL_SPI_GetRxFIFOLevel(SPI3) == LL_SPI_RX_FIFO_EMPTY)
    {
        // If there are no more data
        new_data_arrived = true;
        memset(recv_buffer,'\0',recv_buffer_index);
        recv_buffer_index = 0;
    }

}

预先感谢您的帮助。

最佳答案

10 Mbits 上的 SPI 意味着每秒将有 125 万个中断(在 8 位传输的情况下),这足以通过中断进行处理,尤其是与 HAL 结合使用。

STM32L4xx 速度相当快 (80MHz),但在这种情况下,这意味着每个中断调用所花费的时间不能超过 64 个周期。但是调用中断需要 12 个周期,退出中断需要 10 个周期(它处于理想状态,总线上没有等待状态),因此如果您的中断代码需要 42 个或更多周期,那么您可以确定您错过了一些字节。

以下是我的建议:

  • 首先尝试启用一些编译器优化,以加快代码速度。
  • 更改中断例程并从中断处理程序中删除所有不必要的内容(使用 SW FIFO 并在主循环中处理接收到的数据)
  • 但根据您的情况,最佳解决方案可能是使用 DMA 传输。

关于interrupt - STM32 SPI 在使用中断时丢弃数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50730710/

相关文章:

embedded - SPI通信中CPOL/CPHA设置的使用

java - JNI 代码在 Windows XP 中工作正常,但在 Windows 7 中崩溃

linux - 有没有办法检查中断是否被处理?

c - 8051 中外部中断的质数例程

stm32 - 使用 HAL 驱动程序在 stm32 上进行 EEPROM 仿真

linux - 使用 STM32F1 MCU 处理损坏的 SPI 数据

c - PSoC 1 中不同引脚的 GPIO 中断

c - map 文件中 STM32 的 IAR 堆栈使用情况

c++ - memcpy 命令在复制时交替数据

keycloak - 为什么 Keycloak 不断重新部署相同的 .jar 文件?