zhenglingo 发表于 2012-11-18 23:35:58

51单片机的定时器纠结了很久的问题

请问前辈们51单片机里的定时器   在初始化给TH0TL0装上值,然后溢出,申请中断(假设中断打开),进入中断服务函数后,重新给TH0,TL0装值,请问此时TH0,TL0是出中断以后开始计数还是一进中断装上值就开始计数?

health 发表于 2012-11-19 01:09:58

一直不停计数。

zhenglingo 发表于 2012-11-19 07:33:35

health 发表于 2012-11-19 01:09 static/image/common/back.gif
一直不停计数。

你的意思就是只要赋值后就开始计数了   我明白了谢谢

health 发表于 2012-11-19 10:42:33

zhenglingo 发表于 2012-11-19 07:33 static/image/common/back.gif
你的意思就是只要赋值后就开始计数了   我明白了谢谢

和赋值没什么关系的,只受运行控制位控制,如TR0。

853728579 发表于 2012-11-19 10:59:07

在开中断后,定时器就开始计数,在计数溢出之后,产生一个中断信号,进入中断服务程序,在中断服务程序中又重新给TH和TL赋值,只要你定时器的开着的,那第计数器是一直在计数,你要知道,定时器和中断是分开的。

zhenglingo 发表于 2012-11-19 11:02:51

health 发表于 2012-11-19 10:42 static/image/common/back.gif
和赋值没什么关系的,只受运行控制位控制,如TR0。

      初始化已经给TH0,TL0装上值了(非自动重装模式下), 如果溢出(中断允许时),此时TH0,TL0都为0了,进入中断服务函数中,重新装值。那你的意思就是在中断里装上值后定时器就开始跑吗?还是等退出中断函数后计数?你说的一直不停的计数那是在自动重装模式下吧

zhenglingo 发表于 2012-11-19 11:21:01

853728579 发表于 2012-11-19 10:59 static/image/common/back.gif
在开中断后,定时器就开始计数,在计数溢出之后,产生一个中断信号,进入中断服务程序,在中断服务程序中又 ...

你的意思是在进入中断给TH0 TL0装值后,定时器就开始计数吗?而不是等中断结束后开始 (定时器已经打开,并且不是自动重装模式下。

853728579 发表于 2012-11-19 11:41:15

给你赋不赋值是没有关系的,只要你一开定时器开始计数,计数器就一直在计数了,定时器的是否工作是由:TMOD和 TCON 这两个寄存器来控制的,不是说给TH0和TL0赋值后,定时器才开始工作,

wicy001 发表于 2012-11-19 11:49:17

health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。

------------------
前面人家说的很清楚了。
只要TRx=1,定时器就运行,你赋不赋值都要将计数寄存器(TH,TL)++的。
只要TRx=0,定时器就停止。

你赋初值只是决定定时器从什么值开始++而已 。
自动重装方式,也只是管着自动重装计数初值,与计时器是否运行无关

405254609 发表于 2012-11-19 11:58:31

一直在计时的,

287504461 发表于 2012-11-19 12:22:40

如果在中断中打开计时器就会计时。。

zhanyanqiang 发表于 2012-11-19 15:34:26

一启动定时器就开始计数,独立的(它自己一直在动作),中断里面赋值只是把计数器里面我们不想要的的值刷一下(变成我们想要的)。可以这么理解

zhenglingo 发表于 2012-11-20 19:32:39

health 发表于 2012-11-19 10:42 static/image/common/back.gif
和赋值没什么关系的,只受运行控制位控制,如TR0。

嗯我明白了 多谢

zhenglingo 发表于 2012-11-20 19:41:16

853728579 发表于 2012-11-19 11:41 static/image/common/back.gif
给你赋不赋值是没有关系的,只要你一开定时器开始计数,计数器就一直在计数了,定时器的是否工作是由:TMOD ...

嗯    根据你的解释    在TH0TL0溢出时假设中断允许,那么在进入中断的过程中TL0 TH0始终在计数,因为由溢出到进入中断的时间很小(如果此时CPU不在执行更乘法指令或者已经进入其它中断的服务函数),在这种情况下只有TL0计了数,当进入后又重装TH0,TL0这时重装的TL0与之前的TL0是否为相加或者被替换掉,TL0 = 重装值 还是 TL0 = 重装值+溢出到中断过程中TL0计数值   假设我不忽略这个过程的误差情况下,只是为了更加精确

zhenglingo 发表于 2012-11-20 19:43:08

wicy001 发表于 2012-11-19 11:49 static/image/common/back.gif
health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。



thank you   

zhenglingo 发表于 2012-11-20 19:51:01

zhanyanqiang 发表于 2012-11-19 15:34 static/image/common/back.gif
一启动定时器就开始计数,独立的(它自己一直在动作),中断里面赋值只是把计数器里面我们不想要的的值刷一 ...

不想要的值?指的是误差值吗?比如说从溢出后的到进入中断 这段时间TL0计的值是这段不要吗? 要道理来说应该需要加上这段值才准确啊   经查资料我知道TH0 TL0溢出后并不是马上得到中断响应所以此时计数器还在计数假设为T1当进入中断后 重装了TH0 TL0那么之前的T1是如何处理的?如果舍弃就不准确了应该需要加上这个值吧对于这点还是有点迷惑

roy2002 发表于 2012-11-20 20:02:45

分开的,一个管一个的,不冲突

cddyy 发表于 2012-11-20 20:42:44

所以51的16位定时器方式是有误差的,要提前消掉。

zhenglingo 发表于 2012-11-20 20:56:53

cddyy 发表于 2012-11-20 20:42 static/image/common/back.gif
所以51的16位定时器方式是有误差的,要提前消掉。

你好   哪么我这样处理是否正确呢在中断中装值时TLX= TLX+ 初值 TLX= TLX+ 初值   这样处理可以吗?

zhenglingo 发表于 2012-11-20 21:38:31

roy2002 发表于 2012-11-20 20:02 static/image/common/back.gif
分开的,一个管一个的,不冲突

你好   哪么我这样处理是否正确呢在中断中装值时TLX= TLX+ 初值 TLX= TLX+ 初值   这样处理可以吗?

roy2002 发表于 2012-11-20 22:06:30

zhenglingo 发表于 2012-11-20 21:38 static/image/common/back.gif
你好   哪么我这样处理是否正确呢在中断中装值时TLX= TLX+ 初值 TLX= TLX+ 初值   这样处理可以吗? ...

不用加哦,加了就不是你需要的了吧,中断发生了的同时就赋了初值了,我是这样理解的

xslff 发表于 2012-11-20 22:10:16

本帖最后由 xslff 于 2012-11-20 22:13 编辑

虽然是个小问题,但很重要。
我的理解(暂未实验),因该是覆盖,定时器就是个累加器,累加到顶(头)告诉你一声(产生中断),不管你听(中断打开并配套了中断程序)或不听(未开中断或没有中断程序),定时器都会清0并(有延时很短)重新开始累加,如果您听了,中断程序马上运行(有延时)告诉定时器从某个数开始累加(比如从2开始,有的单片机可能才累加到1,有些可能累加到3了),定时器应该直接从给的数开始累加,不会去管自己目前累加到的数。

zhenglingo 发表于 2012-11-20 22:24:23

xslff 发表于 2012-11-20 22:10 static/image/common/back.gif
虽然是个小问题,但很重要。
我的理解(暂未实验),因该是覆盖,定时器就是个累加器,累加到顶(头)告诉 ...

按照你所说的   这样处理应该是没问题的啊   TLX = TLX + 初值THX = THX +初值

xslff 发表于 2012-11-20 22:37:16

本帖最后由 xslff 于 2012-11-20 22:47 编辑

zhenglingo 发表于 2012-11-20 22:24 static/image/common/back.gif
按照你所说的   这样处理应该是没问题的啊   TLX = TLX + 初值THX = THX +初值

请问一下,您做什么要这么精确?

zhenglingo 发表于 2012-11-20 23:02:14

xslff 发表于 2012-11-20 22:37 static/image/common/back.gif
请问一下,您做什么要这么精确?

我用IO口模拟PWM输出,一个可调的占空比   我主要做的就是用PID去控制PWM输出,AD采集的模块。但是用PID去控制占空比来输出PWM时总是不准确,经过发现是定时器不准问题   所以现在就在弄定时器部分,原来我忽略了定时器里的很多细节。    但是THXTLX在溢出之后,仍然会计数啊,看论坛上的帖子,在溢出到中断期间会需要一定的时间假设为T1,如果我需要更准确的定时,那么在进入中断后重新装值,按你所说,THX,TLX的的值被覆盖,如果不加处理,整个过程中就多计数了T1,因为这个T1是定时器自己加的值,所以在重装值时应该加上这个值还补偿啊,就是说应该让定时器少计数T1了,因为定时器所计的时间是0XFFFF-初值   所以0XFFFF-(初值+T1),这样不就是减去了多计的时间吗?不知道这样理解有没有问题

zhanyanqiang 发表于 2012-11-21 10:44:17

zhenglingo 发表于 2012-11-20 23:02 static/image/common/back.gif
我用IO口模拟PWM输出,一个可调的占空比   我主要做的就是用PID去控制PWM输出,AD采集的模块。但是用PI ...

T1清零了马上硬件自己重新开始从0计数,到我中断入口函数赋值这段时间T1,目前来说我也是这么理解的~~~~

xslff 发表于 2012-11-21 11:13:51

本帖最后由 xslff 于 2012-11-21 11:15 编辑

zhenglingo 发表于 2012-11-20 23:02 static/image/common/back.gif
我用IO口模拟PWM输出,一个可调的占空比   我主要做的就是用PID去控制PWM输出,AD采集的模块。但是用PI ...

这个应该比较难精确,但我觉得有办法让这个误差缩小!
首先因为定时器的速度和单片机的工作频率精密相关,所以缩小误差的工作必须首先保证有稳定的工作频率!
然后要反复的做试验(汇编代码),看看这个误差均值是多少(固定频率)!
其次赋值过程中对试验得到的误差均值进行处理同时还要注意赋值运算差生的误差(不知道您在不在意这个微小的误差)!
最后重复上面的步骤再次试验,验证直到结果让您满意为止!


PS:这么费劲,还不如更换一款性能高的单片机!

zhenglingo 发表于 2012-11-21 14:49:43

zhanyanqiang 发表于 2012-11-21 10:44 static/image/common/back.gif
T1清零了马上硬件自己重新开始从0计数,到我中断入口函数赋值这段时间T1,目前来说我也是这么理解的~~~~ ...

那么找我这样处理没有问题吗?在进入中断后TLX = TLX + 初值THX = THX +初值

页: [1]
查看完整版本: 51单片机的定时器纠结了很久的问题