简体   繁体   English

使用中断时STM32 SPI丢弃数据

[英]STM32 SPI dropping data while using interrupt

I'm trying to send a variable size array of bytes over SPI using interrupts. 我正在尝试使用中断通过SPI发送可变大小的字节数组。 The system is composed by two nucleo STM32L432 boards. 该系统由两个核STM32L432板组成。 The sender board works fine, but I'm having issue with the receiver board. 发送器板工作正常,但是接收器板出现问题。 Specifically, I noticed that very often some bytes are dropped. 具体来说,我注意到很多时候会丢弃一些字节。 Beyond the default initialization provided by CubeMX, I have also the following settings in my init function: 除了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);
}

The SPI is set to work at 10 Mbit/s. SPI设置为以10 Mbit / s的速度工作。 Can it be that the communication speed is too fast? 可能是通讯速度太快了吗?

Following are the IRQ handler and the callback. 以下是IRQ处理程序和回调。

IRQ handler 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 */
}

Callback 打回来

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;
    }

}

Thank you in advance for your help. 预先感谢您的帮助。

SPI on 10 Mbits mean that you will have 1.25 millions interrupts per second (in case of 8bit transfer) and this is quite enough to process by interrupts especially in combination with HAL. 10 Mbit的SPI意味着您每秒将有1.25百万个中断(在8位传输的情况下),这足以处理中断,尤其是与HAL结合使用时。

STM32L4xx is quite fast (80MHz) but in this case it mean that every interrupt call can't take longer than 64 cycles. STM32L4xx的速度非常快(80MHz),但是在这种情况下,这意味着每个中断调用都不能超过64个周期。 but calling interrupt take 12 cycles, exit interrupt 10 cycles (it is in ideal state with no wait states on bus) so if your interrupt code will take 42 or more cycles then you can be sure that you miss some bytes. 但是调用中断需要12个周期,退出中断需要10个周期(它处于理想状态,总线上没有等待状态),因此,如果您的中断代码需要42个或更多个周期,则可以确保丢失某些字节。

Here are my suggestions: 这是我的建议:

  • First try to enable some compiler optimizations, to speed-up the code. 首先尝试启用一些编译器优化,以加速代码。
  • Change interrupt routine and remove everything unnecessary from interrupt handler (use SW FIFO and process received data in main loop) 更改中断例程并从中断处理程序中删除所有不必要的内容(使用SW FIFO并在主循环中处理接收到的数据)
  • But best solution in your case can be to use DMA transfer. 但是,根据您的情况,最佳解决方案是使用DMA传输。

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

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