基于51单片机的数字时钟设计

目录

一、总体概述

1、计时控制方案

2、主控制器模块

3、显示电路模块

4、调试按键模块

5、电源模块

6、闹钟声光报警模块

二、系统总体结构

1.电路图

三、系统的硬件设计与实现

1、电源电路

2、显示电路

3、单片机基本电路

4、按键电路

四、功能测试及结果分析

五、程序附录


一、总体概述

摘 要

本设计采用89S52系列单片机作为时钟的控制核心,电路使用了八个数码管作为时钟显示,用计数器中断程序作为了一秒钟的精确计数,并用按钮实现了调闹钟时间和时钟时间的校对功能。

关键词:单片机、控制、显示、调时。

Abstract

This design's adopting a single slice of the 89 S52 serieses machine is the control core of the clock, the electric circuit used eight piece code tubes as the clock manifestations,

The precision that used to count the machine interruption procedure conduct and actions for a second count, counteracting a button to carry out to adjust check of the alarm clock time and the clock time function.

1、计时控制方案

AT89S52内部含有2个定时器,可以利用一个定时器与程序计数器相结合的方式,在系统晶振的驱动下,产生标准时钟频率。

2、主控制器模块

主控制器的选择对电路功能的实现尤为重要

方案一:单片机和数字芯片结合使用,这样的好处是能减少单片机的工作量,使电路不单纯的只依赖于单片机工作,但是如果使用数字芯片,就有点违背题目初忠,单片机的功能也不能直观的显现出来。而且相对来说成本要高。电路也不够简略。

方案二:单独使用单片机控制,它的好处是外围电路比较简单直观,所有的控制都只需用软件程序来实现,对于单片机来说,时钟程序远不够它自身的承受量,所以只要程序编的合理,就能比较方便的实现。

基于上述理论分析,拟选择方案二。

3、显示电路模块

采用数码管显示,这种显示方法比较直观,也比较切合现实生活,而且对于电路的设计来说比较方便,节省了电路板的空间,使用三极管驱动后所需电压也相对较低,稳定性也相对较高,而且编程较简单。

八个数码管显示,用按键实现对时钟和日期的显示,因为在实际生活中我们对日期显示的需求并不在每时每刻,所以大可在需要时再显示。这样就减少了八个数码管的占用空间和成本。

直接与端口连接,使得外围电路直观简单,在编程序时也会显得简单明了。

4、调试按键模块

采用独立式按键电路,每个键单独占有一根I/O接口线,每个I/O口的工作状态互不影响,此类键盘采用端口直接扫描方式。缺点是当按键较多时占用单片机的I/O数目较多,优点是电路设计简单,且编程极其容易。考虑到时钟控制在实际使用时的资源量并不大,使用按钮控制可以大大减少按键的使用量。

5、电源模块

取用单片三端稳压集成7805,电路简单、稳定可靠,且成本低,稳压效果好。

6、闹钟声光报警模块

取用单片机编程音乐输出,数十只不同颜色的发光二极管排列成不同的图形,利用单片机编程控制发光管作不同的闪烁,可观性与娱乐性都大大提高,又能突出单片机在多功能控制的特点。

二、系统总体结构

 

1.电路图

                                      

 

工作原理:利用单片机89S52作为本系统的中控模块。电路设有四个按键,一个为功能选择开关,能够选择调节时间、日期、第一个闹钟、第二个闹钟;第二个为“加”按钮,能够实现数字的累加;第三个为“减”按钮,能够实现数字的递减;第四个为确定选择开关。电路程序取用单片机内部其中一个定时中断系统作为基准秒频,这样能够使CPU达到最大利用。功能调节时显示电路仍然能够达到同步显示。当调节的闹钟时间与时钟显示的时间相等时,声光报警电路动作,取用LM386能够放大单片机输出的音频信号,推动扬声器发出乐耳的音乐;利用80只不同颜色的发光二极管排列成奥运五环,在单片机的驱动下能够以不同方式闪烁发光,使人耳目一新。

三、系统的硬件设计与实现

时钟程序的整体设计方案是用单片机驱动电路控制时钟显示,为显示提供电源,用软件程序控制时种运行和各种调节功能。

1、电源电路

取用单片三端稳压集成7805,电路简单、稳定可靠,且成本低,稳压效果好。

                             

 

2、显示电路

采用八只共阳数码管作为时钟电路的显示。数码管的a~h分别并联在一起,由单片机的P0口控制,每只数码管的共阳极分别接一只PNP三极管驱动,三极管具有电流放大作用。

                

 

3、单片机基本电路

单片机基本电路是使单片机正常工作所需要的最基本的电路,包括有复位电路,时钟电路,电源电路。

4、按键电路

                                               

 

                       

 

四、功能测试及结果分析

    时钟最主要的是精度的调节,对此我们做了多次试验来调节时钟的精度。精度的实现主要是由单片机的计数器控制,我们所用的晶振是12M的,即周期为(1/12000000)s,经过计算,将一秒钟分割成20000*600个晶振周期,所以在计数器的高低位参数设定时,用了(FFFF-600)来计数,但是由于实际运用中,这样的计算还是有挺大的误差,因此,在调试过程中,做了多次的修改。

具体测试如下:

测试次数

测试时间

误差

备注

第一次

一小时

快三秒

修改

第二次

一小时

慢两秒

修改

第三次

两小时

快两秒

修改

第四次

三小时

快两秒

修改

第五次

三小时

快一秒半

修改

第六次

三小时

慢一秒

修改

第七次

三小时

快不到半秒

修改

五、程序附录

#include<reg52.h>
sbit a0=P1^0;
sbit a1=P1^1;
sbit a2=P1^2;
sbit a3=P1^3;
sbit a4=P3^6;
sbit a5=P3^1;
static char JP[10]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb};
static char Lie[4]={0xef,0xdf,0xbf,0x7f};
char LEDXS[8];
static char LEDWEI[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
static char LED[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char hour,minute,second;
unsigned int C100us;                  //100us计数单元
unsigned int M,H,key,J=1,K=1,KK=1,MO,DA,YE,M1=61,H1=25,M2=61,H2=25;
//
void wait(unsigned int i)           //延时函数
{unsigned int j;
 for(j=0;j<i;j++);
}

anniu()                            //按钮函数
{key++;
 wait(2000);
}

void displayled(void)                   //显示函数
{unsigned char i;
 for(i=0;i<8;i++)
 {P0=LEDXS[i];
  P2=LEDWEI[i];
  wait(100);
 }
}

void date(void)                    //日期函数
{unsigned int s;
  LEDXS[0]=LED[2];
  LEDXS[1]=LED[0];
  LEDXS[2]=LED[0];
  LEDXS[3]=(LED[YE]-0x80);
  LEDXS[4]=LED[MO/10];
  LEDXS[5]=(LED[MO%10]-0x80);
  LEDXS[6]=LED[DA/10];
  LEDXS[7]=LED[DA%10];
  s=10;
  while(s)
  {s--;
   displayled();
  }
}

void LEDTS(void)                        //调时函数
{unsigned int q=0,a,b,c,w,s,x,y;
 if((a1==0)&&(key==1)){q=1;}
 if((q==1)&&(key!=3))
 {M++;
   if(M==60){M=0;H++;}
   if(H==24){H=0;}
 }
 if((a2==0)&&(key==1)){x=1;}
 if((x==1)&&(key!=3))
 {M--;
   if(M==0){M=59;}
 }
 if((a1==0)&&(key==2)){w=1;}
 if((w==1)&&(key!=3))
 {H++;
  if(H==24){H=0;}
 }
  if((a2==0)&&(key==2)){y=1;}
  if((y==1)&&(key!=3))
 {H--;
  if(H==0){H=23;}
  if(a4==0){key=1;}
 }
  if(a1==1){q=0;w=0;}
  if(a2==1){x=0;y=0;}
  LEDXS[0]=LED[H/10];
  LEDXS[1]=LED[H%10];
  LEDXS[2]=0xbf;
  LEDXS[3]=LED[M/10];
  LEDXS[4]=LED[M%10];
  LEDXS[5]=0xbf;
  LEDXS[6]=LED[0];
  LEDXS[7]=LED[0];
  if(key==5){a=1;}
  while(a)
  {date();
   if(a1==0){DA++;if(DA==32){DA=0;}}
   if(a2==0){DA--;if(DA==0){DA=31;}}
   if(key!=5){a=0;}
   if(a0==0){anniu();}
  }
  if(key==6){b=1;}
  while(b)
  {date();
   if(a1==0){MO++;if(MO==13){MO=0;}}
   if(a2==0){MO--;if(MO==0){MO=12;}}
   if(key!=6){b=0;}
   if(a0==0){anniu();}}
  if(key==7){c=1;}
  while(c)
  {date();
   if(a1==0){YE++;if(YE==10){YE=0;}}
   if(a2==0){YE--;if(YE==0){YE=9;}}
   if(key!=7){c=0;}
   if(a0==0){anniu();}}
    s=10;
  while(s)
  {s--;
   displayled();
  }
  K=1;
  J=1;
}

void T0Int(void) interrupt 1 using 0   //T0中断服务函数
{C100us--;
 if(C100us==0)               //100us计数器为0,重置计数器
 {C100us=20000;
  wait(140);
  second++;
  if(second==60){second=0;minute++;}
    if(minute==60){minute=0;hour++;}
      if(hour==24){hour=0;DA++;}
        if(DA==30){MO++;DA=0;}
          if(MO==12){YE++;MO=0;}}}
//
void main(void)         //主函数
{unsigned int p,q,w;
 TMOD=0X02;         //设置T0工作方式与初值
 TH0=0xd2;
 TL0=0x00;
 IE=0X82;           //开中断
 hour=0;
 minute=0;
 second=0;
 w=0;
YE=6; 
MO=5;
 DA=7;
 C100us=20000;
 TR0=1;             //启动定时器
 P3=0xff;            
 while(1)
 {LEDXS[0]=LED[hour/10];
  LEDXS[1]=LED[hour%10];
  LEDXS[2]=0xbf;
  LEDXS[3]=LED[minute/10];
  LEDXS[4]=LED[minute%10];
  LEDXS[5]=0xbf;
  LEDXS[6]=LED[second/10];
  LEDXS[7]=LED[second%10];
  displayled();
  if(a0==0){p=1;}
  while(p)
  {LEDTS();                                 //调入调时函数
   if(a0==0){anniu();}
   if(key==3)
   {if(a1==0){minute=M;hour=H;second=0;K=0;KK=0;}  //调节时钟时间
            {if(a3==0){M2=M;H2=H;J=0;}
            if(J==1)
            {if(a3==1){M1=M;H1=H;}}}             //调节闹钟时间
             if(minute==M){M1=0;H1=0;M2=0;H2=0;}
             if(a2==0){p=0;key=0;goto hat;}
   }
hat: if(key==4){q=1;}                     //显示年月日
  while(q)
  {date();
   if(a0==0){anniu();}
   if(key>4){q=0;}
  }
   if(key>7){p=0;}
  }
  w++;
  if(w==100){key=0;w=0;}
  if(K==1)
       {if((minute==M1)&&(hour==H1))
          {a5=0;a4=1;}}                     //达到闹铃时间响铃
  if(KK==1){if((minute==M2)&&(hour==H2))
            {a5=0;a4=1;}}
  if(a1==0){a5=1;a4=0;if(minute==M1){K=0;}if(minute==M2){KK=0;}}
   if((minute>=(M1+1))&&(minute!=M2))
    {a5=1;a4=0;K=1;if(a5==1){M=minute;H=hour;}}  //过一分钟后停
   if((minute>=(M2+1))&&(minute!=M1))
   {a5=1;a4=0;KK=1;if(a5==1){M=minute;H=hour;}}
 if(a3==0)                                        //显示闹钟时间
    {anniu();if(key==1)
                     {
                      LEDXS[0]=LED[H1/10];
                      LEDXS[1]=LED[H1%10];
                      LEDXS[2]=0xbf;
                      LEDXS[3]=LED[M1/10];
                      LEDXS[4]=LED[M1%10];
                      LEDXS[5]=0xbf;
                      LEDXS[6]=LED[0];
                      LEDXS[7]=LED[0];
                      while(1)
                      {if(a3==1){key=2;goto aa;}
                       displayled();}}
                    aa: if(key==2)
                     {
                      LEDXS[0]=LED[H2/10];
                      LEDXS[1]=LED[H2%10];
                      LEDXS[2]=0xbf;
                      LEDXS[3]=LED[M2/10];
                      LEDXS[4]=LED[M2%10];
                      LEDXS[5]=0xbf;
                      LEDXS[6]=LED[0];
                      LEDXS[7]=LED[0];
                      while(1)
                      {if(a3==0){key=3;goto aa;}
                       displayled();}key=0;}
   }
 }
}

  • 29
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下饭的王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值