MCS-51单片机的中止呼应延迟时刻,取决于其它中止服务程序是否在进行,或取决于正在履行的是什么样的指令。单中止体系中的中止呼应时刻为3~8个机器周期[1]。无论是哪一种原因引起的差错,在准确守时的运用场合,有必要考虑它们的影响,以保证准确的守时操控。依据守时中止的不同运用状况,应挑选不同的准确守时编程办法。
文中以守时器T1作业在守时办法1为例,晶振频率为12MHz。
1 办法1
在守时器溢出中止得到呼应时,中止守时器计数,读出计数值(反映了中止呼应的延迟时刻),依据此计数值算出到下一次中止时,需多长时刻,由此来重装载和发动守时器。例如守时周期为1ms,则一般守时器重装载值为-1000(0FC18H)。下面的程序在核算每个守时周期的准确重装载值时,考虑了由中止计数(CLR TR1)到重新发动计数(SETB TR1)之间的7个机器周期时刻。程序中#LOW(-1000+7)和#HIGH(-1000+7)是汇编符号,别离表明-1000+7=0FC1FH这个当即数的低位字节(1FH)和高位字节(0FCH)。
……
CLR EA ;制止一切中止
CLR TR1 ;中止守时器T1
MOV A,#LOW(-1000+7) ;希望数的低位字节
ADD A,TL1 ;进行批改
MOV TL1,A ;重装载低位字节
MOV A,#HIGH(-1000+7) ;对高位字节处理
ADDC A,TH1
MOV TH1,A
SETB TR1 ;重发动守时器
SETB EA ;重开中止
……
此办法适用于各种原因形成的守时差错的状况,为通用办法。
2 办法2
假设守时周期为10ms,一般守时器重装载值为0D8F0H,中止子程序如下[2]:
ORL TL1,#0F0H
MOV TH1,#0D8H
……
这儿用ORL TL1,#0F0H替代MOV TL1,#0F0H 可进步守时精度。此办法只适用于重装载值低位字节的低4位为零,且中止呼应的延迟时刻小于16个机器周期的状况。相似的守时器重装载值有0FFF0H,0FFE0H等。
3 办法3
假设守时周期为1ms,一般守时器重装载值为0FC18H,中止子程序如下:
MOV A,#LOW(-1000+4) ;希望数的低位字节
ADD A,TL1
MOV TL1,A
MOV A,#HIGH(-1000+4) ;对高位字节处理
ADDC A,TH1
MOV TH1,A
DEC TL1 ;康复提早了的2个机器周期
……
这种办法中不中止守时器计数进程,若在履行指令ADDC A,TH1 或MOV TH1,A时,刚好产生TL1溢出向TH1进位的状况,则TH1的值就不对了,会产生更大的差错。为此,程序段最初为重装载值加4,若有溢出进位,则可提早产生,其间2个机器周期是考虑到为TL1重装载占用的时刻。
此办法适用于体系中无其它更高优先级中止源的状况。若相似办法1,在程序段最初和结束别离加上制止一切中止(CLR EA)和开中止(SETB EA)指令,则将适用于一切状况。
4 办法4
假设守时周期不确定,只知道守时器重装载值存放在寄存器R3、R2中,中止子程序如下:
MOV A,#05H ;3个机器周期装载TL1,2个周期提早
ADD A,TL1
ADD A,R2
MOV TL1,A
MOV A,R3 ;处理高位字节
ADDC A,TH1
MOV TH1,A
DEC TL1 ;康复提早了的2个机器周期
……
此法适用于守时周期不确定的状况,其它同办法3。
5 办法5
当守时中止产生的方位可预知时,一般出现在主程序的AJMP $ (或SJMP $)等候指令处,中止延迟时刻为3个或4个机器周期。取固定值4可简化补偿程序。以守时周期1ms为例,中止子程序如下:
ORG 001BH
MOV TL1,#LOW(-1000+4)
MOV TH1,#HIGH(-1000+4)
……
此办法适用于守时中止总产生在同一条指令方位,且无其它中止源的状况。
结 语
上述5种办法差错均不超越1个机器周期,其间办法1、3、4较为通用,适用于任何状况,但程序较长;办法2、5简略,但有必要留意满意对应条件,才干运用。