解决Stm32 HAL_UART_Receive无法读取数据的问题

最近在做Stm32方面的工作时发现使用HAL_UART_Receive函数去读取数据时出现了问题,代码如下: 

char buffer[128] = {0};
HAL_UART_Receive(phuart, buffer, 128, timer);

这段代码非常简单,就是在一定时间内读取满128个字符,但是会有一个问题,如果超时时buffer没有被读取到128个字节那么下次还可以读取,但是一旦超出或到达128个字节下次在读取就会没有数据,但是在中断情况下是可以正常读取的,随后我去查了一下USART寄存器,发现它有一个OVRDIS的功能,简单来说就是当数据达到buff设定大小时会将ORE标志置1,那么下次来新数据时如果ORE为1则不会填充到buff区里。

并且HAL库里的code在读取时都会判断这个位是否为1,这么做的目的是为了防止将未读取的数据覆盖掉

如果你是使用Stm32Cube.MX生成的usart代码,在配置里这个选项是默认打开的

 

我去查看了一下HAL库里的HAL_UART_Receive函数,它在循环里并没有做清除ORE的工作,而中断函数可以正常读取的原因是因为在中断函数里清除了标志位

可以看到下面的代码每次循环代码,里面没有任何清除标志位的Code

while (huart->RxXferCount > 0U)
    {

      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      if (pdata8bits == NULL)
      {
        *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
        pdata16bits++;
      }
      else
      {
        *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
        pdata8bits++;
      }
      huart->RxXferCount--;
    }

所以我们在HAL_UART_Receive函数的while循环里加入一行清除ORE标志位的code就可以了:

将下面的代码添加到while循环第一行就可以了

__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);

物联沃分享整理
物联沃-IOTWORD物联网 » 解决Stm32 HAL_UART_Receive无法读取数据的问题

发表评论