使用STM32F401的HAL库,编写串口中断收发数据。
HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
每次调用HAL_UART_Receive_IT()函数启动中断模式接收数据后,只能正常接收到第1批数据(数据包长为函数中定义的RXBUFFERSIZE值)。例如RXBUFFERSIZE=1时,只能收到1个数据;RXBUFFERSIZE=5时,只能收到5个数据。
我的愚见,接收一个数据,系统会进入中断函数USARTx_IRQHandler(),运行一次函数UART_Receive_IT(),但是接收完RXRXBUFFERSIZE数据,才会运行一次HAL_UART_RxCpltCallback();若RXBUFFERSIZE=5,运行5次UART_Receive_IT()(运行完5次后关闭中断),运行1次HAL_UART_RxCpltCallback()。
查阅资料了解到HAL库对于USART的接收中断的处理,划分了好几层。
首先,串口接收中断触发后的入口程序在启动文件startup_stm32f401xc.s中定义为USART1_IRQHandler()和USART2_IRQHandler();
然后,USARTx_IRQHandler()的内容就一句:调用HAL_UART_IRQHandler();
接着,HAL_UART_IRQHandler()对一系列的异常场景进行处理后,再调用UART_Receive_IT();
最后,而在UART_Receive_IT()中,会判断RxXfeiCount值是否为0,当为0时就关断了串口接收中断!RxXfeiCount是UART结构体中“剩余待接收的数据计数值”。——也就是说,每当接收完HAL_UART_Receive_IT()函数中规定的RXBUFFERSIZE个数据就关闭接收中断。这也解释了为什么会出现只收到第1批数据后,再也无法接收数据的现象了。
HAL库对于串口接收中断处理的几层调用关系如下:
USARTx_IRQHandler()┗━ HAL_UART_IRQHandler()┗━ UART_Receive_IT(){if (--huart->RxXferCount == 0U){/* Disable the UART Data Register not empty Interrupt */__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);..............HAL_UART_RxCpltCallback();.......}
显然,在Main()中每次调用HAL_UART_Receive_IT()后,都能收到一批数据,那么采用循环的方式也可以持续接收到串口数据。但是这样做和“查询接收”没啥区别了吧。另一种更好的思路是:每完成一批数据接收后,自动使能接收中断。
而在UART_Receive_IT()函数中调用了接收回调函数HAL_UART_RxCpltCallback()。只要在这个回调函数中末尾再添加HAL_UART_Receive_IT(),重新打开串口接收中断、并设定接收的数据量就解决了。
提示:这里填写该问题的具体解决方案:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{ ..........................HAL_UART_Receive_IT(UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
}
—参考原文:【STM32F401CCU6小系统调试案例——串口采用HAL库中断方式接收,只能收到第一批数据】
上一篇:windows消息机制
下一篇:基于深度学习的图片上色