STM32 串口UART1中断卡死的问题
问题发现
- 在调试程序的过程中,发现按键切换会导致程序卡死;
- 程序卡死卡死对应的语句中含有
printf
输出; - 使用Keil 5 Debug时,发现出错情况在于 串口UART1对应的中断服务函数
USART1_IRQHandler
中;
问题原因
因为串口中断服务函数内为空语句:
void USART1_IRQHandler(void)
{
}
这我就很郁闷了,这里面怎么能是空语句呢?少了串口收发的清除标志位呀!
问题解决
果断拿出以前学习时候的串口收发例程 当然是我火哥的
,找到并添加对应Code:
void USART1_IRQHandler(void)
{
/* 加入清除标志位,否则会卡死在串口中断服务函数中 */
uint8_t ucTemp;
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
{
ucTemp = USART_ReceiveData(DEBUG_USARTx);
USART_SendData(DEBUG_USARTx,ucTemp);
}
}
问题暂时解决,在网上搜索了一些串口卡死的相关资料,隐隐感觉冥冥之中还有很大学问。
问题延伸
经过一番搜索之后,发现好像其实是受两个寄存器状态改变的影响:
- 打开
RXNEIE
,默认会同时打开RXNE
和ORE
中断; - 必须第一时间清零
RXNE
,如果没有及时清零,下一帧数据过来时就会产生Overrun error
; - 错误就是
ORE
导致的; - 解决办法要清除
ORE
;
所以最终的解决方案应该是:
void USART1_IRQHandler(void)
{
/* 加入清除标志位,否则会卡死在串口中断服务函数中 */
uint8_t ucTemp;
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) //检查 USART 是否发生中断
{
USART_ClearITPendingBit(DEBUG_USARTx,USART_IT_RXNE); // 清中断标志
ucTemp=USART_ReceiveData(DEBUG_USARTx);
}
if(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_ORE) == SET) // 检查 ORE 标志
{
USART_ClearFlag(DEBUG_USARTx,USART_FLAG_ORE);
USART_ReceiveData(DEBUG_USARTx);
}
}
所以,之前的程序中,中断服务函数里面啥也没有肯定是不行的,其次只检查 RXNE
是不行的,还需要检查 ORE
标志,需要将两者在中断服务函数中清除,才能正常进行 下一次 的数据发送和接收。
这个问题应该还需要延伸,下次遇到再进行补充。
After
参考链接:https://www.cnblogs.com/citycomputing/p/6139456.html
Drafer : LJacki
Date : 2019-04-05