STM8S串口中断卡死调试记录

项目使用STM8S003单片机,数据发送速率比较慢时,一切正常。当速率快的时候,系统卡死,具体表现为一直运行中断服务程序,无法执行while(1)里面的内容了。

调试记录

开始怀疑是一直在响应某个中断,断点调试后发现是一直在响应UART1接收中断。调试步骤如下:

怀疑是串口中断里做了数据解析工作,导致在解析途中又收到了第二个串口接收中断,然后发生异常。解决办法是在串口接收中断中关闭串口接收中断,数据解析完成后再打开串口接收中断,防止在本次数据解析时发生下一次接收中断。具体代码表现如下:

 /**
   * @brief  UART1 RX Interrupt routine
   * @param  None
   * @retval None
   */
  INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
 {
   /* In order to detect unexpected events during development,
	  it is recommended to set a breakpoint on the following instruction.
   */
	 uint8_t temp;
	 temp = UART1_ReceiveData8();
	 UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE); //关闭串口中断
	 gh_protocol_parse(temp, &gh_parse);		//解析数据
	 UART1_ClearITPendingBit(UART1_IT_RXNE);
 	 UART1_ITConfig(UART1_IT_RXNE_OR, DISABLE);	//打开串口中断
 
 }

测试后发现问题依旧,所以又考虑是不是还有其他中断干扰(工程中还开启了两个定时器中断,中断频率比较高),索性关闭全局中断试试,如下:

 /**
   * @brief  UART1 RX Interrupt routine
   * @param  None
   * @retval None
   */
  INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
 {
   /* In order to detect unexpected events during development,
	  it is recommended to set a breakpoint on the following instruction.
   */
	 uint8_t temp;
	 temp = UART1_ReceiveData8();
	 disableInterrupts(); //关闭全局中断
	 gh_protocol_parse(temp, &gh_parse);		//解析数据
	 UART1_ClearITPendingBit(UART1_IT_RXNE);
 	 enableInterrupts();	//打开全局中断
 
 }

测试后,问题依旧。

没办法,只能看看发生异常后,串口寄存器的状态,然后再定位异常。如下图所示。

在这里插入图片描述

OR_LHE置位,数据手册上如是介绍这位:
在这里插入图片描述

所以判断是过载错误没有清除导致中断异常,按照数据手册,每次中断来之前先读SR 然后后再读DR,不管有没有过载错误,都把该位给清掉,代码改成如下:

/**
  * @brief  UART1 RX Interrupt routine
  * @param  None
  * @retval None
  */
 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
    uint8_t temp;

    temp = UART1->SR;
    temp = UART1_ReceiveData8();
	gh_protocol_parse(temp, &gh_parse);
	UART1_ClearITPendingBit(UART1_IT_RXNE);


}

烧录后,重新测试,发现快速率接收数据也不会出现卡死现象,系统运行正常,至此问题解决。

总结

在日常的开发过程中,我们往往注重的是如何完成特定的需求,没有考虑出现异常情况下的解决办法,如本例中所示,串口通讯时,为了接收实时性而选用中断接收,但是对于接收异常则没有考虑进去。同样的在其他外设的使用中也会犯类似的错误,所以解决途径是只有自己踩坑了,才知道填。将此分享出来是防止其他人踩同样的坑,亦或是正在踩坑的人早点跳出。

发布了44 篇原创文章 · 获赞 60 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/u014421520/article/details/102561240