打印

数字钟进阶——多功能数字钟

[复制链接]
2254|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
面对你|  楼主 | 2008-11-5 12:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
上一个数字钟程序有点问题,继续DIY如下:
源代码如下:
//4个数码管依次显示时分,秒用LED灯,4个按键,按SW1,显示日历或时间 ,SW2,相应显示高位加一,SW3,相应显示低位减一
#include<reg51.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
uchar  *dis_ptr;
uchar data dis_buf[4]={0,0,0,0};//显示缓冲区
uchar data time_buf[3]={0x00,0x00,0x00};//时钟显示数据
uchar data date_buf[2]={0x0b,0x04};//日历显示数据
uchar code seg_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
    0xf8,0x80,0x90,0xff};//7段共阴极,依次为0-9
uchar code digit_tab[4]={1,2,4,8};//动态显示缓冲区
uint m=0;
uint n=0;
uint p=0;
uint key_flag=0;
sbit p10=P1^0;//接LED灯,低电平有效
sbit p24=P2^4;//SW1
sbit p25=P2^5;//SW2
sbit p26=P2^6;//SW3
void init_sys();
void disply_one(void);
void dis_buf_flash(void);
bit key_test(void);
void key(void);
void key_delay();
void main()
{init_sys();
for(;;);}
void init_sys(void)//T0工作于方式2,定时250um,
{
dis_ptr=dis_buf+3;
TH0=6;
TL0=6;
TMOD=2;
IE=0x82;
IP=2;
TR0=1;


}

void disply_one(void)//动态显示1位
{uchar i;
P0=seg_tab[*dis_ptr];
i=dis_ptr-dis_buf;
P2=~digit_tab;
if (dis_ptr>dis_buf)
    dis_ptr--;
else dis_ptr=dis_buf+3;
}


void dis_buf_flash(void)//显示数据送缓冲区
{if(p%2==1)//刷新日历
    {
dis_buf[0]=date_buf[0]/10;
dis_buf[1]=date_buf[0]%10;
dis_buf[2]=date_buf[1]/10;
dis_buf[3]=date_buf[1]%10;
   }
else//刷新时间
{dis_buf[0]=time_buf[0]/10;
dis_buf[1]=time_buf[0]%10;
dis_buf[2]=time_buf[1]/10;
dis_buf[3]=time_buf[1]%10;}
}

void time0(void) interrupt 1 
{    dis_buf_flash();
  disply_one();
            
                  TF0=0;
                   m++;
                   n++;
                  
                if(key_test()==0)
                {key_flag=0;}
                    
                   if ((n>=40)&&(key_flag==0))//10ms扫描键盘
                   {n=0;
                   key_test();//扫描键盘
                   if(key_test()==1){
                      key_delay(); 
                      if(key_test()==1)
                           {key();}
                      
                                     }
                   }
                   if(m>=2000){p10=0;}
                  if (m>=4000)//1秒处理
                 {    m=0;
                      p10=1;
                        time_buf[2]+=1;
                        if(time_buf[2]>=60)//60秒处理
                     {time_buf[2]=0;
                         time_buf[1]+=1;}
                       if (time_buf[1]>=60)//60分处理
                       {time_buf[1]=0;
                        time_buf[0]+=1;}
                      if (time_buf[0]>=24)//24小时处理
                      {
                        time_buf[0]=0;
                       time_buf[1]=0;
                       time_buf[2]=0;
                       date_buf[1]+=1;
                      }
                      if(date_buf[1]>=30)//30天处理
                         {date_buf[1]=1;
                          date_buf[0]+=1;}
                    if(date_buf[0]>=13)//12个月处理
                           {date_buf[0]=1;
                            date_buf[1]=1;}
                }
  
                           
 }
bit key_test(void)//测试键盘有无键按下
{
if ((p24==0)||(p25==0)||(p26==0))
return ((bit)1);
else return ((bit)0);
}


void key(void)//按键处理
{key_flag=1;//置标志,停止键盘扫描!
if(p24==0)
    {++p; }

else if(p25==0){if(p%2==1){date_buf[0]+=1;}//高位区域加一
                else time_buf[0]+=1;
               }
               
else {if(p%2==1){date_buf[1]+=1;}//低位区域加一
                else time_buf[1]+=1;
               }



}
                   

void key_delay()//去抖动
{uchar i,s;
for(i=10000,s=5;s>=1;i--)
    {s=i;}
}
程序能正常执行,显示
但时间误差太大!
达到60:100
分析可能有什么程序断在中断中被延时!
调试后发现问题出在中断中的
 if(key_test()==0)
                        {key_delay();
                        if(key_test()==0)
                        {key_flag=0;}
                        }
因为我设置了标志位用来标志有键按下时停止扫描键盘!无键按下时扫描键盘,
这就导致没键按下时,每次都要延迟,一个中断延时一次,1秒下来就误差很多了
解决办法:把上述程序段中的延时程序去了!再经调试,能准确显示了!

请大家多多指教!

相关帖子

沙发
mxh0506| | 2008-11-5 12:18 | 只看该作者

用一片RTC不就都搞定了?

比较高档的RTC精度用普通单片机+晶振是做不到的
当然,如果前提就是不用RTC除外

使用特权

评论回复
板凳
面对你|  楼主 | 2008-11-12 09:19 | 只看该作者

回复2楼

我想用一个任意的普通单片机也能实现这些功能
如果用专业的RTC,那就不要这么麻烦了!!
呵呵!!

使用特权

评论回复
地板
killer007| | 2008-11-23 20:36 | 只看该作者

这和公交车上的数字钟差不多

我也有过这个想法。
精度问题要解决,还要做点时间误差补偿。
另外,电源要是能用干电池那是最好的,外观作好了在家里用就很不错。功耗也很重要,可以考虑在夜间进入休眠模式,但按了开关后可唤醒。

使用特权

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

本版积分规则

4

主题

7

帖子

0

粉丝