使用两个在STM32F2上运行115200波特的USART,一个用于与无线电模块通信,另一个用于PC上的串行通信。时钟速度为120 The。
当从这两个USART接收数据时,在一个USART或另一个USART上可能同时发生溢出错误。做一些快速的信封计算,应该有足够的时间来处理两者,因为中断只是简单地将字节复制到循环缓冲区。
无论是从理论上还是从测量的角度来看,将字节推送到缓冲区的中断代码应该/确实以2-4S的顺序运行,在115200波特时,我们有大约70 at的时间来处理每个字符。
为什么我们在一个或另一个USART上看到矿砂?
最新情况-补充资料:
考虑到以上所有的情况,在我们清理干扰所需的时间内,70 is至少是10倍--所以我不确定它是否如此容易解释。我是否应该得出结论,肯定还有其他因素让我眼花缭乱?
MDK-ARM是4.70版
系统中断是由RTOS使用的,所以不能对此进行计时,其他ISRs采用2-3S来运行每个字节。
发布于 2014-12-06 07:38:59
几个月前,我在Cortex M4 (SAM4S)上遇到了一个类似的问题。我有一个功能,在100赫兹的基础上调用计时器中断。
同时,我配置了一个UART,用于中断char接收。UART上的预期数据是64字节长的数据包,每个字符上的中断会导致延迟,因此我的100 Hz更新功能在20 Hz左右运行。在这个特定的120 MHz处理器上,100赫兹是相对缓慢的,但是每一个字符的中断都会导致大规模的延迟。
我决定将UART配置为使用PDC (外围DMA控制器),我的问题立即消失了。
DMA允许UART在内存中存储数据,而不会中断处理器,直到缓冲区满了为止,节省了大量的开销。
在我的例子中,我告诉PDC将UART数据存储到缓冲区(字节数组)中,并指定长度。当UART通过PDC填充缓冲区时,PDC发出一个中断。
在PDC ISR中:
正如swineone上面所建议的那样,实现DMA,你就会热爱生活。
发布于 2018-05-02 19:50:21
也有类似的问题。短解-将过采样转换为8位,从而使USART时钟更精确。明智地选择你的MCU时钟!
huart1.Init.OverSampling = UART_OVERSAMPLING_8;此外,添加USART错误处理程序和机制,以检查数据是否有效,如CRC16。下面是STM32F0xx系列的示例,我假设它在整个系列中应该非常相似。
void UART_flush(void) {
// Flush UART RX buffer if RXNE is set
if READ_BIT(huart1.Instance->ISR, USART_ISR_RXNE) {
SET_BIT(huart1.Instance->RQR, UART_RXDATA_FLUSH_REQUEST);
}
// Not available on F030xx devices!
// SET_BIT(huart1.Instance->RQR, UART_TXDATA_FLUSH_REQUEST);
// Clear All Errors (if needed)
if (READ_BIT(huart1.Instance->ISR, USART_ISR_ORE | USART_ISR_FE | USART_ISR_NE)) {
SET_BIT(huart1.Instance->ICR, USART_ICR_ORECF | USART_ICR_FECF | USART_ICR_NCF);
}
}
// USART Error Handler
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
if(huart->Instance==USART1) {
// See if we have any errors
if (READ_BIT(huart1.Instance->ISR, USART_ISR_ORE | USART_ISR_FE | USART_ISR_NE | USART_ISR_RXNE)) {
// Flush errors
UART_flush();
// Raise Error Handler
_Error_Handler(__FILE__, __LINE__);
}
}
}DMA也可能有帮助。我的问题与USART时钟公差有关,后者甚至可能导致DMA实现时的溢出错误。因为这是USART硬件问题。不管怎么说,希望这能帮到别人!干杯!
发布于 2021-02-06 22:53:18
最近我遇到了这个问题,所以我实现了一个尚未植入的UART_ErrorCallback函数(仅是_weak版本)。是这样的:
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
HAL_UART_DeInit(&huart1);
MX_USART1_UART_Init(); //my initialization code
...这就解决了超支的问题。
https://stackoverflow.com/questions/23078848
复制相似问题