51单片机定时器不准确,请进

//aabbcc分别是秒分时,09年5月9号 1点10分编 胡智畅
//适用于11.0592M晶振 运行一年误差在一秒左右

#include<intrins.h>
#include <reg51.h>
unsigned char a,a1,a2,a3,a4,aa,bb,cc,dd,ab;
sbit dat=P1^0; //定义驱动74595的数据脚为p1.0 四位数码管连74595
sbit clk=P1^1; //74595的时钟
sbit lat=P1^2; //栓锁
sbit gw=P1^3; //个位显示控制脚
sbit sw=P1^4; //十位
sbit bw=P3^3; //百位
sbit qw=P3^4; //千位
sbit pl5=P3^6; //165锁存 8个键盘连74165
sbit clk5=P3^7; //165时钟
sbit Do5=P3^5; //165串口数据

//------字表------------------------------
unsigned char code tab[]=
{ 0x3F,0x06,0x5B,0x4F, //"0","1","2","3"
0x66,0x6D,0x7D,0x07, //"4","5","6","7"
0x7F,0x6F,0x77,0x7c, //"8","9","A","B"
0x39,0x5e,0x79,0x71,0x80 //"C","D","E","F"
} ;

//------显示延时--------------------------
ds1ms()
{
unsigned char d;
for(d=0;d<250;d++); //大约1ms@12M
}
//------送出循环-------------------------
dsout(unsigned char j)
{
unsigned char i;
for(i=0;i<8;i++)
{
dat=j&0x80; //高位在前
clk=1;
clk=0;
j<<=1;
}
lat=1;
lat=0; //锁存
}
//----74HC595显示程序--------------------
display(unsigned char sjqw,sjbw,sjsw,sjgw,dian)
{
dsout(tab[sjgw]); //查表得到数据段码送显示
gw=0;
ds1ms();
gw=1;
dsout(tab[sjsw]);
sw=0;
ds1ms();
sw=1;
dsout(tab[sjbw]);
bw=0;
ds1ms();
bw=1;
dsout(tab[sjqw]);
qw=0;
ds1ms();
qw=1;
dsout(tab[dian]);
bw=0;
ds1ms();
bw=1;
}

ReadDat()
{
unsigned char i,t;
clk5=0;
pl5=0;
pl5=1;
for(i=0;i<8;i++)
{
t<<=1;
t=t|(bit)Do5;
clk5=1;
clk5=0;
}
P0=t;
if(ab>5)
{
ab=0;
switch(t)
{
case 0x7f:cc=cc+10;break;
case 0xbf:cc=cc-10;break;
case 0xdf:cc=cc+1;break;
case 0xef:cc=cc-1;break;
case 0xf7:bb=bb+10;break;
case 0xfb:bb=bb-10;break;
case 0xfd:bb=bb+1;break;
case 0xfe:bb=bb-1;break;
break;
}
if(cc>24)
cc=0;
if(bb>60)
bb=0;
}
}
//---------------------------------------
main()
{
EA=1;
TMOD=0x11;
ET0=1;
ET1=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR0=1;
TR1=1;
ab=0;
dd=0xfe;
while(1)
{
P0=dd;
a3=bb/10;
a4=bb%10;
a1=cc/10;
a2=cc%10;

if(a==14)
{
aa++;
a=0;
dd=_crol_(dd,1);
if(aa==60)
{
bb++;
aa=0;
if(bb==60)
{
cc++;
bb=0;
if(cc==24)
cc=0;
}
}
}
ReadDat();

display(a1,a2,a3,a4,16); //a1a2现实小时,a3a4现实分钟,16是小时分钟中间的小数点
}

}

void timer0() interrupt 1
{
TH0=0;
TL0=0;
a++;
}

void timer1() interrupt 3
{
TH0=(65536-40000)/256;
TL0=(65536-40000)%256;
ab++;
}
T1定时器用来走时间的,怎么调也调不准,帮忙调试下

进入T1中断后关所有中断 EA= 0,同时里面的指令最好用汇编实现可以计算出指令运行时间,考虑上这一部分时间,同时把T1中断的优先级设定为最高优先级。只要你的晶振质量可靠定时还是非常准确的!
温馨提示:内容为网友见解,仅供参考
第1个回答  2009-05-12
这是51单片机的固有误差,很难消除,建议做准确时间的不要用51内部定时器,而用外部时钟芯片,如DS1302等
第2个回答  2009-05-12
运行一年误差在一秒左右

<<< 糊 智 畅 >>>他在骗谁????????

高档的时钟芯片都没这样的精度

51单片机程序定时器怎么这么不准确啊,求高手指点!
一般建议用TH0=(65536-516)\/256 ;TL0=(65536-516)%256;这种方式,保证不出问题。

51单片机定时器初值用变量设置定时不准确,为什么,求高手。TH0=(65536...
晶振12M TH0=(65536-1000)%256; TL0=(65536-1000)%256; 这种定时方式是准确的但是如果我用变量 x=1000; TH0=(65536-x)%256; TL0=(65536-x)%256; 定时时间就不对了,这是不是正常现象,还是我程序有问题,全部如下 #include <reg52.h> #define ucha... 展开 刚铎的哨子 | 浏览3020 次 |举报 我有更...

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

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

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

51单片机的定时器问题
1、关闭定时器是TR0=0;执行TR0=0;之后,定时器就停止计数,也就是TH0和TL0会保持当前值不会变,ET0=0是关闭定时器的中断,执行ET0=0后,即使定时器还在计数,计数发生溢出的时候不会进入中断。2、在我们使用定时器模式1进行定时,TH0和TL0有三种情况会发生变化:a、直接对TH0和TL0进行写入数值...

51单片机定时器怎么设置时间
编个小程序,把你的时间,输入到单片机。

为什么51单片机定时器计数值取出来之后会比初值还小
有两种可能会造成这种情况:1、定时计数器启动后会从初值开始每个机器周期+1,也就是从49806开始每个机器周期+1,等记到65535(0xFFFF)后下一个周期就会清零,即从0000H开始计数。所以工作方式1在定时中断响应函数中一开始都要重装初值,否则就从0开始了。你说的情况可能定时中断函数中没有重装初值或者...

51 单片机 程序出错 不执行定时器中断1 同时delay函数也有错 求高手...
2.中断程序里,进入中断程序以后如果不是特殊需要,先关断自身的中断控制位,退出中断的时候再打开 3.在单片机里写程序的时候能省资源就省,52单片机是8位的,如果变量范围不超过255就不要用int变量,而且如果不涉及到负数就用unsigned定义 4.在中断程序中如果不是必要,不要定义变量,使用全局变量完成和...

51单片机定时问题,为什么程序那儿要加一个while(1);
main函数中while(1)之前的代码是赋初值操作,是为中断调用使用的。之所以有while(1)是为了使得程序一直在运行,所以才有中断操作的不断执行,否则程序只运行一次就终止啦。

相似回答