STM32 串口UART1中断卡死的问题
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
Drafer : LJacki Date : 2019-04-05