完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在一项目中,使用STM32作为主控,程序运行一段时间后概率出现主循环卡死现象。
问题分析如下: 1、程序USART2不停接收并处理串口数据,波特率115200; 2、主循环卡死; 3、USART1中断及TIM2中断响应函数运行正常;(USART1及TIM2中断优先级均比USART2高) 4、出现现象后,拔掉USART2的接收数据线,现象不能回复正常; 5、出现现象后,拔掉后再插入USART2的接收数据线,现象不能回复正常; 6、并未出现HardFault现象; 基于以上4点,可能原因如下: 1、USART2接收中断标志没有清除; 2、堆栈数据溢出,导致程序异常; 3、USART2中断重入导致异常; 4、USART2中断函数被异常响应; 5、USART2中断ERR; 对于以上可能原因一一分析: 1、中断接收标志清楚问题: (1)USART2接收中断响应函数如下: (2)出现现象后,通过Usart1中断获取到如下信息: a. USART_GetITStatus(USART2, USART_IT_RXNE) == RESET b. USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET c. 执行USART_ClearFlag(USART2, USART_FLAG_RXNE)及 USART_ClearITPendingBit(USART2, USART_IT_RXNE)后无法恢复正常; 结论:与USART2 RXNE中断标志无关。 2、堆栈数据溢出,导致程序异常; (1)使用2倍栈空间,问题存在,概率不会降低; (2)使用0.5倍栈空间,问题存在,概率不会提高; (3)使用0.25倍栈空间,程序运行进入HardFault; 结论:与堆栈无关。 3、USART2中断重入导致异常; (1)使用标志法,确认出现问题时,中断响应函数没有重入; 结论:中断响应函数没有重入。 4、USART2中断函数被异常响应; (1)USART2中断函数可以被正常调用,只是不停进入中断响应函数,卡死主循环; (2)检查程序Map,没发现与中断响应函数地址相同的函数; (3)检查中断向量表,没发现异常; 结论:中断函数没有被异常调用; 5、USART2中断ERR; (1)关闭USART2中断,主循环恢复正常; (2)启动USART2中断,主循环卡死; (3)获取到DR=0x0000; (4)USART_GetITStatus取到:RXNE=0,PE=0,TXE=0,TC=0,IDLE=0,LBD=0,CTS=0,ERR=0,ORE=0,NE=0,FE=0; (5)通过USART_ClearITPendingBit清除CTS,LBD,TXE,TC,RXNE,IDLE,ORE,NE,FE,PE均无法恢复正常; (6)通过USART_GetFlagStatus: a.第一次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=1,ORE=1,NE=0,FE=0,PE=0 b.第二次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=0,ORE=0,NE=0,FE=0,PE=0 c.第三次:CTS=0,LBD=0,TXE=1,TC=1,RXNE=0,IDLE=0,ORE=0,NE=0,FE=0,PE=0 (7)通过USART_ClearFlag清除CTS,LBD,TXE,TC,RXNE,IDLE,ORE,NE,FE,PE均无法恢复正常; 分析: (1)为什么通过USART_GetITStatus获取了所有中断标志,均为RESET(TC、TXE中断没开),还会进中断? (2)为什么通过USART_ClearITPendingBit清除了所有中断标志,还会进入中断? (3)为什么关闭USART2中断后再次启动它还会进入卡死状态? (4)为什么通过USART_GetFlagStatus第一次和第二次读的不一样?而且USART_ClearFlag清掉所有Flag,也没法恢复正常? 带着以上几个疑问,查看了参考手册,才恍然大悟!如下: (1)打开RXNEIE,默认会同时打开RXNE和ORE中断。 (2)必须第一时间清零RXNE,如没及时清零,下一帧数据过来时就会产生Overrun error! (3)错误就是ORE导致的 出现错误时,读了RXNE=0,出错应该是上图打勾的情况,如下 (4)如文档说明,要清除ORE中断需要按顺序读取USART_SR和USART_DR寄存器! 那就是说USART_ClearFlag清掉所有Flag后,还必须读一遍USART_DR寄存器! 经过测试出现问题后依次读读取USART_SR和USART_DR,程序回复正常! (5)那还有一个问题,为什么USART_GetITStatus读不到ORE中断标志? 读USART_GetITStatus函数就知道了,只有CR3的EIE置1且SR的ORE置1,读出来USART_GetITStatus(USART2, USART_IT_ORE) 才是 SET。 见CR3的EIE位说明。 解决办法,出现通过接收时,通过USART_GetFlagStatus读取ORE,若不为RESET,则读取DR数据丢弃。 修改如下: 总结: 1、看文档!看文档!还是看文档!(重要的事情要说3遍) 2、库函数用的时候,也要注意其实现,稍有不慎就可能用错。 3、注意USART_GetFlagStatus与USART_GetITStatus的区别,还有中断响应机制。 4、任意时候都要考虑出错处理。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 16:01 , Processed in 0.805841 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号