Serial port 具有两个USART中断的溢出错误
在STM32F2上使用两个以115200波特运行的USART,一个用于与无线电模块通信,另一个用于从PC串行。时钟速度为120MHz 当同时从两个USART接收数据时,一个USART或另一个USART上可能会发生溢出错误。做一些快速返回信封的计算应该有足够的时间来处理这两个问题,因为中断只是简单地将字节复制到一个循环缓冲区 从理论上和测量上看,将字节推送到缓冲区的中断代码应该/确实以2-4µS的顺序运行,在115200波特时,我们有大约70us的时间来处理每个字符 为什么我们在一个或另一个USART上看到偶然的矿石 更新-其他信息:Serial port 具有两个USART中断的溢出错误,serial-port,embedded,interrupt,stm32,Serial Port,Embedded,Interrupt,Stm32,在STM32F2上使用两个以115200波特运行的USART,一个用于与无线电模块通信,另一个用于从PC串行。时钟速度为120MHz 当同时从两个USART接收数据时,一个USART或另一个USART上可能会发生溢出错误。做一些快速返回信封的计算应该有足够的时间来处理这两个问题,因为中断只是简单地将字节复制到一个循环缓冲区 从理论上和测量上看,将字节推送到缓冲区的中断代码应该/确实以2-4µS的顺序运行,在115200波特时,我们有大约70us的时间来处理每个字符 为什么我们在一个或另一个USA
systick中断由RTO使用,因此无法计时,其他ISR每字节运行2-3µS 几个月前,我在Cortex M4(SAM4S)上遇到了与你类似的问题。我有一个函数,根据定时器中断以100赫兹的频率被调用 同时,我配置了一个UART来中断字符接收。UART上的预期数据是64字节长的数据包,每个字符上的中断都会导致延迟,因此我的100Hz更新功能在20Hz左右运行。在这个120MHz的处理器上,100Hz的速度相对较慢,但每个字符上的中断都会导致大量延迟 我决定将UART配置为使用PDC(外围DMA控制器),我的问题立即消失了 DMA允许UART将数据存储在内存中,而不中断处理器,直到缓冲区已满,从而节省大量开销 在我的例子中,我告诉PDC将UART数据存储到缓冲区(字节数组)中,并指定了长度。当UART通过PDC填充缓冲区时,PDC发出中断 在PDC ISR中:
正如上面swineone所建议的,实施DMA,你就会热爱生活。也有类似的问题。短解决方案-将过采样更改为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的硬件问题。不管怎样,希望这能帮助别人!干杯 我最近遇到了这个问题,所以我实现了一个UART_ErrorCallback函数,它还没有被植入(只是_弱版本)。 是这样的:
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
HAL_UART_DeInit(&huart1);
MX_USART1_UART_Init(); //my initialization code
...
这就解决了超支问题。你没有提供足够的信息让别人说出你为什么会超支。明显的候选者:在其他地方禁用中断?高优先级中断处理程序太慢?代码中有Bug吗?没有足够的信息来确定哪个.ISR延迟在该芯片上是非常致命的,UART没有fifo缓冲区。你的理论计算已经偏离了2倍。添加ISR占用太多时间的高优先级中断,或者在您不知道的代码中禁用中断,并且溢出很容易解释。感谢您的评论,我为问题添加了更多信息,我不确定还能提供哪些其他信息。RTX(或ARM-MDK)的哪个版本?Cortex-M3的早期版本有缺陷,不完全支持中断优先级分组。如果没有代码,这个问题可能无法回答。我不会放弃一个无法解释的问题,因为以后症状可能会在其他地方出现。尽管如此,在我最近的几个项目中,我一直使用DMA来创建一个循环缓冲区,用于存储从USART接收的数据。实际的硬件(DMA控制器)不会错过最后期限(除非它也过载了,但除非你用它做其他事情,否则以这种速度进行2次使用应该是小菜一碟)。