最近在做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就可以了:文章来源:https://www.toymoban.com/news/detail-538968.html
将下面的代码添加到while循环第一行就可以了文章来源地址https://www.toymoban.com/news/detail-538968.html
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
到了这里,关于Stm32 HAL_UART_Receive读取不到数据的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!