stm32 - 是否可以在 STM32F3 上使用 DMA 通过 SPI 传输无限数据?

标签 stm32 dma radio-transmission

我正在开发一种基于新协议(protocol)的 RF 调制解调器,该协议(protocol)具有在一帧中传输 96 字节的功能 - 但它们会在通信结束之前不断发送。我计划在 STM32 中使用两个 96 字节缓冲区 - 在下一行中我将解释原因。

我想通过 USB-CDC 将前 96 字节帧发送到 STM32 - 然后外部调制解调器芯片将生成“9600bps”时钟,STM 必须在指定的输出引脚上逐位写入有效负载(在每个时钟脉冲)。 当STM32注意到它已经发送了一半的96字节帧时——它向PC发送通知发送更多数据——PC将立即通过USB-CDC重新填充第二个96字节缓冲区。当 STM32 结束发送第一个缓冲区时 - 立即开始发送第二个缓冲区内容。当它将发送第二个缓冲区的一半时 - 如前所述,它将向 PC 请求另一个 96 字节帧。 一直这样,在 PC 发送命令停止 tx 之前。

此传输模式 - 串行,使用“触发时钟”。 使用 DMA 可以实现这一点吗?我该如何设置它? 我想使用 DMA 来使用 USB,同时将数据传输到 radio 调制解调器芯片。这是正确的方法吗?

我正在构建一个开源 radio 通信系统项目,该项目具有数据包和流功能以及数字语音。我正在为 PC radio 调制解调器设计电子产品。项目名为 M17,由 Wojtek SP5WWP 维护。

最佳答案

  1. 回复。通用架构。 USB ACM 上的串行通信不必使用相同大小的缓冲区,并且与 SPI 上的下游通信同步。您可以使用尽可能大的缓冲区,以便 PC 可以提前发送数据。如果 PC 提供数据的速度不够快,这将减少缓冲区下溢的机会。使用循环缓冲区并在数据包从 USB 到达时填充它。

  2. DMA 是正确的方法。尽管人们经常说 DMA 仅在高带宽操作时才需要,但实际上使用 DMA 可能比处理每个字节的中断更容易,即使您每秒只处理 9600 位。

  3. STM32F3 中的 DMA Controller 具有半传输完成(DMA_ISR 中的 HTIF)位,您可以轮询该位或使其生成并中断。结合传输完成状态 (TCIF) 和循环位(DMA_CCR 中的 CIRC),您可以组织双缓冲数据管道,以便传输可以与 MCU 正在执行的任何其他操作重叠。应用程序将在 HTIF 事件上重新加载 DMA 缓冲区的前半部分。当 TCIF 事件发生时,它会重新加载后半部分。必须在另一半完成之前尽快完成。然而,只有当您需要不断地传输数据时,即总量大于 DMA 缓冲区的大小时,您才需要双缓冲管道。 停止循环 DMA 可能很棘手。我想STM32和外部芯片都知道要发送多少字节。在这种情况下,收到此金额后,禁用 DMA。

  4. STM32 中似乎需要一个从 SPI,因为外部芯片生成 SPI 时钟。

  5. DMA 的设置并不困难,但是它需要多种东西才能正常工作。我假设寄存器级编程,如果您使用某种框架,您将需要找出它如何实现这些功能。启用 SPI 时钟、SPI 引脚的 GPIO 端口和 DMA,将引脚配置为 AF。为 SPI 外设找到正确的 DMA channel 。对于 SPI DMA,您通常需要两个 channel :TX 和 RX,但对于从属 SPI,您可能只需要一个 channel 。配置 SPI,注意时钟极性和相位,并将其设置为为每个 TX 和/或 RX 生成 DMA 请求。设置指向 channel 中 SPI DR 寄存器的 DMA CPAR channel 寄存器,并对所有其他 DMA channel 寄存器进行适当编程。启用 DMA channel 。在从机模式下启用 SPI。当 SPI 主时钟在 MOSI/SCK 引脚上提供数据时,DMA Controller 会将它们放入内存中。当缓冲区半满和满时, channel 将设置 HTIF 和 TCIF 位,并生成和中断(如果您指定)。使用这些事件来实现流量控制。

关于stm32 - 是否可以在 STM32F3 上使用 DMA 通过 SPI 传输无限数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59397307/

相关文章:

嵌入式目标上的 C++ : Low overhead storage backend

contiki - 将 cc2530 radio 与 Contiki 结合使用

通过 radio 波(业余 radio )的 GPS 跟踪系统?

python - 树莓派串口数据传输输入输出延迟

linux - 在用户空间使用 DMA 内存传输

c - 中断和DMA,后台发生了什么?

c - HID 报告在更改长度时不起作用

assembly - 为什么在从引导加载程序跳转到应用程序之前需要更新堆栈指针

c - 为什么 USART2 发送垃圾值?

caching - DMA/Microblaze 直接访问用户空间页面物理地址后读取错误数据(内核分散/聚集)