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);    
	}	
}

问题暂时解决,在网上搜索了一些串口卡死的相关资料,隐隐感觉冥冥之中还有很大学问。

问题延伸

经过一番搜索之后,发现好像其实是受两个寄存器状态改变的影响:

  1. 打开 RXNEIE ,默认会同时打开 RXNEORE 中断;
  2. 必须第一时间清零 RXNE ,如果没有及时清零,下一帧数据过来时就会产生 Overrun error
  3. 错误就是 ORE 导致的;
  4. 解决办法要清除 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

你可能感兴趣的:(STM32设计及调试信息)