打印

定时器 定时一秒为何不准 先谢谢大家了

[复制链接]
8254|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhengjirui|  楼主 | 2010-10-28 22:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void main()
{

t0=0;

fz=0;
   
TMOD=0x01;             //同时选择定时器         
    TH0=(65536-50000)/256;

TL0=(65536-50000)%256; //定时赋初值        

EA=1;

ET0=1;

TR0=1;
//让定时器1.2启动

while(1)

{

c=fz/10;

d=fz%10;

e=miao/10;

f=miao%10;

display(c,d,e,f);
//特别重要,要是放在定时函数中显示的是左边的偏暗,右边的亮

}                                   //特别重要,要是放在定时函数中显示的是左边的偏暗,右边的亮

}

void time0() interrupt 1
{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

t0++;

if(t0==20)

{   

t0=0;

miao++;

if(miao==60)

{

fz++;

if(fz==2)

{

fz=0;

miao=0;

}

miao=0;

}

}
/*

    c=fz/10;

d=fz%10;

e=miao/10;

f=miao%10;

display(c,d,e,f);
*/
//特别重要,要是放在定时函数中显示的是左边的偏暗,右边的亮
}

相关帖子

沙发
zhengjirui|  楼主 | 2010-10-28 22:42 | 只看该作者
使用的是12m的晶振 ,   定时数选的是50000  乘以20  ,后来测了一下不准,改成40000    25能好一点
不知道为什么   麻烦大家解释一下

使用特权

评论回复
板凳
ayb_ice| | 2010-10-29 08:26 | 只看该作者
中断响应是要时间的,
在重新赋值时,定时器仍在运行,这时会有误差
解决方法
1: 补偿误差
2: 自动重装载

使用特权

评论回复
地板
laoliang3064| | 2010-10-29 08:53 | 只看该作者
这就是C和汇编的差别。

使用特权

评论回复
5
yuyetufu| | 2010-10-29 09:35 | 只看该作者
有点误差也是难免的,关键是误差多少?一般是很小的。

使用特权

评论回复
6
ayb_ice| | 2010-10-29 09:44 | 只看该作者
程序(人为)误差是完全可以消除的

使用特权

评论回复
7
刘前辈| | 2010-10-29 09:54 | 只看该作者
本帖最后由 刘前辈 于 2010-10-29 10:19 编辑

如果按照3楼的说法,只要在timer0( )中断程序中把TL0的重装语句注释掉就可以达到自动修正;像下面这样:

void time0() interrupt 1
{
TH0=(65536-50000)/256;

//TL0=(65536-50000)%256;  //把这句注释掉。

t0++;
if(t0==20)
……
……

这不知是所长还是HotPower的专利,凡是16进制最后一个数(二进制最后4位)为 0H的T1/T0 重装值,都可以通过这种方法实现精确修正。
例如50ms定时重装值是3CB0H,你肯定能在32us之内响应中断,这时TL0所走过的数,正好就是你要修正的值!Hot说“只要保证TL0不翻山就行……”他说的是重载值最后8位为0的情况。其实只要最后4位(TL0低半字节)就行。
        
       注意上述所说的忽悠点,能够发现并修改完善的一定是细心的人。

使用特权

评论回复
8
ayb_ice| | 2010-10-29 10:04 | 只看该作者
本帖最后由 ayb_ice 于 2010-10-29 10:06 编辑

下面是标准的处理汇编程序
中断在重新赋初值部分,请确保此中断是最高优先级中断,同时不和别的中断共享最高级优先级

; Update 8051 Interrupt Timer
                CLR        TR0
                MOV        A,TL0
                ADD        A,#LOW (?RTX_CLOCK + 7)
                MOV        TL0,A
                MOV        A,TH0
                ADDC        A,#HIGH (?RTX_CLOCK + 7)
                MOV        TH0,A
                SETB        TR0

其它方法还有很多

以上是KEIL RTX51 TINY的系统中断部分源代码(只适应于标准51,不同的单周期51要修改才行)

使用特权

评论回复
9
刘前辈| | 2010-10-29 10:40 | 只看该作者
本帖最后由 刘前辈 于 2010-10-29 10:44 编辑

8楼的程序应用是有前提条件的:

1、系统中只有一个、并且是唯一的一个中断timer0( );
2、timer0 中断的发生时刻,只能在单机器周期指令期间!如果是发生在双机器周期或者3机器周期指令期间,修正值就不只是7 。
   (?RTX_CLOCK + 7)只是按照timer0 最短响应时间计算的。往往中断响应时间不一定总是最短,还可能是(?RTX_CLOCK + 8),或(?RTX_CLOCK + 9),不是静态修正值。所以:

   (?RTX_CLOCK + 7)不是一个精确修正值。只是一个“差不多”可以接受的修正值。

使用特权

评论回复
10
ayb_ice| | 2010-10-29 10:51 | 只看该作者
LS理解错了

这是精确的,只要保证此时不被中断即可,这是很容易保证的

使用特权

评论回复
11
刘前辈| | 2010-10-29 11:49 | 只看该作者
除非10楼能够说明:

1、 (?RTX_CLOCK + 7)的7是怎么来的?——光说“精确”是空话。
2、dengmiao有个修正程序,他用的是+8 。如果+7 精确,那么dengmiao,还有singleywy(他说他仔细研究过)都错了!
3、当然3者都是同一条件:12M标准8051。
4、到底谁对?3个中国人,一个也没说清楚自己的+7,+8是怎么来的?+7是Copy了Intel的,+8 就算是dm的原创,singleywy 还是没说清+8 是怎么来的。
5、所长和Hot的程序修正绝对精确,理论无懈可击。范围条件限制清楚。我们最好也能做到。



、、


使用特权

评论回复
12
ayb_ice| | 2010-10-29 12:01 | 只看该作者
可以看出赋初值并不是直接赋值
在TR0=0后,定时器就不走了,在TR0=0之前定时器不是0而是响应中断的延时+运行至TR=0的那些指令的周期数
在此基础上修正一下即可,7就是TR0=0和TR0 = 1之间的指令周期数

使用特权

评论回复
13
老鱼探戈| | 2010-10-29 12:29 | 只看该作者
主要是指令误差,
误差要通过软件调整的

使用特权

评论回复
14
ayb_ice| | 2010-10-29 13:30 | 只看该作者
计算如下

周期1    CLR        TR0
周期1    MOV        A,TL0
周期1    ADD        A,#LOW (?RTX_CLOCK + 7)
周期1    MOV        TL0,A
周期1    MOV        A,TH0
周期1    ADDC       A,#HIGH (?RTX_CLOCK + 7)
周期1    MOV        TH0,A
            SETB       TR0

使用特权

评论回复
15
aceice| | 2010-10-29 13:34 | 只看该作者
从响应中断到关闭定时器之间是需要时间的,关闭定时器后,将这个值修正过来即可。

使用特权

评论回复
16
ninibaba| | 2010-10-29 14:10 | 只看该作者
想要非常精确的定时
就要用示波器抓这个时间
比如让某一个IO口
在定时时间到后输出方波
这样就可以得到定时时间了
然后根据得到的时间去调整

使用特权

评论回复
17
刘前辈| | 2010-10-29 14:56 | 只看该作者
本帖最后由 刘前辈 于 2010-10-29 14:59 编辑

明白了。
还有一个疑问:如果LZ是这个问题,那么:
50ms 里不过误差5~10us而已,一秒钟最大误差不过200us!  —— 2个小时才误差1秒!一个软定时器精度不过如此吧。难道LZ能够说一秒钟误差200us(万分之二)的定时器定时不准?

     所以,LZ说的主要恐怕不是修正精度问题。人类的感觉觉察不到万分之二的误差。

使用特权

评论回复
18
ayb_ice| | 2010-10-29 15:21 | 只看该作者
还有很多软件的方法解决误差问题

使用特权

评论回复
19
cheng700127| | 2010-10-29 16:34 | 只看该作者
你选用的晶振是12M的吧,晶振改为11,0592,会不会好一点,
还有一点就是软件本身的缺点了

使用特权

评论回复
20
kuner| | 2010-10-29 17:33 | 只看该作者
加几个nop或 减nop

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

1

粉丝