51单片机定时器不准,请各位高手进来看看。。。。

2019-07-16 07:04发布

本帖最后由 baidu202 于 2011-5-12 23:13 编辑

#include<reg51.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit key=P1^7;
bit flag=0;
uint t;
uchar sec=0,min=0,hour=0,x=0,u=0xfe,tt=0;//t计时一秒 tt计时2毫秒
uchar code Num[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0xff;
};
uchar Num_Buf[]=
{0,0,10,0,0,10,0,0};


void display()
{
   if(tt==1)
  {
    tt=0;
    P2=u;
    u=_crol_(u,1);
    P0=Num[Num_Buf[x]];
    x++;
    if(x==8)x=0;
  }
}

void timer0()interrupt 1
{
ET0=0;
TH0=-(2010/256);
TL0=-(2010%256);
t++;
tt++;
if(t==500)
{
t=0;
sec++;
}
ET0=1;
}


void main()
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=-(2000/256);
TL0=-(2000%256);
P2=0xff;
P0=0xff;
while(1)
{
   display();
    if(sec==60)
    {
          sec=0;
          min++;
          if(min==60)
          {
               min=0;
               hour++;
               if(hour==24)
               {
               hour=0;
                }
           }
    }
  Num_Buf[6]=sec/10;
  Num_Buf[7]=sec%10;
  Num_Buf[3]=min/10;
  Num_Buf[4]=min%10;
  Num_Buf[0]=hour/10;
  Num_Buf[1]=hour%10;
}
}




我是一个新手,才学51单片机
这是我编的一个单纯的计时器,没有其他功能, 只有从00-00-00开始。后来发现,定时时间不准,定时器初值越小的时候越不准,误差很大。定时器初值补偿也试过,无法修正。请各位高手帮我看看哪里有问题。晶振是12兆的。
无论怎样,先说声谢谢大家。。。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
魔杰彬
1楼-- · 2019-07-16 07:46
 精彩回答 2  元偷偷看……
chenhengjin
2楼-- · 2019-07-16 12:51
用单片机的晶体振荡器,程序定时会有误差。
爱我别走
3楼-- · 2019-07-16 16:42
试试这样修改下:
/*****************************************************************************************
                                                           修改版
*****************************************************************************************/
#include<reg51.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit key=P1^7;
bit flag=0;
uint t;
uchar sec=0,min=0,hour=0,x=0,u=0xfe,tt=0;//t计时一秒 tt计时2毫秒
uchar code Num[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0xff;
};
uchar Num_Buf[]=
{0,0,10,0,0,10,0,0};

void display()
{
   if(tt==1)
  {
    tt=0;
    P2=u;
    u=_crol_(u,1);
    P0=Num[Num_Buf[x]];
    x++;
    if(x==8)x=0;
  }
}

void timer0()interrupt 1
{
ET0=0;
//TH0=-(2010/256);
//TL0=-(2010%256);
//定时周期尽量设置长一些,因为进入中断以及重装初值都需要消耗时间。这个时间和你定时周期越接近,定时越不精确。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t++;
tt++;
//if(t==500)
if(t==20)
{
t=0;
sec++;
  if(sec==60)
    {
          sec=0;
          min++;
          if(min==60)
          {
               min=0;
               hour++;
               if(hour==24)
               {
               hour=0;
                }
           }
    }

}
ET0=1;
}


void main()
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
//TH0=-(2000/256);
//TL0=-(2000%256);
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
P2=0xff;
P0=0xff;
while(1)
{
   display();
//这里潜在的问题,假如此时sec=60,主函数将要执行 if(sec==60)的时候,突然发生定时器中断,
//在中断里面进行了src++,中断退出后,返回主函数继续执行 if(sec==60),而此时sec已经变成了61,
//这里的判断是不是就失效呢?
//在程序中要避免在中断和主函数同时使用一个资源,(资源:变量,函数,硬件等待)
//否则就会因为资源争夺而发生冲突。
/* if(sec==60)
    {
          sec=0;
          min++;
          if(min==60)
          {
               min=0;
               hour++;
               if(hour==24)
               {
               hour=0;
                }
           }
    }*/
  Num_Buf[6]=sec/10;
  Num_Buf[7]=sec%10;
  Num_Buf[3]=min/10;
  Num_Buf[4]=min%10;
  Num_Buf[0]=hour/10;
  Num_Buf[1]=hour%10;
}
}
07071624
4楼-- · 2019-07-16 18:40
楼上分析得很到位
767763503
5楼-- · 2019-07-16 20:34
晶体震荡器会有误差     这是不可避免的    如果要即时准的用ds12c887吧1302也行

一周热门 更多>