CUBE HAL库下的USART接收中断问题

博主在使用STM32单片机的USART1中断接收时遇到回调函数不触发的问题。经过排查,发现USART的IRQ函数内使用printf或HAL_UART_Transmit会导致中断回调失效。解决方案包括在IRQ函数中直接处理逻辑或调整回调函数调用顺序。此外,还发现TIM中断的回调也有类似问题。博主强调了深入理解函数底层和单步调试的重要性,并分享了调试经验和教训。
摘要由CSDN通过智能技术生成

---------------------------------------↓↓↓ 华丽丽的分割线 ↓↓↓---------------------------------------------
在连续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)上方(记得自定义一个接收数组作为开启函数的参数
定义接收数组
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里面定义接收数组
仍在main.c下方的USER CODE Block4里面重定义回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
需要修改stm32xxxx.it文件中的USARTx_IRQHandler函数的内容和该回调函数内容分别如下:
IRQ函数修改后的内容
main.c里自定义回调函数修改后的内容

烧录程序,功能正常
在这里插入图片描述

总结
单片机型号是蓝桥杯STM32G431RBT6,本人不仅发现UART的中断的Callback不能使用,而且发现TIM定时器的输入捕获和输出比较的中断的Callback也不能正常使用,
但是也不知道问题在哪儿,555……
上述对于UART的中断问题没有从根本上得到解决,至此衷心希望有大佬能给与热心解答,
如果您对绕过问题的方法有问题请在发表评论区,我看到会回复,
如果您看出了我的问题所在亦请在评论区中指出,感激不尽0…

在使用STM32HAL库进行串口DMA接收数据时,可能会出现数据缺失的情况。根据引用\[1\]中的博主的经验,他在使用STM32CubeIDE生成的代码中发现了一些问题,导致串口接收不到数据。为了解决这个问题,他建议稍作修改初始化流程,先初始化DMA,再初始化相关的串口。具体的修改流程如下所示: MX_DMA_Init(); MX_USART1_UART_Init(); MX_UART4_Init(); MX_UART5_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_USART6_UART_Init(); 此外,引用\[2\]中提到了一些整体思路。首先,需要打开串口空闲中断,并开启DMA接收。当串口接收到空闲中断标志后,会跳转到中断函数进行处理。在中断函数中,可以使用__HAL_DMA_GET_COUNTER函数来获取DMA接收剩余的字节数,然后根据实际收到的字节数进行处理。最后,需要重新初始化缓冲区并重新开启DMA接收。 需要注意的是,根据引用\[3\]中的代码,__HAL_DMA_GET_COUNTER函数用于统计DMA接收剩余的字节数。在开始时,DMA接收的字节数是固定的,然后在空闲中断中,通过这个函数可以统计到实际收到的字节数。根据实际情况,可以根据收到的字节数定义合适的变量类型,如uint16_t。 希望以上的信息对你有帮助。如果还有其他问题,请随时提问。 #### 引用[.reference_title] - *1* [stm32HAL库 串口接收不定长数据(DMA传输)](https://blog.csdn.net/qq_33954661/article/details/124882073)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [STM32 HAL库 串口DMA接收不定长数据](https://blog.csdn.net/weixin_41872408/article/details/118739340)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值