首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两次USART中断下的溢出错误

两次USART中断下的溢出错误
EN

Stack Overflow用户
提问于 2014-04-15 08:52:44
回答 3查看 11.1K关注 0票数 9

使用两个在STM32F2上运行115200波特的USART,一个用于与无线电模块通信,另一个用于PC上的串行通信。时钟速度为120 The。

当从这两个USART接收数据时,在一个USART或另一个USART上可能同时发生溢出错误。做一些快速的信封计算,应该有足够的时间来处理两者,因为中断只是简单地将字节复制到循环缓冲区。

无论是从理论上还是从测量的角度来看,将字节推送到缓冲区的中断代码应该/确实以2-4S的顺序运行,在115200波特时,我们有大约70 at的时间来处理每个字符。

为什么我们在一个或另一个USART上看到矿砂?

最新情况-补充资料:

  1. 在我们的代码中没有其他ISRs在此时开火。
  2. 我们正在运行Keil,系统中断配置为每10 We启动一次。
  3. 此时我们不会禁用任何中断。
  4. 根据这本书(设计师对Cortex-M处理器家族的指南),中断延迟大约是12个周期(并不是真正致命的)。

考虑到以上所有的情况,在我们清理干扰所需的时间内,70 is至少是10倍--所以我不确定它是否如此容易解释。我是否应该得出结论,肯定还有其他因素让我眼花缭乱?

MDK-ARM是4.70版

系统中断是由RTOS使用的,所以不能对此进行计时,其他ISRs采用2-3S来运行每个字节。

EN

回答 3

Stack Overflow用户

发布于 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中:

  1. 给PDC新的空缓冲区
  2. 重新启动UART PDC (所以我们可以在isr中收集数据)
  3. 进入RINGBUFFER的memcpy全缓冲区
  4. 出口ISR

正如swineone上面所建议的那样,实现DMA,你就会热爱生活。

票数 2
EN

Stack Overflow用户

发布于 2018-05-02 19:50:21

也有类似的问题。短解-将过采样转换为8位,从而使USART时钟更精确。明智地选择你的MCU时钟!

代码语言:javascript
复制
huart1.Init.OverSampling = UART_OVERSAMPLING_8;

此外,添加USART错误处理程序和机制,以检查数据是否有效,如CRC16。下面是STM32F0xx系列的示例,我假设它在整个系列中应该非常相似。

代码语言:javascript
复制
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硬件问题。不管怎么说,希望这能帮到别人!干杯!

票数 0
EN

Stack Overflow用户

发布于 2021-02-06 22:53:18

最近我遇到了这个问题,所以我实现了一个尚未植入的UART_ErrorCallback函数(仅是_weak版本)。是这样的:

代码语言:javascript
复制
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
     if(huart == &huart1)
     {
         HAL_UART_DeInit(&huart1);
         MX_USART1_UART_Init(); //my initialization code
      ...

这就解决了超支的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23078848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档