CUBE HAL库下的USART接收中断问题
---------------------------------------↓↓↓ 华丽丽的分割线 ↓↓↓---------------------------------------------
在连续4天高强度debug下,问题已经解决((嘻嘻(*^▽ ^)):
stm32xxit.c的USART的IRQ函数里面不能用串口的printf或者HAL_UART_Transmit函数,
一旦用了的话就会造成无法进入中断回调,具体错误是error8数据溢出。
在控制变量法的对照试验下,证明了我下述的问题就是由于上述原因导致的。
小结:
本次问题百问无回应,自己几乎能把网上那几个固定的答案给背下来了仍无解。
后面下定决心深入探索,不仅学会了调用报错函数查看异常原因,也对串口中断的函数调用体系有了充分的了解。总而言之,虽然过程很痛苦但是收获极大!目前很开心~
个人收获-
①以后遇见BUG遵循单步查找原则
②成立了debug文件夹,保留源文件并上传了百度云,以后也要持续积累经验!!
③评论区前辈说的有道理,向下扎到根,不可只会简单调用API,了解函数底层是有必要的
以上,
HAL库,冲~
---------------------------------------↑↑↑ 华丽丽的分割线 ↑↑↑---------------------------------------------
问题背景
在使用STM32单片机的USART1进行串口接收中断时,发现自定义的中断回调函数不能被正常调用,关键配置过程及问题如下:
①CUBE配置 (注意在project manager里面选择单独为外设生产.c和.h文件)
②添加printf重定向:
在usart.h里面添加stdio.h和string.h
在usart.c里面添加printf重定向函数
while(1)里测试发送数据正常
③验证串口中断接收功能(出现问题)
查阅网上资料得知:
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)负责开启接收中断
只有调用这个函数开启接收中断后,USARTx接收到数据才会进入到stm32xxxxit.c文件里面的USARTx_IRQHandler函数,所以把该开启函数放在while(1)上方(记得自定义一个接收数组作为开启函数的参数)
USARTx_IRQHandler函数内容如下:
个人认为HAL_UART_IRQHandler的功能是:
①调用串口接收数据回调函数HAL_UART_RxCpltCallback
②清空一切接收标志位、并且清空接收数组缓存
网上说回调函数HAL_UART_RxCpltCallback是一个weak弱定义函数,使用该回调函数时可以在任意处重新定义它,并且在其函数内部加入要执行的逻辑,即可在发生接收中断时执行该逻辑。
我在main.c的USER block 4块中重定义了该回调函数:
(提示:该函数内部需要重新调用开启中断的IT函数,否则接收中断只能发生一次)
烧录程序,
正常情况下应该是在串口助手发送任意字符串后,串口助手上反馈:There is callback
但实际情况是:串口助手发送字符串后,无任何反馈
写至此,我也不知是哪里出了问题
但通过上述知识储备和一番探索过后,我作出了以下两种可以绕过该问题的解决方案:
绕过问题的两个方案
方案一:不用回调函数,直接在it文件里面的IRQ函数里写逻辑
缺点:
① 需要在it.c的上方引入usart.h文件
② main.c里面定义的接收数组要在main.h文件里extern称全局变量
(因为IT函数HAL_UART_Receive_IT的参数需要填入接收数组,
在main.c的while(1)上方调用了IT函数,而且在it文件里的IRQ函数内夜里调用了IT函数)
烧录程序测试,功能正常
方案二:还用回调函数,不过需要调整下官方代码顺序
缺点:修改官方代码顺序可能会带来潜在BUG隐患
仍在main.c下方的USER CODE Block4里面重定义回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
需要修改stm32xxxx.it文件中的USARTx_IRQHandler函数的内容和该回调函数内容分别如下:
烧录程序,功能正常
总结
单片机型号是蓝桥杯STM32G431RBT6,本人不仅发现UART的中断的Callback不能使用,而且发现TIM定时器的输入捕获和输出比较的中断的Callback也不能正常使用,
但是也不知道问题在哪儿,555……
上述对于UART的中断问题没有从根本上得到解决,至此衷心希望有大佬能给与热心解答,
如果您对绕过问题的方法有问题请在发表评论区,我看到会回复,
如果您看出了我的问题所在亦请在评论区中指出,感激不尽0…