51单片机程序定时器怎么这么不准确啊,求高手指点!

单片机:ATML89S52 晶振:11.0592MHZ
要求:560us波形
说明:两个定时器都在使用,波形正常,但是定时器T0出来的延时与理想值相差很多,计算的理想值应该是560/(12/11.0592)=516.实际使用的是780后,示波器观察延时才是560us。另外有时候,定时器又是极为准确的,真不明白到底是说明原因?
程序:
void initial(void)
{
TMOD=0x11;//定时器0,1方式1
TF0=0;
TF1=0;
}

void us_560(void)
{
TH0=-780/256;
TL0=-780%256;
TR0=1;//定时器0开始计数
TR1=1;//定时器1开始工作
while(TF0==0)
{
TH1=0xff;
TL1=-1;
while(TF1==0) {};
P3_4=!P3_4;
TF1=0;
}
TF0=0;
}
最初版本: TH0=-516/256;TL0=-516%256; //偏差非常大
修改为程序中得 :TH0=-780/256; TL0=-780%256; //基本准确
刚才又试了下改成:TH0=(65536-516)/256 ;TL0=(65536-516)%256;//基本准确
请问这又是什么原因呢?

这是编译器造成的,你最好用Debug模式看看生成的汇编代码是什么摸样,比较一下你那三种方 式给TH0和TL0赋的是什么样的值。

这是我试验的结果:
4: TH0=-780/256;
C:0x0003 758CFD MOV TH0(0x8C),#0xFD
5: TL0=-780%256;
C:0x0006 758AF4 MOV TL0(0x8A),#0xF4
6: TH0=-516/256;
C:0x0009 758CFE MOV TH0(0x8C),#0xFE
7: TL0=-516%256;
C:0x000C 758AFC MOV TL0(0x8A),#0xFC
8: TH0=(65536-516)/256;
C:0x000F 758CFD MOV TH0(0x8C),#0xFD
9: TL0=(65536-516)%256;
C:0x0012 758AFC MOV TL0(0x8A),#0xFC

看出差别了吧?使用-780时给T0赋值0xFDF4,使用第三种方式赋值为0xFDFC,这两个数字相近,所以结果基本正确。但是使用-516时赋值的0xFEFC,这差别就大了,结果就是不正确。

一般建议用TH0=(65536-516)/256 ;TL0=(65536-516)%256;这种方式,保证不出问题。
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-11-10
定时器是从小到大计数的,前2个设置是错误的。
另外,定时器中断处理时有时间开销,如寄存器入栈。尤其是用c编译器,额外开销是不可见的。

学习单片机、CPLD,请到“电子设计网dzsj”
第2个回答  2011-11-10
用中断来做,指令也要占用时间。轮询会随机不确定的。
第3个回答  2011-11-10
每条指令也需要时间呀,当然不是516,而是780很正常,你可以减掉这个误差值呀,追问

如果指令也算时间的话,那么计数的应该更短啊,而不是变长啊!

51单片机程序定时器怎么这么不准确啊,求高手指点!
这是编译器造成的,你最好用Debug模式看看生成的汇编代码是什么摸样,比较一下你那三种方 式给TH0和TL0赋的是什么样的值。这是我试验的结果:4: TH0=-780\/256;C:0x0003 758CFD MOV TH0(0x8C),#0xFD 5: TL0=-780%256;C:0x0006 758AF4 MOV TL0(0x8A),#0xF4...

51单片机定时器初值用变量设置定时不准确,为什么,求高手。TH0=(65536...
看一下C代码编译后的汇编代码就知道了,用变量方式很耗时,而直接用数字,编译器已经将算式的值算好了,代码里就是一个MOV指令而已,只需1us!!!TH0=(65536-2000)\/256; TL0=(65536-2000)%256;汇编后,只要2us就完事了。 而用变量方式,单片机很忙,计算几十乃至上百微妙才完事!15: TH0...

51 单片机 程序出错 不执行定时器中断1 同时delay函数也有错 求高手...
1.独立按键的判断在程序中如果没有用sbit定义过不能写为 P2^n 的形式,在程序体内这种写法表示的是异或 2.中断程序里,进入中断程序以后如果不是特殊需要,先关断自身的中断控制位,退出中断的时候再打开 3.在单片机里写程序的时候能省资源就省,52单片机是8位的,如果变量范围不超过255就不要用int...

关于51单片机定时器的问题。我用郭天祥的51学习班做了一个电子表,发现...
我做时钟都是用最大的计时时间来减少中断插入的影响,这里用50ms,再减掉5毫秒就基本上差不多了。

为什么51单片机定时器计数值取出来之后会比初值还小
你说的情况可能定时中断函数中没有重装初值或者干脆没有响应定时中断,所以造成计数值小于初值。这种情况有个前提,就是外部中断的产生没有人为干预,原因见下面。2、鉴于你每次读出的都是48,外部中断产生应该是自动的(很有规律),如果不是这样,比如说是手动产生外部中断或者说需要人为控制产生外部中断,...

关于51单片机定时器问题
第一 ,变量 定义 uchar temp;a;b; 中间的 2个 冒号 应该是 逗号(uchar tmep,a,b;),使用 分号的俺还真没 试过;第二,定时器的 2处 初始化值 均错误,TL1=(65536-50000)%256,是 % 运算,不是 \/ 运行,TH1 是正确的。第三,按12MHz 晶振计算,定时器为 50ms 中断,程序 ...

51单片机用定时器输出1HZ方波 为什么我的程序仿真以后io口狂闪 并...
你的if语句后多加了一个分号,所以单片机一个while循环就一直在执行led=~led,所以io就狂闪

51单片机时钟不准,8小时就慢1分钟,请大家帮忙看看
不用外部的时钟,照样可以得到准确的时间,精度可以和晶振的精度相同。采用定时器2,自动重装初始值,就是一个可行的方法。采用定时器0、1,也可以,只是中断的次数,频繁了一些。

单片机高手给点拨下,定时器这个不太理解,定时器初始化有几种方法啊...
51 单片机中定时器,是个 16 位的加法计数器。其内容是 0000H ~ FFFFH,即:0 ~ 65535。每隔一个机器周期,加一次一。加到 65536,就会溢出,产生中断。在外部振荡器频率 = 11.0592 MHz 时,机器周期=1085.06944...us。要想定时 1000us,这就有点困难了。在外部振荡器频率 = 12 MHz 时,...

51单片机程序如下,问定时器为啥没工作,求改错。
判断if(TF0==1)是否满足,这里不满足(因为TF0=0),所以 IF里面所有的东西都没有执行(包括定时器的重装),所以定时器只计数了一次,然后程序结束。你这里不能吧定时器0的重装数据放在主函数里面,这个过程要放在中断函数里面取处理,因此用定时器时,要开启定时器0中断。程序应该这么 写:

相似回答