关于51单片机中的计时小编程问题

书上的示例是要求P1.0口输出周期为2ms的方波,书上给出如下程序:

有一点不明白,在重装T1初值后P1.0取非后,要过1ms才能从SJMP $原地踏步中跳到BRT1中,再经过两条赋值指令才再次对P1.0取非,这两条指令的执行要经过几个机器周期的时间,这样输出的方波周期就大于2ms了吧,这么想错在哪了呢?

第1个回答  2014-05-30
这么想没错。定时器定时虽说比程序延时来得精确,但不是说没有误差。不管怎么说,误差总是客观存在的。这里补充两点:
1、 原程序存在错误。定时器方式0最大计数值为2^13=8192us,初装值为E018H=57368us,即定时定时初装值已远大于最大计数值。
如果要在方式0下定时1ms=1000us,初装值应为8192-1000=7192 = 1C18H ,其它语句的执行因为是2~3us级,可忽略(因数中断程序中的三个语句耗时仅6us)。你可能要问:为什么不把这些时间折算到定时初值中去?答案是没有必要。再怎么折算,都有误差,更何况机器周期的时间也是估算的。
2、 若想再精确一些,则可采用方式2(自动重装初值)。追问

书上采用的是方式0,说由于TL1高三位不能用,所以应把1C8H改写成E018H,应该没错。主要是老师要我们拿内部定时器定时中断编一段电子秒表程序,如果这么来误差也太大了吧

追答

是啊,误差是比较大,对时钟显示编程尤为明显。但对秒表影响相对较小,我们就以1ms偏差6个us来看,1s 偏差6ms, 60s偏差360ms(=0.36s)。
本程序如果采用定时器方式2,则偏差会更小,所以我们说对秒表影响较小。

第2个回答  推荐于2016-06-01
你理解的是对的。
关于51定时器的重装问题,典型的解决办法是动态重装。即在重新新的计数初值时,要把前次溢出到本次准备执行重装初值的这段时间的计数,从要装载的总数中减掉。
举例来说,假设中断间隔是1000个计数,重装的初值就是-1000。中断中不能直接重新-1000,而应该重装-(1000-TH/TL),即重装值是-1000+TH/TL。
isr_t0:
push psw

clr tr0
xch a, tl0
add a, #LOW(-1000+7)
xch a, tl0
xch a, th0
addc a, #HIGH(1000+7) // tr0 暂停了7个周期,需要加上去。
xch a, th0
set tr0

cpl p1.0 // 此处可以执行用户想做的事件,但时间不断太长。

pop psw
reti

当然,也不能完全说书上是错的,只能说书上的例子不严谨。本回答被提问者采纳
相似回答