最近复习单片机,复习到了看门狗,就把相关的程序跑飞和解决办法整理了一下,具体看下面:
网址:《51单片机应用开发从入门到精通》——2.13 软件陷阱实例-阿里云开发者社区
网址中提到的汇编语言(加了一些注释):
ORG 0000H
LJMP MAIN ;程序跳转到主程序入口
ORG 0003H ;ORG为伪指令,其定位作用
LJMP X0_INT ;程序跳转到外部中断0中断服务程序入口
NOP ;冗余指令
NOP
LJMP ERR ;陷阱
ERR:
CLR EA ;关闭中断 (1)
MOV DPTR,#ERR1 ;准备第一次返回地址 (2)
PUSH DPH ; (3)
PUSH DPL ; (4)
RETI ;清除高级中断激活标志 (5)
ERR1:
CLR A ;准备复位地址0000H (6)
PUSH A ; (7)
PUSH A ; (8)
RETI ;清除低级中断激活标志 (9)
ERR中,关闭中断并将ERR1压入栈中,但为什么使用REIT指令呢,REIT是中断返回用的啊,这里需要理解下:中断结束,REIT指令执行返回命令,PC寄存器会指向栈顶位置(前面已经将ERR1压入栈中)。这里指回到ERR1处并清除中断标志位
ERR1中,将复位地址压入栈中,执行REIT指令,跳转到地址0000H处,并清除中断标志位。
问题又来了,为什么使用了两个REIT呢?文章里所说:“在最严重的情况下,程序跑飞时,单片机正处于两级中断嵌套的状态,此时需要通过两个RETI指令才能使单片机回到正常状态”。代码中使用了两条RETI指令,就是为了防止最坏的情况发生(所以代码的注释中才会有清除高级中断激活标志位和清除低级中断激活标志位之分)!
问题又又又又又来了,代码中只用了两个REIT,是为了防止两层中断嵌套,但如果是三层中断嵌套呢?这篇文章是51单片机的解决方法,而51单片机最多支持两层嵌套,所以!不用担心捏!
那么,最后说下我在这篇文章中想到的一些东西:复位并不是说简单的程序计数器指向复位地址,还有和复位相关的一些操作,就比如上面提到的中断的开启和关闭、中断标志位的清除等。如果不用WDT,而是用软件陷阱的方法的话,需要考虑的还是挺多的。。