HAL库 踩坑记录
解决STM32F103系列 HAL库 DMA串口收发 频繁出现帧错误 (UART_FLAG_FE ,UART_FLAG_NE)的问题
直接上代码
/**************************************************************************
* @brief 串口错误回调函数
* @retval
**************************************************************************/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if((__HAL_UART_GET_FLAG(huart, UART_FLAG_PE))!=RESET)
{
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00000", 5);
__HAL_UNLOCK(huart);
__HAL_UART_CLEAR_PEFLAG(huart);
}
if((__HAL_UART_GET_FLAG(huart, UART_FLAG_FE))!=RESET)
{
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00001", 5);
__HAL_UNLOCK(huart);
__HAL_UART_CLEAR_FEFLAG(huart);
}
if((__HAL_UART_GET_FLAG(huart, UART_FLAG_NE))!=RESET)
{
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00002", 5);
__HAL_UNLOCK(huart);
__HAL_UART_CLEAR_NEFLAG(huart);
}
if((__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE))!=RESET)
{
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00003", 5);
__HAL_UNLOCK(huart);
__HAL_UART_CLEAR_OREFLAG(huart);
}
// 错误标志位置
Uart_Error_Flag = 1;
}
问题解析
在使用串口DMA 接收数据时候 频繁出现数据接收不到问题
罪魁祸首就是 UART_FLAG_FE 标志位
其次就是 UART_FLAG_NE 标志位
UART_FLAG_FE:文档说明
FE: 帧错误 (Framing error)
数据寄存器 (USART_DR) 位1
当检测到同步错位,过多的噪声或者检测到断开符,该位被硬件置位。由软件序列将其清零(先
读USART_SR,再读USART_DR)。
0:没有检测到帧错误;
1:检测到帧错误或者break符。
注意:该位不会产生中断,因为它和RXNE一起出现,硬件会在设置RXNE标志时产生中断。
如果当前传输的数据既产生了帧错误,又产生了过载错误,硬件还是会继续该数据的传输,并
且只设置ORE标志位。
在多缓冲区通信模式下,如果设置了EIE位,则设置FE标志时会产生中断
UART_FLAG_NE:文档说明
NE: 噪声错误标志 (Noise error flag)
数据寄存器 (USART_DR) 位2
在接收到的帧检测到噪音时,由硬件对该位置位。由软件序列对其清玲(先读USART_SR,再
读USART_DR)。
0:没有检测到噪声;
1:检测到噪声。
注意:该位不会产生中断,因为它和RXNE一起出现,硬件会在设置RXNE标志时产生中断。
在多缓冲区通信模式下,如果设置了EIE位,则设置NE标志时会产生中断。
代码解释
// 解锁
__HAL_UNLOCK(huart);
// 这段代码就文档说明的内容
__HAL_UART_CLEAR_FEFLAG(huart);
最后需要在 串口错误回调函数中 添加一个 进入中断的错误标志位
// 错误标志位置
Uart_Error_Flag = 1;
用来在主循环里检测 DMA接收数据时候出现过错误
if(Uart_Error_Flag == 1)
{
// 首先停止DMA
HAL_UART_DMAStop(&huart2);
Delay_ms(10);
//然后再次开启DMA
HAL_UART_Receive_DMA(&huart2, Buffer_2, 5);
Uart_Error_Flag = 0;
}
到此问题方可解决 (在此记录一下)