【发布时间】:2021-07-15 23:54:27
【问题描述】:
我目前正在从事一个项目,我在 STM32 系统上具有 USART 输入和 SAI(串行音频接口,类似于 SPI)输出。
我创建了一个循环缓冲区,用作 pinpong 缓冲区(双缓冲区)结构。从 USART 接收的输入样本存储在头指针指向的缓冲区中。当 SAI 外设请求新数据时,会从该缓冲区的尾指针中提取数据。
在我的代码开始时,我等到一半的缓冲区被填满,然后激活 SAI。 SAI 以 40kHz 的恒定速率输出。输入样本以大约 40kHz 的相同速率从外部设备的 USART 接收。
理想情况下,我希望我的头指针和尾指针之间的差异是恒定的。
我还实现了一种保护机制,当两个指针指向同一位置时,它使 Tail 指针等待并从 SAI 输出最后一个样本,直到缓冲区的一半被填充。
代码在开始时工作。问题是当大约 2 分钟的时间过去时,我们会看到头部和尾部指针指向同一位置,这会在我们的样本中产生不连续性。这意味着一个指针比预期的慢或快。我确信 SAI 协议会不断输出 40kHz(我用示波器检查过)。但是,我不太确定 USART 计时的准确性。我无法修改外部 USART 设备的代码,也无法更改输出速率 40kHz,它必须是这个值。
是否有另一种方法(可能是乒乓缓冲方法除外)来处理异步输入和同步输出?
【问题讨论】:
-
串行端口传输数据的速度是否可能比 SAI 输出的速度快?
-
@Steve 是的,更快或更慢可能是问题所在。我们的测量结果显示每秒有 22 个样本差异。
-
因此,如果源每秒传输 22 个样本的速度比消耗的快,那么这表明您的内存缓冲区约为 2k 样本。如果这是音频,那么您可能会不时放下一个样本,因此可能有一种算法可以在听者不注意的情况下执行此操作。
-
你能想到其他方法吗?因为 SAI 驱动一个射频调制器芯片,该芯片通过采样信号的相位发送信息。因此,丢弃样本会导致相位混乱。不幸的是,我不能放弃样品。
-
嗯。我已经开始写一篇关于如何做到这一点的答案帖子,但如果你不能丢弃样本,那么你必须弄清楚为什么你的输入速度快了 0.05%,或者如果这些不是连续传输,则可能使用更大的环形缓冲区.这听起来是个棘手的问题。
标签: c asynchronous synchronization stm32 microcontroller