首先, 你在主程序和中断中都调用了DISPLAY
所以在DISPLAY中用到的寄存器都要压栈
在DISPLAY里面还使用到了B寄存器, 所以它也需要入栈才行
其他的你自己再检查一下
首先介绍一下51的寄存器组:
通过设置PSW寄存器的第3位和第4位可以任意切换寄存器组。在进入中断前,切换寄存器组,可以方便的保护原寄存器组的数据不被中断里的语句破坏,很方便。
RS1RS0 字节地址
000组寄存器00H~07H
011组寄存器08H~0FH
102组寄存器10H~17H
113组寄存器18H~1FH
RS1=PSW4RS0=PSW3
常见错误有三种:
1、为中断函数指定了第0组寄存器
C程序:voidint0()interrupt0using0
编译后的汇编如下:
PUSHACC
PUSHB
PUSHDPH
PUSHDPL
PUSHPSW
MOVPSW,#0x00
。。。。。。
因为main()函数使用的就是第0组寄存器,中断程序会改变寄存器组的数据。主程序运行时,随时都有可能产生中断,等中断返回主程序时,寄存器R0-R7的值已经被改变了。这是非常严重的错误。而且故障时有时无,错误也是莫明其妙。
2、中断优先级不同,寄存器组号相同
C程序:voidint0()interrupt0using1//低优先级中断
voidT0()interrupt1using1//高优先级中断
因为高优先级的中断可以打断正在执行的低级中断,转向持行高级中断。这就是所谓的中断的中断。与第1种错语一样,高级中断的程序,会改变低级中断正在使用的寄存器。
3、不写using。严格的说,这样写不能算是错误。但这是相当不好的习惯。
C程序:voidint0()interrupt0
编译后的汇编如下:
PUSHACC
PUSHB
PUSHDPH
PUSHDPL
PUSHPSW
MOV PSW,#0x00
PUSH0x00
PUSH0x01
PUSH0x02
PUSH0x03
PUSH0x04
PUSH0x05
PUSH0x06
PUSH0x07
。。。。。。
没用using指定寄存器组,编译器就默认分配了第0组寄存器,然后又用8条语句把第0组的R0-R7保存到栈中,退出中断时还需要8个d栈。这样“笨拙”的写法,占用了程序空间32个字节、占有堆栈8个字节。也许高级版本的编译器会改进吧,搞单片机的还是规矩些好。
经验总结:
1、写中断程序一定要用using语句指定寄存器组。第1、2、3组都可以,不能是0
2、51单片机的中断有两个优先级。一个中断不会打断另一个相同优先级的中断。这样相同级别中断可以使用同一个组。比如:低优先级的中断函数都用using1,高优先级的中断都用using2。这样不会冲突。
下面是一个正常的例子:
C程序:voidint0()interrupt0using1
编译后的汇编如下:
PUSHACC
PUSHB
PUSHDPH
PUSHDPL
PUSHPSW
MOV PSW,#0x08
。。。。。。
如果你的中断程序不去改动,当然不受影响。不过,因为中断,堆栈会压入断点地址,这样堆栈指针就受影响了。
有改动的话当然是影响的,因为堆栈是RAM的一部分,而所有的RAM都是全局的。因此任何一部分程序的改动都是有影响的。
以上就是关于51单片机汇编中断堆栈保护问题,求大神赐教,小弟在此谢谢。在线等。全部的内容,包括:51单片机汇编中断堆栈保护问题,求大神赐教,小弟在此谢谢。在线等。、51单片机中断寄存器使用注意的问题、单片机寄存器中的数据进入堆栈后受不受中断程序控制等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)