STM32 HAL库回调函数工作机制及UART接收回调执行时机咨询
兄弟,我来给你掰扯清楚HAL库这个UART接收回调的事儿,刚好我平时做STM32项目经常跟它打交道,给你说透:
回调函数的执行时机:
首先,HAL_UART_RxCpltCallback()不是随便触发的,它得配合你调用的中断模式接收函数(比如HAL_UART_Receive_IT())才能工作。举个例子,如果你调用了HAL_UART_Receive_IT(&huart1, rx_buf, 5),那只有当USART硬件把5个字节的数据都接收完成,并且全部存到你指定的rx_buf缓冲区之后,这个回调函数才会被HAL库调用。和缓冲区、数据长度的依赖关系:
完全依赖!你在HAL_UART_Receive_IT()里设置的接收数据长度,就是触发回调的核心条件。硬件UART的接收FIFO(如果你的芯片带这个功能)会临时存收到的字节,但最终必须凑够你指定的长度,HAL库才会触发这个回调。而你传入的缓冲区rx_buf,就是硬件用来存放接收数据的地方,写满指定长度后,才会触发后续的回调逻辑。硬件中断的触发逻辑:
你猜的没错——硬件UART确实会在每收到一个字符时就触发接收中断,但这个中断首先会进入HAL库的底层中断服务函数(比如USART1_IRQHandler())。在这个底层ISR里,HAL会默默计数已经接收的字节数:如果还没到你设置的长度,它就会重置中断标志,继续等待下一个字节;只有当接收的字节数刚好达到你指定的长度时,才会调用HAL_UART_RxCpltCallback(),同时标记这次接收任务完成。
另外给你个实用小技巧:如果想实现连续的中断接收,一般会在HAL_UART_RxCpltCallback()的末尾再次调用HAL_UART_Receive_IT(),这样下一轮的接收中断就会被重新开启,就能持续接收数据了。
内容的提问来源于stack exchange,提问作者Genius_SexyBoy

