历史上的今天
今天是:2025年02月06日(星期四)
2020年02月06日 | STM8S串口中断卡死调试记录
2020-02-06 来源:eefocus
项目使用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);
}
烧录后,重新测试,发现快速率接收数据也不会出现卡死现象,系统运行正常,至此问题解决。
总结
在日常的开发过程中,我们往往注重的是如何完成特定的需求,没有考虑出现异常情况下的解决办法,如本例中所示,串口通讯时,为了接收实时性而选用中断接收,但是对于接收异常则没有考虑进去。同样的在其他外设的使用中也会犯类似的错误,所以解决途径是只有自己踩坑了,才知道填。将此分享出来是防止其他人踩同样的坑,亦或是正在踩坑的人早点跳出。
上一篇:STM8 SPI的学习
史海拾趣
|
买了一个128M的FLASH的mini2440,将光盘自带的u-boot.bin烧入后,在超级终端里看不到任何信息。。。。。。。。 急!请大家帮帮忙,谢谢了~… 查看全部问答> |
|
难得休息两天,回到工作,第一件事情是给媳妇帮忙翻译论文,而手头上的事情虽然充满着挑战,当总体还是应付的过来。由于很长一段的时间都是直接给国外做支持工作,对比国内项目的管理,让我生出了一种感受,同样的方法,同样的流程,到了我们这里一 ...… 查看全部问答> |
|
如题:在ADS1.2下(处理器pxa270) 我想用malloc可以吗 如: void main() { char strTitle[] = \"*************Pxa270Boot*************\"; char *pch = (char *)malloc(strlen(strTile)); memcp ...… 查看全部问答> |
|
大虾们!帮帮忙,我现在在学串口通信,我知道上位机发送一个字节的数据给单片机,然后让数码管显示发送的数据但是现在我想通过上位机发送一些数据给单片机,让1602显示的时间通过上位机发过来的数据进行改变, 该怎么发送呢 哪位大虾有这个程序没 ...… 查看全部问答> |
|
stm32f107VCT6+DP83848调试问题--【已解决】 本帖最后由 yl20084784 于 2016-4-30 21:58 编辑 淘宝上买了块开发板,店家的程序上修改好了自己的程序,然后抄板 布局店家没给,自己估计着弄得,现在上网线后,灯不亮。 调试发现 程序卡死在 /* Reset ETHERNET on AHB Bus */ ...… 查看全部问答> |
|
找资料的时候找到的:STM32F7-Discovery iconview理解与修改 在找资料时找到一个关于iconview自绘的资——网址如下,看得不是很懂。 http://www.dt-tech.net/Dteam/f7/iconviewEx/ … 查看全部问答> |




