基于单片机AT89C2051的电子钟设计方案

最新更新时间:2014-04-30来源: 21IC关键字:单片机  AT89C2051 手机看文章 扫描二维码
随时随地手机看文章

 电路见图1.

 

  一片20引脚的单片机AT89C2051为电子钟主体,其显示数据从P1口分时输出,P3.0~3.3则输出对应的位选通信号。由于LED数码管点亮时耗电较大,故使用了四只PNP型晶体管VT1~VT4进行放大。本来笔者还有一种更简的设计方案(见图2),可省去VT1~VT4及R1~R4八个元件,但这种设计由于单片机输出口的灌入电流有限(约20mA),数码管亮度较暗而不向读者介绍,除非你采用了高亮度的发光数码管。

  P3.4、P3.5、3.7外接了三个轻触式按键,这里我们分别命名为:模式设定键set(P3.4)、时调整键hour(P3.5)、分调整键min(P3.7)。C1、R13组成上电复位电路。VT5及蜂鸣器Bz为闹时讯响电路。三端稳压器7805输出的5V电压供整个系统工作。此电子钟可与任何9~20V/100mA的交直流电源适配器配合工作,适应性强。

  电子钟功能

  1.走时:通过模式设定键set选择为走时,U1、U2显示小时,U3、U4显示分。U2的小数点为秒点,每秒闪烁一次。

  2.走时调整:通过模式设定键set选择为走时调整,按下hour键对U1、U2的走时“时”显示进行调整(每0.2秒递加1)。按下min键对U3、U4的走时“分”显示进行调整(每0.2秒递加1)。

  3.闹时调整:通过模式设定键set选择为闹时调整,按下hour键对U1、U2的闹时“时”显示进行调整(每0.2秒递加1)。按下min键对U3、U4的闹时“分”显示进行调整(每0.2秒递加1)。

  4.闹时启/停设定:通过模式设定键set选择为闹时启/停设定,按下min键U3的小数点点亮,闹时功能启动;按下hour键U3的小数点熄灭,闹时功能关停。

  由于电路设计得极其简单,因此丰富的功能只能由软件完成,这里软件设计成为了关键。下面介绍软件设计要点。

  图3为主程序状态流程。

  运行时建立的主要状态标志如下:

  flag-掉电标志。掉电后,flag内为一随机数;重新设定时间后flag内写入标志数55H.

  set-工作模式设定标志。

  hour-走时“时”单元。

  min-走时“分”单元。

  sec-走时“秒”单元。

  dEDA-走时5mS计数单元

  t_hour-闹时“时”单元。

  t_min-闹时“分”单元。

  d_05s-0.5秒位标志。每秒钟的前0.5秒置1,后0.5秒置0,以使秒点闪烁。

  o_f-闹时启/停位标志。闹时启动置1,闹时关停置0.

  另外将定时器T0设定为5mS的定时中断。这里晶振频率为12MHz,因此5mS的初值为-5000,但实际上程序还要作其它运算,使得时间偏长,经调整为-4800后试验刚好。计时单元deda每次中断均加1.走时函数判断deda>=200时即令秒单元sec加1.同理秒单元sec满60后令分单元min加1.分单元min满60后令时单元hour加1.时单元hour满24后清0.

  上电后,首先进行初始化,对各状态标志、输入输出口及定时器T0进行初始化工作,以适应后面程序的要求。

  随后程序判断有无set键按下,如按下,则set键值从0起加1.set键值只能从0加到3,然后又回到0.

  接下来,根据键值进行散转。若set=0,运行走时程序;若set=1,进入调整闹时时间程序;若set=2,进入调整走时时间程序;若set=3,显示已调好的闹时时间,同时进入启/停闹时程序。

  散转完后,进行判断掉电标志flag是否等于55H.若不等,说明刚开机上电或运行过程中掉过电,这时四个数码管以1Hz的频率闪烁四个8字,提示时间不准;若相等,说明未掉电,RAM区内容未变化,时间准确。

  再下来程序又转回到初始化之后进行循环运行。

  由于使用了四只数码管密集排列,因此只能采用双面印刷板设计,图4、5分别为正面(元件面)、反面的印板图。尺寸3000milx4000mil(7.62cmx10.16cm)。图6为计算机输出的三维仿真印制板。

  元件选用

  为了走时准确,晶振X最好选用温漂小的。四个数码管U1~U4可选用发绿光的,这样光泽较柔和。蜂鸣器Bz要购买绕线型的电动式蜂鸣器(市场上有一种加电压即工作的蜂鸣器这里不适用),因驱动信号为脉冲信号。其它元件一般无特殊要求。

  使用方法

  上电后,四个LED数码管闪烁四个8字。

  按一下set键,闪烁现象消失(此时set=1),U1的小数点亮,说明此刻可以调整闹时时间。按下hour键,U1、U2作加法;按下min键,U3、U4作加法。这些调整好的数据被同时送入RAM区的闹时记忆“时”单元t_hour和闹时记忆“分”单元t_min.

  再按一下set键,set=2,U2的小数点亮,此刻可以调整走时时间。按下hour键,U1、U2作加法;按下min键,U3、U4作加法。这些调整好的数据也被同步送入RAM区的“时”记忆单元hour和“分”记忆单元min.

  再按一下set键,set=3,显示刚才调整的闹时时间,此刻可以选择启动/关停闹时。按下min键,o_f位标志置1,U3的小数点亮,闹时启动;按下hour键,o_f位标志置0,U3的小数点灭,闹时关闭。

  若再按一下set键,set=0,电路进入走时状态,U1、U2显示小时,U3、U4显示分。U2的小数点作秒点闪烁。

  在闹时启动的情况下,走时到达设定闹时,则蜂鸣器Bz鸣响一分钟进行提醒。

  附:用C51编写的源程序清单(已由实验板运行通过)

  #include                        /*包含器件配置文件*/

  #define uchar unsigned char

  #define uint unsigned int

  char DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,

  0x92,0x82,0xF8,0x80,0x90,};/*0~9的数码管段码*/

  uchar hour=0,min=0,sec=0;                /*时、分、秒单元清零*/

  uchar deda=0;                                  /*5mS计数单元清零*/

  uchar t_hour=0,t_min=0;                   /*闹时时、分单元清零*/

  bit d_05s=0;                             /*0.5秒标志*/

  bit o_f=0;                                         /*闹时启/停标志*/

  uchar set=0;                                      /*模式设定标志*/

  uchar m=0;

  uchar flag=0;                                     /*RAM掉电标志*/

  void delay(uint k);                              /*延时子函数*/

  void conv();                                       /*走时单元转换*/

  void p_out();                                      /*判别闹时到否子函数*/

  void dirve();                                       /*走时时间输出驱动子函数*/

  void t_dirve();                                    /*闹时时间输出驱动子函数*/

  /*闹时启/停子函数*/

  void time1_of()

  {uchar m;

  if(P3_7==0)delay(1);

  if(P3_7==0)o_f=1;

  for(m=0;m<30;m++)

  {

  t_dirve();

  P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

  if(P3_1==0){if(o_f==1)P1_7=0;}else P1_7=1;

  delay(1);

  }

  if(P3_5==0)delay(1);

  if(P3_5==0)    o_f=0;

  for(m=0;m<30;m++)

  {

  t_dirve();

  P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

  if(P3_1==0){if(o_f==1)P1_7=0;else P1_7=1;}

  delay(1);

  }

  }

  /*走时函数*/

  void time()

  {

  conv();                                              /*走时单元转换*/

  dirve();                                              /*走时时间输出驱动子函数*/

  p_out();                                             /*判别闹时到否子函数*/

  }

  /*定时器T0  5mS初始化*/

  void init_timer()

  {

  TMOD=0x01;

  TH0=-(4800/256);

  TL0=-(4800%256);

  IE=0x82;

  TR0=1;

  }

  /*扫描按键子函数*/

  void sCAN_key()

  {

  delay(1);

  if(P3_4==0)set++;

  if(set>=4)set=0;

  if(set==1)flag=0x55;

  F0:if(P3_4==0)goto F0;                      /*按键未释放,在此等候*/

  }

  /*延时子函数*/

  void delay(uint k)

  {

  uint i,j;

  for(i=0;i

  for(j=0;j<121;j++)

  {;}}

  }

  /*5mS定时中断服务子函数*/

  void zd(void) interrupt 1

  {

  TH0=-(4800/256);

  TL0=-(4800%256);

  deda++;

  }

  /*调整走时时间*/

  void time_adj()

  {uchar m;

  if(P3_5==0)delay(1);

  if(P3_5==0)hour++;

  if(hour==24)hour=0;

  for(m=0;m<30;m++)

  {

  dirve();

  if(P3_2==0)P1_7=0;

  else P1_7=1;

  delay(1);

  }

  if(P3_7==0)delay(1);

  if(P3_7==0)min++;

  if(min==60)min=0;

  for(m=0;m<30;m++)

  dirve();

  if(P3_2==0)P1_7=0;

  else P1_7=1;

  delay(1);

  }

  }

  /*调整闹时时间*/

  void time1_adj()

  {uchar m;

  if(P3_5==0)delay(1);

  if(P3_5==0)t_hour++;

  if(t_hour==24)t_hour=0;

  for(m=0;m<30;m++)

  {

  t_dirve();

  }

  if(P3_7==0)delay(1);

  if(P3_7==0)t_min++;

  if(t_min==60)t_min=0;

  for(m=0;m<30;m++)

  {

  t_dirve();

  }

  }

  /*时、分、秒单元及走时单元转换*/

  void conv()

  {

  if(deda<=100)d_05s=0;

  else d_05s=1;

  if(deda>=200){sec++;deda=0;}

  if(sec==60){min++;sec=0;}

  if(min==60){hour++;min=0;}

  if(hour==24){hour=0;}

  }

  /*走时时间输出驱动子函数*/

  void dirve()

  {

  P1=DATA_7SEG[hour/10];P3=0xf7;delay(1);

  P1=DATA_7SEG[hour%10];P3=0xfb;delay(1);

  if(d_05s==1){if(P3_2==0)P1_7=0;else P1_7=1;}

  delay(1);

  P1=DATA_7SEG[min/10];P3=0xfd;delay(1);

  if(o_f==1){if(P3_1==0)P1_7=0;else P1_7=1;delay(1);}

  P1=DATA_7SEG[min%10];P3=0xfe;delay(1);

  }

  /*闹时时间输出驱动子函数*/

  void t_dirve()

  {

  P1=DATA_7SEG[t_hour/10];P3=0xf7;delay(1);

  if(P3_3==0)P1_7=0;else P1_7=1;

  delay(1);

  P1=DATA_7SEG[t_hour%10];P3=0xfb;delay(1);

  P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

  P1=DATA_7SEG[t_min%10];P3=0xfe;delay(1);

  }

  /*判别闹时到否子函数*/

  void p_out()

  {

  if(o_f==1){

  if(t_hour==hour){if(t_min==min)

  if(P3_0==0){P1_7=0;delay(1);}

  else P1_7=1;

  }

  }

  }

  /*主函数*/

  void main()

  {

  init_timer();                       /*定时器T0初始化*/

  while(1)                                     /*无限循环*/

  {

  if(P3_4==0)scan_key();               /*有按键,调用

  键扫描子函数*/

  switch(set)                                        /*根据set键值散转*/

  {

  case 0:time();break;                                   /*走时时间程序*/

  case 1:time1_adj();break;                     /*闹时时间调整*/

  case 2:time_adj();break;                      /*走时时间调整*/

  case 3:time1_of();break;                      /*启/停闹时*/

  default:break;                                     /*其它退出*/

  }

  if(flag!=0x55)                             /*判断掉电标志*/

  {for(m=0;m<100;m++)               /*点亮四个8字400mS*/

  {

  P1=0x80;P3=0xf7;delay(1);

  P1=0x80;P3=0xfb;delay(1);

  P1=0x80;P3=0xfd;delay(1);

  P1=0x80;P3=0xfe;delay(1);

  }

  P1=0xff;P3=0xff;delay(400); /*熄灭四个8字400mS*/

关键字:单片机  AT89C2051 编辑:探路者 引用地址:基于单片机AT89C2051的电子钟设计方案

上一篇:一款600W正弦波逆变器设计制作的全流程(三)
下一篇:基于AN8026控制芯片的变频器电源设计方案

推荐阅读最新更新时间:2023-10-12 22:39

20课:单片机定时/计数器实验
前面我们做了定时器的实验,现在来看一看计数实验,在工作中计数常常会有两种要求:第一、将计数的值显示出来,第二、计数值到一定程度即中断报警。第一种如各种计数器、里程表,第二种如前面例中讲到的生产线上的计数。先看第一种吧。我们的硬件中是这样连线的:324组成的振荡器连到定时/计数器1的外部管脚T1上面,我们就利用这个来做一个计数实验,要将计数的值显示出来,当然最好用数码管了,可我们还没讲到这一部份,为了避免把问题复杂化,我们用P1口的8个LED来显示计到的数据。 程序如下: ORG 0000H ,http://www.51hei.com AJMP START ORG 30H START: MOV SP,#5FH MOV TMOD,
[单片机]
单片机制作模拟电子琴
  在这个小制作里除了给大家介绍了“mini”模拟电子琴所需的硬件外,还主要介绍了用单片机为控制核心如何控制蜂鸣器演奏音节的基本方法。   实现这个电路的硬件是非常简单的,硬件主要运用了STC89C52RC单片机为核心的主控芯片,外设有8个按键,和一个复位按键以及蜂鸣器作为喇叭在这里我就不多说了。主要是由STC89C52单片机的的P1口8个按键控制Do,Re,Mi,Fa,So,La,Xi,Do的各个音符,然后由P0口的一位数码管显示出来,同时位于P3.3口的蜂鸣器发出声音。   现在我主要简单介绍单片机如何控制蜂鸣器演奏音阶的方法,我们都知道单片机具有强大的控制功能和灵活的编程实现特性,我们可以利用单片机产生不同频率来获
[单片机]
<font color='red'>单片机</font>制作模拟电子琴
单片机应用系统抗干扰技术
近年来, 单片机 在工业自动化、生产过程控制、智能仪器仪表等领域的应用越来越广泛,大大提高了产品的质量,有效地提高了生产效率。但是,测控系统的工作环境往往复杂、比较恶劣,尤其是系统周围的电磁环境,这对系统的可靠性与安全性构成了极大的威胁。单片机测控系统必须长期稳定、可靠运行,否则将导致控制误差加大,严重时会使系统失灵,甚至造成巨大损失。下面着重分析 干扰 对单片机应用系统的影响,并结合亲身经验,从软、硬两个方面给出具体的解决方法。 2. 干扰对单片机应用系统的影响 影响应用系统可靠、安全运行的主要因素来自系统内部和外部的各种电磁干扰,以及系统结构设计、元器件安装、加工工艺和外部电磁环境条件等。这些因素对单片机系统造成的
[应用]
嵌入式实时操作系统uC/OS-II及其应用
早在上世纪六十年代,就已经有人开始研究和开发嵌入式操作系统。但直到最近,它才在国内被越来越多的提及。其在通信、电子、自动化等需要实时处理的领域所日益显现的重要性吸引了人们越来越多的注意力。针对国内大部分用户使用的51系列的8位处理器,我们可以选择mC/OS-II 。  mC/OS- II是由Labrosse先生编写的一个开放式的内核,它最主要的特点就是源码公开的自由软件。这一点对于用户来说可谓利弊各半;好处在于,一方面它是免费的;另一方面用户可以根据自己的需要对它进行修改。坏处在于,它缺乏必要的支持。它没有功能强大的软件包,用户通常得自己编写驱动程序,特别当用户使用的是不太常用的单片机,还必须自己编写移植程序。  mC/OS-I
[嵌入式]
单片机实现干簧管计数器的实验
 在本实验中,要设计一个干簧管计数器,并用数码管来显示。在本例中,还要接触单片机一个重要的功能“中断”。   干簧管是干式舌簧管的简称,是一种有触点的无源电子开关元件,具有结构简单,体积小便于控制等优点,其外壳一般是一根密封的玻璃营,管中装有两个铁质的弹性簧片电板,还灌有一种叫金属铑的惰性气体。下图是它的结构示意图。   平时,玻璃管中的两个由特殊材料制成的簧片是分开的。   当有磁性物质靠近玻璃管时,在磁场磁力线的作用下,管内的两个簧片被磁化而互相吸引接触,簧片就会吸合在一起,使结点所接的电路连通。外磁力消失后,两个簧片由于本身的弹性而分开,线路也就断开了。因此,作为一种利用磁场信号来控制的线路开关器件
[电源管理]
<font color='red'>单片机</font>实现干簧管计数器的实验
单片机入门程序六
;*****************************************; ;实验名称: 六位数码管动态显示0-1-..-5实验; ;作者: 龙谊 ; ;版本: VER 1.0 ; ;说明: 采用共阴极数码管 ; ;修改: 无 ; ;编程语言: 汇编语言 ; ;*****************************************;
[单片机]
MSP430单片机命名规则
TI MSP430命名规则
[单片机]
MSP430<font color='red'>单片机</font>命名规则
基于stc89c52单片机和gsm模块的电力变压器防盗系统设计
1 引言 在油田等地域分布辽阔的野外地区,输电线路和电力变压器因远离供电局经常面临被盗的危险,一旦输电线和电力变压器被盗,将会造成很大的经济损失,给电力系统的稳定运行和油田安全生产造成极大的隐患。随着gsm移动通信网络的迅速发展和用户的日益扩大,gsm的信号覆盖范围很广,盲区越来越少,现在gsm机站建设迅速,设计上已经覆盖了整个地区。为此,本文利用gsm通讯网络开发出的输电线路和变压器防盗系统,能有效地对偏远地区的输电线路和电力变压器的运行情况实时监控。 2 系统设计 本文主要描述了利用stc89c52单片机实现的基于gsm模块的电力变压器防盗系统,包括stc89c52单片机的功能特点、gsm短信模块工作原理、传感器工作原理。
[单片机]
基于stc89c52<font color='red'>单片机</font>和gsm模块的电力变压器防盗系统设计
小广播
最新电源管理文章
换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved