[方案相关] 解决STM32F103系列 HAL库 DMA串口收发

[复制链接]
837|8
 楼主| 远芳侵古道 发表于 2022-6-28 17:42 | 显示全部楼层 |阅读模式
解决STM32F103系列 HAL库 DMA串口收发 频繁出现帧错误 (UART_FLAG_FE ,UART_FLAG_NE)的问题

HAL库 踩坑记录

解决STM32F103系列 HAL库 DMA串口收发  频繁出现帧错误 (UART_FLAG_FE ,UART_FLAG_NE)的问题

直接上代码

  1. /**************************************************************************
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  串口错误回调函数
  3.   * @retval
  4. **************************************************************************/
  5. void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  6. {
  7.     if((__HAL_UART_GET_FLAG(huart, UART_FLAG_PE))!=RESET)
  8.     {
  9.                         // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00000", 5);
  10.                         __HAL_UNLOCK(huart);
  11.                         __HAL_UART_CLEAR_PEFLAG(huart);
  12.     }
  13.     if((__HAL_UART_GET_FLAG(huart, UART_FLAG_FE))!=RESET)
  14.     {
  15.                         // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00001", 5);
  16.                         __HAL_UNLOCK(huart);
  17.                         __HAL_UART_CLEAR_FEFLAG(huart);
  18.     }
  19.    
  20.     if((__HAL_UART_GET_FLAG(huart, UART_FLAG_NE))!=RESET)
  21.     {
  22.                         // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00002", 5);
  23.                         __HAL_UNLOCK(huart);
  24.                         __HAL_UART_CLEAR_NEFLAG(huart);
  25.     }      
  26.    
  27.     if((__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE))!=RESET)
  28.     {
  29.                         // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"00003", 5);
  30.                         __HAL_UNLOCK(huart);
  31.                         __HAL_UART_CLEAR_OREFLAG(huart);
  32.     }   

  33.         //        错误标志位置
  34.         Uart_Error_Flag = 1;
  35. }



 楼主| 远芳侵古道 发表于 2022-6-28 17:44 | 显示全部楼层
问题解析

在使用串口DMA 接收数据时候 频繁出现数据接收不到问题
 楼主| 远芳侵古道 发表于 2022-6-28 17:44 | 显示全部楼层
罪魁祸首就是 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标志时会产生中断。
 楼主| 远芳侵古道 发表于 2022-6-28 17:47 | 显示全部楼层
代码解释
  1. // 解锁
  2. __HAL_UNLOCK(huart);

  3. // 这段代码就文档说明的内容
  4. __HAL_UART_CLEAR_FEFLAG(huart);
 楼主| 远芳侵古道 发表于 2022-6-28 17:48 | 显示全部楼层
最后需要在 串口错误回调函数中 添加一个 进入中断的错误标志位
 楼主| 远芳侵古道 发表于 2022-6-28 17:49 | 显示全部楼层
  1. //        错误标志位置
  2. Uart_Error_Flag = 1;
 楼主| 远芳侵古道 发表于 2022-6-28 17:49 | 显示全部楼层
用来在主循环里检测 DMA接收数据时候出现过错误
 楼主| 远芳侵古道 发表于 2022-6-28 17:50 | 显示全部楼层
  1. if(Uart_Error_Flag == 1)
  2. {
  3.     // 首先停止DMA
  4.     HAL_UART_DMAStop(&huart2);
  5.     Delay_ms(10);
  6.     //然后再次开启DMA
  7.     HAL_UART_Receive_DMA(&huart2, Buffer_2, 5);
  8.     Uart_Error_Flag = 0;
  9. }
 楼主| 远芳侵古道 发表于 2022-6-28 17:59 | 显示全部楼层
到此问题方可解决 (在此记录一下)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

86

主题

887

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部