我目前正在进行一个项目,在STM32系统上有USART输入和SAI(串行音频接口,类似于SPI(输出。
我创建了一个循环缓冲区,充当乒乓缓冲区(双缓冲区(结构。从USART接收的输入样本被存储在磁头指针指向的这个缓冲器中。当SAI外围设备请求新数据时,数据会从这个缓冲区的尾部指针中提取。
在我的代码开始时,我等待,直到一半的缓冲区被填满,然后激活SAI。SAI以40kHz的恒定速率输出。从外部设备的USART以大约相同的速率40kHz接收输入样本。
理想情况下,我希望我的头指针和尾指针之间的差值是恒定的。
我还实现了一种保护机制,当两个指针指向同一位置时,使Tail指针等待并输出SAI的最后一个样本,直到填充一半的缓冲区。
代码一开始就工作。问题是,当大约2分钟的时间过去时,我们会看到头部和尾部指针指向同一位置,这会在我们的样本中产生不连续性。这意味着一个指针比预期的慢或快。我确信SAI协议持续输出40kHz(我用示波器检查了它(。然而,我不太确定USART计时的准确性。我不能修改外部USART设备的代码,也不能更改40kHz的输出速率,它必须是这个值。
有没有其他方法(可能不是乒乓缓冲区方法(来处理异步输入和同步输出?
如果您所说的是从某个外部设备接收(连续(串行数据,然后以某种速率将其转发到您自己的某个接口。。。基于您的时钟。即使数据是相同的格式并且时钟是"0";相同的";,则预期某个地方会出现缓冲区溢出。
如果1(以线速率连续2(输入源和输出源是不同的时钟3(参考时钟肯定会有差异,如果输入源时钟稍快,那么只要流保持连续并以线速率,那么最终就会溢出。
时钟随着温度和电压的变化而变化,因此delta可以改变。
甚至可以减少从输入输出的数据的百分比,如果输入是连续的,则仍然会溢出。这取决于你的输出是否也是线速率,或者你是否有裕度,裕度可以克服时钟的差异。
还要记住,uart很难以那个精确的速率运行,使用时钟分频器并接近,你可以有两台计算机以相同的速率使用uart,增量可能相对较大,溢出可能很快发生。为了让uart工作,时钟必须足够好,才能通过一个字符,因此即使振荡器非常好,没有pll,并且双方使用相同的参考时钟(但不是相同的uart、时钟系统等(,也可以有几个百分比的折扣。
如果你提高输出速率或减少输出的数据,使其不处于行速率,那么问题可能会消失,或者可能需要数小时或数天才能发生。。。
如果我误解了这个问题,请原谅,我会删除这个答案。