STM32L053调试LPUART+DMA+空闲中断收不定长数据时出现帧错误的解决办法
现象
程序仿真正常跑没问题,串口一发数程序就会死在串口错误中断回调函数中
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
while(1)
{
}
}
单步调试发现是在
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
中的
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
条件不满足,跳入了
else
{
/* Non Blocking error : transfer could go on.
Error is notified to user through user error callback */
HAL_UART_ErrorCallback(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
此时ErrorCode 中值为4,即发生了frame error ;
关于frame error在参考手册中有如下描述:
帧错误 (Framing error)
如果接收数据时未在预期时间内识别出停止位,从而出现同步失效或过度的噪声,则会检测
到帧错误。
检测到帧错误时:
FE 位由硬件置 1。
无效数据从移位寄存器传送到 LPUART_RDR 寄存器。
单字节通信时无中断产生。然而,在 RXNE 位产生中断时,该位出现上升沿。多缓冲区
通信时,LPUART_CR3 寄存器中的 EIE 位置 1 时将发出中断。
通过将 1 写入 LPUART_ICR 寄存器中的 FECF 位来复位 FE 位。
继续仿真,观察在错误发生前后的寄存器状态变化,发现ORE位置1,RXNE有0-1-0的变化,RDR寄存器中数据为发送数据中的一个,参考以下描述:
上溢错误
如果在 RXNE 未复位时接收到字符,则会发生上溢错误。RXNE 位清零前,数据无法从移位
寄存器传送到 RDR 寄存器。
每接收到一个字节后,RXNE 标志位都将置 1。当 RXNE 标志位是 1 时,如果在接收到下一个
数据或尚未处理上一个 DMA 请求时,则会发生上溢错误。发生上溢错误时:
ORE 位置 1。
RDR 中的内容不会丢失。对 LPUART_RDR 执行读操作时可使用先前的数据。
移位寄存器将被覆盖。之后,上溢期间接收到的任何数据都将丢失。
如果 RXNEIE 位置 1 或 EIE 位置 1,则会生成中断。
通过设置 ICR 寄存器中的 ORECF 位复位 ORE 位。
产生了DMA没有正确打开,RDR中数据没有及时取出而导致了问题的出现,仔细排查代码发现DMA通道正确,但request写错了。提醒:参考手册的图中REQ数字与通道数字不对应