STM32 UART DMA方式,如何避免出现数据过载错误

2019-12-15 10:58发布

各位大神们!

小弟用STM32 UART4接收(用DMA方式)串口WIFI模块数据时  UART4 有时会出现过载错误

现象描述:
WIFI模块是接收/发送 实时音频传输的数据,8K采样率,每采集500个字节对方发送一次
UART4 DMA方式接收 波特率:230400  
  接收方法:当UART4总结空闲标志置1了,才去读取DMA接收到的数据

串口WIFI模块的数据量:
网络良好时: 每隔40ms有会500Byte数据
网络较差时:每隔40ms左右会有500个Byte,但500Byte可能会被分成十多次从WIFI模块串口发送出来,每次发送的间隔有几毫秒甚至底于1毫秒
                   (过载错误时基本上是在这个情况下出现的)
网络很差时:有时连续几百毫秒都没数据,突然3000左右字节连接发送过来
注:以上情况是用示波器观察到的

代码如下:
  1. /*****************************************************
  2. ** 查询DMA接收数据的状态
  3. ** buff: 存储接收到的数据
  4. ** 返回:没有接收数据返回0
  5.          否则返回接收到数据的个数
  6. *****************************************************/
  7. unsigned short Receive_UART4(unsigned char *buff)
  8. {
  9.         unsigned short remaining,i,num;
  10.         static unsigned short count = UART4_RX_SIZE;
  11.         if(USART_GetFlagStatus(UART4,USART_FLAG_IDLE))
  12.         {
  13.                 //思想:Receive_UART4函数每隔2ms调度1次,
  14.                 //若两次调度期间接收到的数据的数量没有发送变化。
  15.                 //则串口处于空闲状态;即可复制DMA传输的数据
  16.                 remaining = DMA_GetCurrDataCounter(DMA2_Channel3);
  17.                 if((remaining == UART4_RX_SIZE) || (count != remaining))               
  18.                          count = remaining;
  19.                 else
  20.                 {
  21.                         num = (UART4_RX_SIZE - remaining);
  22.                         //再次判断总线是否空闲
  23.                         if(!USART_GetFlagStatus(UART4,USART_FLAG_IDLE))
  24.                                 return 0;
  25.                         DMA2_Channel3->CCR   &= ~(1 << 0);        //停止DMA
  26.                         for(i = 0; i < num; i++)
  27.                         {
  28.                                 buff[i] = UART4_RxBuff[i];
  29.                         }
  30.                         DMA2_Channel3->CNDTR = UART4_RX_SIZE;         //设置DMA传输大小
  31.                         DMA2_Channel3->CMAR  = (unsigned long)UART4_RxBuff; //设置DMA缓存
  32.                         DMA2_Channel3->CCR   |= (1 << 0);          //启动DMA
  33.                         return num;               
  34.                 }
  35.         }
  36.         return 0;       
  37. }
复制代码请教各位,这种环境下如何避免UART的数据过载现象?
另外,DMA停止后启动时间大概多长?貌似手册上没有说明
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。