搜索
bottom↓
回复: 27

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

[复制链接]

出0入0汤圆

发表于 2012-11-18 23:35:58 | 显示全部楼层 |阅读模式
请问前辈们  51单片机里的定时器   在初始化给TH0  TL0装上值,然后溢出,申请中断(假设中断打开),进入中断服务函数后,重新给TH0,TL0装值,请问此时TH0,TL0是出中断以后开始计数还是一进中断装上值就开始计数?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-11-19 01:09:58 | 显示全部楼层
一直不停计数。

出0入0汤圆

 楼主| 发表于 2012-11-19 07:33:35 | 显示全部楼层
health 发表于 2012-11-19 01:09
一直不停计数。

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

出0入0汤圆

发表于 2012-11-19 10:42:33 | 显示全部楼层
zhenglingo 发表于 2012-11-19 07:33
你的意思就是只要赋值后就开始计数了   我明白了  谢谢

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

出0入0汤圆

发表于 2012-11-19 10:59:07 | 显示全部楼层
在开中断后,定时器就开始计数,在计数溢出之后,产生一个中断信号,进入中断服务程序,在中断服务程序中又重新给TH和TL赋值,只要你定时器的开着的,那第计数器是一直在计数,你要知道,定时器和中断是分开的。

出0入0汤圆

 楼主| 发表于 2012-11-19 11:02:51 | 显示全部楼层
health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。

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

出0入0汤圆

 楼主| 发表于 2012-11-19 11:21:01 | 显示全部楼层
853728579 发表于 2012-11-19 10:59
在开中断后,定时器就开始计数,在计数溢出之后,产生一个中断信号,进入中断服务程序,在中断服务程序中又 ...

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

出0入0汤圆

发表于 2012-11-19 11:41:15 | 显示全部楼层
给你赋不赋值是没有关系的,只要你一开定时器开始计数,计数器就一直在计数了,定时器的是否工作是由:TMOD  和 TCON 这两个寄存器来控制的,不是说给TH0和TL0赋值后,定时器才开始工作,

出0入17汤圆

发表于 2012-11-19 11:49:17 | 显示全部楼层
health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。

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

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

出0入0汤圆

发表于 2012-11-19 11:58:31 | 显示全部楼层
一直在计时的,

出0入0汤圆

发表于 2012-11-19 12:22:40 | 显示全部楼层
如果在中断中打开计时器就会计时。。

出0入4汤圆

发表于 2012-11-19 15:34:26 | 显示全部楼层
一启动定时器就开始计数,独立的(它自己一直在动作),中断里面赋值只是把计数器里面我们不想要的的值刷一下(变成我们想要的)。可以这么理解

出0入0汤圆

 楼主| 发表于 2012-11-20 19:32:39 | 显示全部楼层
health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。

嗯  我明白了 多谢

出0入0汤圆

 楼主| 发表于 2012-11-20 19:41:16 | 显示全部楼层
853728579 发表于 2012-11-19 11:41
给你赋不赋值是没有关系的,只要你一开定时器开始计数,计数器就一直在计数了,定时器的是否工作是由:TMOD ...

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

出0入0汤圆

 楼主| 发表于 2012-11-20 19:43:08 | 显示全部楼层
wicy001 发表于 2012-11-19 11:49
health 发表于 2012-11-19 10:42
和赋值没什么关系的,只受运行控制位控制,如TR0。

thank you   

出0入0汤圆

 楼主| 发表于 2012-11-20 19:51:01 | 显示全部楼层
zhanyanqiang 发表于 2012-11-19 15:34
一启动定时器就开始计数,独立的(它自己一直在动作),中断里面赋值只是把计数器里面我们不想要的的值刷一 ...

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

出0入0汤圆

发表于 2012-11-20 20:02:45 | 显示全部楼层
分开的,一个管一个的,不冲突

出50入0汤圆

发表于 2012-11-20 20:42:44 | 显示全部楼层
所以51的16位定时器方式是有误差的,要提前消掉。

出0入0汤圆

 楼主| 发表于 2012-11-20 20:56:53 | 显示全部楼层
cddyy 发表于 2012-11-20 20:42
所以51的16位定时器方式是有误差的,要提前消掉。

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

出0入0汤圆

 楼主| 发表于 2012-11-20 21:38:31 | 显示全部楼层
roy2002 发表于 2012-11-20 20:02
分开的,一个管一个的,不冲突

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

出0入0汤圆

发表于 2012-11-20 22:06:30 | 显示全部楼层
zhenglingo 发表于 2012-11-20 21:38
你好   哪么我这样处理是否正确呢  在中断中装值时  TLX= TLX+ 初值 TLX= TLX+ 初值   这样处理可以吗? ...

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

出0入0汤圆

发表于 2012-11-20 22:10:16 | 显示全部楼层
本帖最后由 xslff 于 2012-11-20 22:13 编辑

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

出0入0汤圆

 楼主| 发表于 2012-11-20 22:24:23 | 显示全部楼层
xslff 发表于 2012-11-20 22:10
虽然是个小问题,但很重要。
我的理解(暂未实验),因该是覆盖,定时器就是个累加器,累加到顶(头)告诉 ...

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

出0入0汤圆

发表于 2012-11-20 22:37:16 | 显示全部楼层
本帖最后由 xslff 于 2012-11-20 22:47 编辑
zhenglingo 发表于 2012-11-20 22:24
按照你所说的   这样处理应该是没问题的啊   TLX = TLX + 初值  THX = THX +初值


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

出0入0汤圆

 楼主| 发表于 2012-11-20 23:02:14 | 显示全部楼层
xslff 发表于 2012-11-20 22:37
请问一下,您做什么要这么精确?

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

出0入4汤圆

发表于 2012-11-21 10:44:17 | 显示全部楼层
zhenglingo 发表于 2012-11-20 23:02
我用IO口模拟PWM输出,一个可调的占空比   我主要做的就是用PID去控制PWM输出,AD采集的模块。  但是用PI ...

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

出0入0汤圆

发表于 2012-11-21 11:13:51 | 显示全部楼层
本帖最后由 xslff 于 2012-11-21 11:15 编辑
zhenglingo 发表于 2012-11-20 23:02
我用IO口模拟PWM输出,一个可调的占空比   我主要做的就是用PID去控制PWM输出,AD采集的模块。  但是用PI ...


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


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

出0入0汤圆

 楼主| 发表于 2012-11-21 14:49:43 | 显示全部楼层
zhanyanqiang 发表于 2012-11-21 10:44
T1清零了马上硬件自己重新开始从0计数,到我中断入口函数赋值这段时间T1,目前来说我也是这么理解的~~~~ ...

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

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 15:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表