51单片机,汇编。想做高精度时钟。纠结于定时中断函数返回的问题。
用仿真器一直没明白,定时中断函数执行过程中定时器处于中止状态?
如下程序:
ORG 0000H
AJMP MAIN
;
ORG 0003H
RETI
;
ORG 000BH
AJMP TIMER0
;
ORG 0013H
RETI
;
ORG 001BH
RETI
;
ORG 0030H
MAIN: MOV TMOD,#01H
MOV TH0,#0FFH
MOV TL0,#0A0H
SETB EA
SETB ET0
SETB TR0
AJMP $
TIMER0: MOV TH0,#0FFH
MOV TL0,#0A0H
MOV A,#FFH
LOOP: DEC A
JNZ LOOP
RETI
END
是否在TIMER0函数执行过程中及其调用的函数执行过程中,定时器0处于中止状态,直至REI返回?RETI返回时将PC从栈中取回继续执行中断前程序,是否同时清除定时器0中断标志位?
还是当TIMER0函数执行的同时,定时器0中断标志位已经清0,并且定时器0已经开始重新计时?
另外,中断函数执行时,单片机只将PC压栈,那么普通函数调用时,单片机将哪些寄存器值压栈?全部功能寄存器?还是只有PC?还是部分功能寄存器值压栈?
另外有个不爽的代码。
51汇编不支持MOV R0,R1这种代码,只能MOV R0,01H。真是无语。
Sorry.习惯于C和C++的一些说法,大家也别太深究。
前面定时器0中断子程序里写了一段循环是说明问题。总共255*3=765时钟周期。但在我自己的代码里可能还不止这么多,按中断优先级的说法,同级中断子程序执行中,定时器0溢出的中断不会再响应。如果用做高精度的时钟,应该会出现漏掉部分中断造成计时变慢,不知道有什么解决办法。另外,中断子程序必须给TH0,TL0重新赋值,如果想要时钟更精确的话要考虑这部分代码的执行时间?比如:
TIMER0: MOV TH0,#FFH
MOV TL0,#0A0H
RETI
这样的中断子程序本身执行要4个时钟周期,如果要精确计时95ms是不是至少改成
MOV TH0,#0FFH
MOV TL0,#9CH
?
网上查了一些资料,没有查找51单片机自定义栈的说明,下面是自己自定义栈以及现实的一个子程序,使用R0做自定义栈栈顶指针。不知道是否正确?