打印

请各位大侠帮忙解决电子时钟仿真不精确问题(附C源代码)

[复制链接]
1986|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kinglinlin88|  楼主 | 2011-2-24 09:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kinglinlin88 于 2011-2-24 09:49 编辑

本人是一个小菜鸟,刚接触单片机,想用AT89C51单片机做一个电子时钟。可是代码写完用软件仿真时发现,显示时间与实际时间差了好多,仿真一分钟就差了好几秒。
问题   1:时间的误差是不是由于延时程序及执行程序代码消耗的时间产生的。如何处理.
         2:本程序增加了三个按钮,进行对小时,分钟,秒的调节,可是调节过程中数码管闪烁,请问如何消除数码管的闪烁过程。按键实现是不是正确(代码实现方法)
         3:使用那些集成块可实现精确计时。
         4:更换晶振是否能增加精确度,频率越高是否越好。
         5: 代码那些地方不合理请各位发表一下自己的意见,给我一些建议。






#include<reg51.h>     //包含51单片机寄存器定义的头文件
unsigned char Tab[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  //段码表0~9
//unsigned char port[ ]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE};  //数码管位选1~8
sbit P07=P0^7;       //秒加1
sbit P06=P0^6;       //分加1
sbit P05=P0^5;       //小时加1

unsigned char int_time;  //中断次数计数变量
unsigned char second;  //秒计数变量
unsigned char minute;  //分钟计数变量
unsigned char hour;   //小时计数变量
//********************************************************
//函数功能:延时程序
//********************************************************
void delay(void)
{
unsigned char j;
for(j=0;j<50;j++)
  ;
   
}

void delay10S(void)
{
unsigned int i,k;
for(i=0;i<20000;i++)
;
for(k=0;k<20000;k++)
;
}

//*********************************************************
//函数功能:显示秒的子程序
//入口参数: s
//*********************************************************
void DisplaySecond(unsigned char s)
{
  
P2=0xBF;   //P2.6引脚输出低电平,DS6点亮
P1=Tab[s/10];  //显示十位
delay();
P2=0x7F;   //P2.7引脚输出低电平,DS7点亮
P1=Tab[s%10];
delay();      //显示个位

P2=0xFF;   //关闭所有数码管

}
//*********************************************************
//函数功能:显示分钟的子程序
//入口参数: m
//*********************************************************
void DisplayMinute(unsigned char m)
{

P2=0xF7;   //P2.3引脚输出低电平,DS3点亮
P1=Tab[m/10];
delay();   //显示个位
P2=0xEF;   //P2.4引脚输出低电平,DS4点亮
P1=Tab[m%10];  
delay();

P2=0xDF;      //P2.5引脚输出低电平,DS5点亮
P1=0x40;   //分隔符“-”的段选
delay();

P2=0xFF;   //关闭所有数码管

}
//*********************************************************
//函数功能:显示小时的子程序
//入口参数: h
//*********************************************************
void DisplayHour(unsigned char h)
{
P2=0xFE;   //P2.0引脚输出低电平,DS0点亮
P1=Tab[h/10];  //显示十位
delay();
P2=0xFD;   //P2.1引脚输出低电平,DS1点亮
P1=Tab[h%10];  //显示十位
delay();
P2=0xFB;   //P2.2引脚输出低电平,DS2点亮
P1=0x40;   //分割符“-”的段码
delay();

P2=0xFF;   //关闭所有数码管

}
//*********************************************************
//主函数
//*********************************************************
void main(void)
{
TMOD=0x01;     //使用定时器T0
EA=1;      //开总中断
ET0=1;      //允许T0中断
TH0=(65536-46083)/256;  //定时器高8位赋初值
TL0=(65536-46083)%256;  //定时器低8位赋初值
TR0=1;      //启动定时器T0
int_time=0;     //中断计数变量初始化
second=0;     //秒计数变量初始化
minute=0;     //分钟计数变量初始化
hour=0;      //小时计数变量初始化
while(1)
{
  
  if(P07==1)
  {
  
  TR0=0;
  
  delay10S();
  hour++;
   
  if(second==60)   //若计满60s
  {
  
   second=0;            //如果秒计满60,将秒计数变量清0
  
  }
  
  }
   
  
  if(P06==1)
  {
   TR0=0;
  delay10S();        
  minute++;
      

  if(minute==60)   //若计满60分
  {
  
   minute=0;          //如果分钟计满60,将分钟计数变量清0
     
  }
  
  }

  if(P05==1)
  {
   TR0=0;
  delay10S();
  second++;

  if(hour==24)
  {
   
   hour=0;           //如果小时计满24,将小时计数变量清0   
  }
  
   
  }
  TR0=1;
  DisplaySecond(second);  //调用秒显示子程序
  delay();
  DisplayMinute(minute); //调用分钟显示子程序
  delay();
  DisplayHour(hour);  //调用小时显示子程序
  delay();

}
}
//*********************************************************
//函数功能:定时器T0的中断服务子程序
//*********************************************************
void interserve(void) interrupt 1 using 1
{

int_time++;     //中断次数加1
  if(int_time==20)  //若中断次数计满20次
  {
  
   int_time=0;   //中断计数变量清0
    second++;  //秒计数变量加1
  }

  if(second==60)   //若计满60s
  {
  
   second=0;   //如果秒计满60,将秒计数变量清0
   minute++;   //分钟计数变量加1
  
  }
  if(minute==60)   //若计满60分
  {
  
   minute=0;   //如果分钟计满60,将分钟计数变量清0
   hour++;    //小时计数变量加1
     
  }
  if(hour==24)
  {
  
   hour=0;    //如果小时计满24,讲小时计数变量清0   
  }
  TH0=(65536-46083)/256; //定时器T0高8位重新赋初值
  TL0=(65536-46083)%256; //定时器T0低8位重新赋初值
}

相关帖子

沙发
NE5532| | 2011-2-24 20:30 | 只看该作者
解决的办法就是你搭个实际电路出来看,仿真的不要,否则你永远都是一只菜鸟!

一个糟糕的实物好过一个完美的仿真。

使用特权

评论回复
板凳
chunyang| | 2011-2-24 21:48 | 只看该作者
严重同意楼上的观点。

使用特权

评论回复
地板
kinglinlin88|  楼主 | 2011-2-25 12:11 | 只看该作者
实践出真招!谢二位版主指点!

使用特权

评论回复
5
三叶阳光| | 2011-2-26 16:38 | 只看该作者
我今天第一次看电子钟的源码,居然也能懂个大概。。哈哈

使用特权

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

本版积分规则

7

主题

48

帖子

1

粉丝