在 STM32 传输结束时,循环 DMA 外围到内存的行为如何?

Nik*_*iko 4 embedded usb spi stm32 dma

我想问一下,在以下情况下,STM32 中的 DMA SPI rx 将如何表现。我有一个名为 A 的指定(例如)96 字节数组,用于存储从 SPI 接收到的数据。我打开对每个字节进行操作的循环 SPI DMA,配置为 96 字节。是否有可能,当 DMA 将填充我的 96 字节数组时,传输完成中断将关闭,以快速将 96 字节数组复制到另一个 - B,然后循环 DMA 将开始写入 A(并破坏保存在 B 中的数据) ? 我想通过 USB 将数据从 B 快速传输(每次我从 B 中的 A 获取新数据时)到 PC。

我只是在想如何通过 USB 将 STM32 的连续数据流 SPI 传输到 PC,因为我认为每隔一定时间通过 USB 传输的 96 字节数据块比通过 STM32 将实时 SPI 流传输到 USB 更容易?我不知道这甚至可能

Cli*_*ord 5

为此,您必须能够保证在接收到下一个 SPI 字节并将其传输到缓冲区的开头之前可以复制所有数据。这是否可能取决于处理器的时钟速度和 SPI 的速度,并且能够保证不会发生可能延迟传输的更高优先级的中断。为安全起见,它需要极慢的 SPI 速度,在这种情况下可能根本不需要使用 DMA。

总而言之,这是一个坏主意,完全没有必要。为此,DMA 控制器具有“半传输”中断。当传输前 48 个字节时,您将获得 HT 中断,当您复制下半缓冲区时,DMA 将继续传输剩余的 48 个字节。当您完成转移时,您转移上半部分。这将您必须传输数据的时间从单个字节的接收时间延长到 48 个字节的接收时间。

如果每次传输实际上需要 96 字节,那么您只需将缓冲区设置为 192 字节长 (2 x 96)。

在伪代码中:

#define BUFFER_LENGTH 96
char DMA_Buffer[2][BUFFER_LENGTH] ;

void DMA_IRQHandler()
{
    if( DMA_IT_Flag(DMA_HT) == SET )
    {
        memcpy( B, DMA_Buffer[0], BUFFER_LENGTH ) ;
        Clear_IT_Flag(DMA_HT) ;
    }
    else if( DMA_IT_Flag(DMA_TC) == SET )
    {
        memcpy( B, DMA_Buffer[1], BUFFER_LENGTH ) ;
        Clear_IT_Flag(DMA_TC) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

关于通过 USB 将数据传输到 PC,首先您需要确保您的 USB 传输速率至少与 SPI 传输速率一样快或更快。USB 传输的确定性可能较低(因为它是由 PC 主机控制的——也就是说,当主机明确要求时,您只能在 USB 上输出数据),因此即使平均传输速率足够,可能存在需要进一步缓冲的延迟,因此与其简单地从 DMA 缓冲区 A 复制到 USB 缓冲区 B,您可能需要一个循环缓冲区或 FIFO 队列来馈送 USB。另一方面,如果您已经有了 buffer DMA_Buffer[0]DMA_Buffer[1]并且B您已经有效地拥有了三个 96 字节块的 FIFO,这可能就足够了