一点看法,如果说的不对,请大家见谅,指正!!
51定时器 的 模式2 有个特点就是 不用重装初值,我的单片机课本上这么写着:
“每次计满溢出,寄存器(这里指的是TL0 和 TH0,当然还有 定时器1 的初值。)全部清零,下一次定时计数还要重新装入初值,这样不仅在编程时麻烦,且影响定时时间精度。”
——这本书,是我们老师自己编写的课本,所以就不写出书目信息了。
而我们老师似乎还真是这么做的,在他编写的 实验手册 里,定时器的实验,他还是这么做的。
1秒钟的定时,他把初值设为 100个机器周期,然后软件计数1万次。
做实验的时候我没留意,这两天在编一个类似的程序时,我学习了这个思路,但我却发现,这个思路,在大多数情况下,恰好没有 他所说 的这两个优点:编程简单,定时精度高。
我们就以这个1秒钟的定时来分析一下吧:
首先,因为要软件计数10000次,所以这个计数初值需要两个8位单元存储,就是高低位。(这是麻烦的根源。)
而在中断中,我们需要不断地减1,但是因为,这是高低两位,涉及到低位为0要借高位,所以,不仅麻烦,同时增加了中断程序的执行周期。
我们的实验是这么干的:
下面的HIGH是计数初值的高8位;
LOW是计数初值的低8位,这里我没有实际试一下在编程中用这两个字,因为它们好像是关键字。
这里只是为了明确意义。
TIMER EQU 10000
HIGH EQU 30H
LOW EQU 31H
-----------------------------
MOV A, LOW; (2)
JNZ GOON; (2)
DEC HIGH; (2)
GOON:
DEC LOW; (2)
MOV A, LOW; (2)
ORL A, HIGH; (2)
JNZ EXIT; (2)
MOV HIGH,#HIGH(TIMER); (3)
MOV LOW,#LOW(TIMER); (3)
EXIT:RETI; (1)
每句代码后括号里的数字,是以MCS-51标准查到的 相应代码的指令周期。
也就是说,在中断程序中,要完成计数这一部分的功能,它就需要攻击16个指令周期(最后一次,加重装计数初值,是22个)。
我们知道,定时过程是这样的:定时器完成0到255个机器周期的定时时间,然后进入中断,完成一次计数,然后进入下一个计数循环,也就是说,在这个过程中,我们往往忽略了一个重要的问题——中断程序的执行周期也在每一次计数的执行时间里,也就是说,我们每次定时器定时100个机器周期,但执行起来,实际是100+。
而且,对于 定时模式2 ,因为最大定时只有255个,也就是说,上述这个计数的方法,我们耗掉了22个,这里的定时误差就已经达到了10%。
另外,进了中断,我们可能还要完成别的功能,这就意味着误差会更大。
最核心的问题仍然是 最大定时个数太少,只有255个,只要有20个执行周期就可以达到10%左右,可是,20个执行周期意味着什么呢?
意味着10来条指令,这是很有限的。
前面说过,分成高低两位的计数初值是麻烦的根源,前面说的是它占用了不少的实现计数功能的执行周期以外,它还很麻烦:
因为最大定时初值只有255个,一般我们取250个吧,(4×250=1000)
所以,对于一般的定时要求,比如1秒钟,我们的计数初值就要4000,如果时间再长点,可能要用到三个8位,那事情会更麻烦,而且误差也会更大。
当然,今天我想起了一个以前看到的别的方法,比如说,定时5秒,做一个1秒钟的定时子程序(就是上面的那个程序作为子程序)。
然后用DJNZ 循环计数,这样的话,虽然可能还是用3个8位,但是误差还是跟用两位计数初值一样。但是,到底是麻烦。
而用定时模式1,我们也来算一算,我们会发现,这个方法简单,而且定时精度其实要比模式2更好:
这时,中断程序中的计数很简单:
这里TIMER是定时初值,一般我取50毫秒,5万
----------------------------
DEC R0; (2)
MOV A,R0; (1)
JNZ EXIT; (2)
//MORE CODE FOR OTHER FUNCTION;
MOV TL0,#LOW(TIMER); (3)
MOV TH0,#HIGH(TIMER); (3)
EXIT:RETI; (1)
这里,总共只有6个机器周期,(在满一秒后,是12个机器周期)。
就算是12个周期,重要的事实是,每次的定时长度是50000个周期,相比而言,只有万分之6的误差。
同样的,它对于 中断程序 的执行周期也不像 模式2 那样敏感。前面说过,只有20个机器周期,就可以引起10%左右的误差,而在模式1里,500个执行周期,也才引起1%的定时误差,500个机器周期,至少也是500/3=167条指令。
因此我想这么总结一下:
在定时长度较小(至少小于65535个机器周期吧。否则就得高低两位计数初值。)
另外,中断程序还要比较小。这种情况下,使用模式2,会比较方便,引起的定时误差也不大。
但是,大家是否觉得这两个条件比较苛刻呢?
其实,仔细想想
模式1也就是要重装初值,也就是两条指令,六个执行周期,而且是50000个周期之后,才多了这6个执行周期,你真的那么介意吗?
[ 本帖最后由 辛昕 于 2010-6-2 11:56 编辑 ]