课程设计题三:日历和数字钟

发布者:RainbowDreamer最新更新时间:2019-09-29 来源: eefocus关键字:日历  数字钟  STC89C51 手机看文章 扫描二维码
随时随地手机看文章

要求:


1、数字钟:时、分,小时用二十四进制显示,分钟用六十进制显示。


2、显示采用动态数码管显示方式


3、动态时显示六位:时 分 秒 用按键可切换显示年月日


4、具有清零的功能,且能够对小时、分钟进行调整(校时)。


5、具有整点、半点报时功能,整点用声音次数报时,半点特殊声音报时。


一、Protues仿真图:

二、程序源码:

因为注释非常的全,这里就不再进行讲解了。

/*******************************************************************************

================================================================================

【平    台】STC89C51_sumjess平台

【编    写】sumjess

【E-mail  】1371129880@qq.com

【软件版本】V2.0

【最后更新】2019年06月10日

【相关信息参考下列地址】

【网    站】

           https://blog.csdn.net/qq_38351824

           http://www.51hei.com/bbs/mcu-2-1.html

---------------------------------------------------------------------------------

【dev.env.】MDK4.02及以上版本

【Target  】STC89C51

第一次修订:2019/05/09

第二次修订:2019/05/21

第三次修订:2019/06/10

【problem 】

    (1)库内补充的不全面;

    (2)库内解释部分不全面;

    (3)库内还存在一定的bug;

【direction】

      下一步的目标就是把库继续集成!

【explain 】

      为了方便使用,我也自己写了很多的库,和优化了算法和表示方式!

【warning】

      目前程序中暂无错误 !   

---------------------------------------------------------------------------------

没有完美的代码,只有不断的奉献,大家一起努力;

赠人玫瑰手留余香,欢迎大家反馈bug!

================================================================================

********************************************************************************/

#include    //52单片机头文件

#include"intrins.h"    //循环移位函数头文件

#define uint unsigned int  // 宏定义

#define uchar unsigned char

#define NOT_Break  25      //任意赋值避开条件

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0XBF,0xff}; //共阳极数码管编码0-9和“—”

uchar val[8]={2,3,10,5,9,10,5,5};

 

sbit key0 = P0^0;    //清零

sbit key1 = P0^1;    //时间---年月日转换

sbit BEEP = P3^7;    //蜂鸣器

 

uchar wei=0X01,duan=0;

void smg()//数码管扫描送显示函数

{

P1=wei;         // 选择要点亮的数码管是哪一个

P2=table[val[duan]];   // 给改数码管送显示数据

    wei=_crol_(wei,1);     // 移位,为点亮下一个数码管做准备

duan++;  

if(duan>7) duan=0;   

 

void delay(uint z) //1毫秒

{

uint x,y;

    for(x=z;x>0;x--)

      for(y=110;y>0;y--);   

}

 

void time0init()    //  定时器0初始化函数

{

TMOD=0x01; //设置定时器0为工作方式1(M1M0为01)

TH0=(65536-2000)/256; //装初值12M晶振定时2ms数为2000

TL0=(65536-2000)%256;

EA=1; //开总中断

ET0=1; //开定时器0中断

TR0=1; //启动定时器0

}

 

uint num=0,keytime=0,time; //时间更新  1s,20ms扫描一次按键, 控制修改项闪烁

void time0() interrupt 1

{

TH0=(65536-2000)/256; //装初值12M晶振定时2ms数为2000

TL0=(65536-2000)%256;

keytime++; //20ms扫描一次按键

time++; //控制修改项闪烁

num++; //时间更新  1s

smg();

}  

 

 

 uchar key()

{    

  static  uchar kzt=0; //推动循环,每次执行一次case

  uchar sb=NOT_Break; //任意赋值避开条件

  switch(kzt) //按顺序依次执行

  {

//------------case 0:------------//

case 0: //第一步

P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据  

                         //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平

if(P3!=0xff) //如果有按键按下

{

kzt=1; //向下执行第二步

return NOT_Break; //返回一个无关的值,用来跳出此次循环

}

break; //如果没有按键按下,直接跳出

//------------case 1:------------//

case 1: //第二步

P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据  

                         //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平

if(P3!=0xff) //有按键按下

{

switch(P3)

{

case 0xfe: //第一个按键按下

sb=0;

break; //直接跳出

case 0xfd: //第二个按键按下

sb=1;

break; //直接跳出

case 0xfb: //第三个按键按下

sb=2;

break; //直接跳出  

case 0xf7:      //第四个按键按下

sb=3;

break; //直接跳出

}

kzt=2; //如果无按键按下  向下执行第三步

return sb; //返回sb的值

  }

else //如果无按键按下  回到第一步

{

  kzt=0;

  return NOT_Break; //返回一个无关的值,用来跳出此次循环

  }

break;

//------------case 2:------------//

case 2: //第三步

P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据  

                         //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平

if(P3==0xff) //如果没有按键按下

{

kzt=0; //如果无按键按下  回到第一步

return NOT_Break;

}  

break; //如果有按键按下  直接跳出

}

return NOT_Break;

 }

 

void main()

{  

   char shi=23,fen=59,miao=55,qh=0;   //初始化时分秒   状态标志位(0:正常,1:改变秒钟,2:改变分钟,3:改变时钟)

   char flag=0;   //标志位---年月日&&时分秒

   char keycode=NOT_Break;   //键值

   P0=0xff;

   P1=0xff;

   P2=0xff;

   P3=0xff;

   delay(10);   //保证上面三条指令顺利完成

   time0init();   //定时器0初始化函数

   while(1)

{

    if(key0==0)       //清零按键按下

{

  shi=0;fen=0;miao=0;   //时分秒清零

  qh=0;   //开始显示

  }

    if(key1==0)       //年月日&&时分秒按键按下

{

  while(!key1);   //等待放开按键

  if(flag==0) flag=1;   //年月日&&时分秒

  else  flag=0;  

  qh=0;   //开始显示

  }       

    if(keytime>9)   //2ms*10=20ms

{

  keytime=0;   //计数清零

  keycode=key();   //检测是否有按键按下  

}

//////////////////////////////---时间更新---//////////////////////////////

if((num>=500)&&(qh==0)) //时间更新 2ms*500=1s

{

num=0; //计数清零

miao++; //秒数加1

if(miao>59) //如果miao等于60

{

miao=0; //miao赋值为0

fen++; //分钟加1

if(fen>59) //如果fen等于60

{

fen=0; //fen赋值为0

shi++; //小时加1

if(shi>23) shi=0;//如果shi等于24  shi赋值为0

}

}

}

///////////////////////////////////////////////////////////////////////////

 

//////////////////////////////---按键检测---///////////////////////////////

 

///////////////////////////---第一个按键按下---///////////////////////////////

  if(keycode==0) //第一个按键按下 选择

  {

qh++; //状态标志位(0:正常,1:改变秒钟,2:改变分钟,3:改变时钟)

if(qh>3) qh=1;    //如果qh等于4,qh赋值为1  

keycode=NOT_Break; //任意赋值避开条件

}

///////////////////////////---第二个按键按下---///////////////////////////////

  if(keycode==1)   //第二个按键按下   加

       {

if(qh==1)

        {

   miao++;

           if(miao>59) miao=0;//如果miao等于60 miao赋值为0

 

    }

        if(qh==2)

        {

       fen++;

          if(fen>59) fen=0;   //如果fen等于60 fen赋值为0

 

    }

       if(qh==3)

        {

     shi++;

         if(shi>23)shi=0;   //如果shi等于24 shi赋值为0  

       }

   keycode=NOT_Break;   //任意赋值避开条件

  }

///////////////////////////---第三个按键按下---///////////////////////////////

if(keycode==2)    //第三个按键按下   减

       {

if(qh==1)

        {

   miao--;

           if(miao<0)  miao=59;//如果miao等于-1 miao赋值为59  

    }

        if(qh==2)

        {

      fen--;

          if(fen<0) fen=59;   //如果fen等于-1 fen赋值为59  

    }

       if(qh==3)

        {

      shi--;

         if(shi<0) shi=23;   //如果shi等于-1 shi赋值为23  

       }

   keycode=NOT_Break;   //任意赋值避开条件

  }

///////////////////////////---第四个按键按下---///////////////////////////////   

   if(keycode==3)   //第四个按键按下    确定

   {

qh=0;

keycode=NOT_Break;   //任意赋值避开条件

}

///////////////////////////////////////////////////////////////////////////

///////////////////////////---显示函数---///////////////////////////////   

switch(qh)    //按键按下后立即显示

{

//正常显示  

case 0:

if(flag==1) //显示日期 年月日

{   

val[0]=2;

val[1]=0;

val[2]=1;

val[3]=9;

val[4]=0;

val[5]=7;

val[6]=0;

val[7]=4;

}

else

{

val[0]=shi/10; //显示时间 时分秒

val[1]=shi%10;

val[2]=10;

val[3]=fen/10;

val[4]=fen%10;

if(fen==30) {  BEEP=0;delay(200);BEEP=1; }

else if(fen==0) {  BEEP=0;delay(100);BEEP=1;} 

val[5]=10;

val[6]=miao/10;

val[7]=miao%10;

  }

break;

//秒钟修改后显示  其中秒钟部分在闪烁

case 1:

if(time<250)      //2ms*250=0.5s

{  

    val[0]=shi/10;

val[1]=shi%10;

val[3]=fen/10;

val[4]=fen%10;

val[6]=miao/10;

val[7]=miao%10;    

}

else if(time<500) //2ms*500=1s

{

      val[0]=shi/10;

val[1]=shi%10;

val[3]=fen/10;

val[4]=fen%10;

val[6]=11;

val[7]=11;

}

else if(time>500) //2ms*500=1s

time=0;

}

break;

//分钟修改后显示  其中分钟部分在闪烁

case 2:

if(time<250)

{

    val[0]=shi/10;

val[1]=shi%10;

val[3]=fen/10;

val[4]=fen%10;

val[6]=miao/10;

val[7]=miao%10;  

}

else if(time<500)

    val[0]=shi/10;

val[1]=shi%10;

val[3]=11;

val[4]=11;

val[6]=miao/10;

val[7]=miao%10;     

}

else if(time>500)

{

time=0;

}

break;

//时钟修改后显示  其中时钟部分在闪烁

case 3:

if(time<250)

{

val[0]=shi/10;

val[1]=shi%10;

val[3]=fen/10;

val[4]=fen%10;

val[6]=miao/10;

val[7]=miao%10;

}

else if(time<500) 

{

val[0]=11;

val[1]=11;

val[3]=fen/10;

val[4]=fen%10;

val[6]=miao/10;

val[7]=miao%10;  

}

else if(time>500)

[1] [2]
关键字:日历  数字钟  STC89C51 引用地址:课程设计题三:日历和数字钟

上一篇:课程设计题四:LED彩灯控制器设计
下一篇:课程设计题二:7人多数表决器

推荐阅读最新更新时间:2024-10-09 20:06

PLC实现两线连接型数显仪表系统设计
  引言 目前的 PLC 系统有时需借助于专用的人机界面(HMI)、工业PC来显示过程变量或设置系统参数。HMI和IPC不仅增加了PLC系统的成本,而且无法适应高温、高湿热、多粉尘的工作环境。如果使用PLC系统的I/O直接驱动数码管进行显示,则需要占用大量的PLC系统I/O资源。本文采用单片机和程序控制技术,通过特定的传输时序,只需使用PLC系统的2个I/O点即可实现其参数显示。   1 硬件设计   以STC89C51为核心实现的PLC系统两线连接型数显仪表的硬件组成如图1所示。整个硬件系统主要由STC89C51单片机、输入接口、程序下载接口、数码管显示驱动电路、按键输入(可选)和报警输出(可选)等部分组成。STC89
[单片机]
PLC实现两线连接型数显仪表系统设计
适于学校使用的电子日历设计
  目前市售的电子日历品种较多,一般只能显示时间信息,功能单一。笔者根据学校特点,设 计了一款适于学校使用的电子日历,该电子日历采用几种新型芯片,利用单片机技术,做到 了功能多、显示全、成本低,并有掉电保持功能,非常适于学校各部门的使用,是传统钟表 的升级换代产品。 1功能介绍    电子日历面板如图 1所示。该电子日历可显示年、月、日、星期、时、分的时间信息以及温 度值。另外,还能显示校历周数,重大节庆日的倒计时天数。此功能是区别于其 他电子日历的特点所在。为设定初值,电子日历设有三个按键,采用循环设定方式。过程如 下:按设定键,首先进入校历周数初值设定,按增 /减键,可选择校历周数的2位十进制初值 ;再按设
[单片机]
适于学校使用的电子<font color='red'>日历</font>设计
教您一键将世界杯赛程导入iPhone日历
    要说本周最令人兴奋的事当然非世界杯莫属,虽然比赛大多数是在凌晨时分,但是熬夜看球的激情却丝毫没有退却。就算第二天还要上班,就算第二天还要写 方案,对于真正的球迷来说,这些都比不上彻夜支持自己喜爱的球队重要。   常常熬夜会令人精神萎靡头脑迟钝,万一记错了比赛的时间错过了直播,那悔恨的心情可 想而知,小编现在就教您如何将世界杯赛程导入日历,重要比赛设置好闹钟,这样就不会错过任何精彩的进球了。   其实有关世界杯的应用非常多,但还需要单独下载,而且也不一定所有信息您都需要,光试用查找可能就要浪费很多时间,小编的这个方法既快捷又简单,最适合真球迷使用!   首先打开Safari(需用手机浏览器)输入www.bycm.cc/
[手机便携]
基于单片机的日历时钟模块设计
在实时监控系统的设计中,要实时监测各个控制信号,更重要的是在发生故障时能准确记录故障数据,以便准确分析排除错误。监控系统中一般都要定时采集现场数据,对某些重要的信息不仅要记录其内容,还要记录下该信息发生的准确时间,所记录的实时时间信息应长期保存,因此需要实时时钟来实现。常用的单片机没有实时时钟,若需采用定时器实现,一旦系统掉电,时钟就不能运行,这是实时监控系统 不允许的,而采用独立运行的实时时钟便可实现。但一般的时钟芯片在系统掉电时,其数据也会丢失,需提供备用电池。而时钟芯片DS12887在系统掉电时数据不丢失,广泛应用于测量和控制系统。因此,这里给出了实时时钟DS12887在单片机应用系统中的应用。 1 主要器件造型 1.1
[单片机]
基于单片机的<font color='red'>日历</font>时钟模块设计
基于FPGA的数字日历设计
  基于FPGA 设计数字日历可以实现以软件方式设计硬件的目的,无需购买专用数字芯片,从而克服了传统利用多片数字集成电路设计数字日历存在焊接麻烦、调试繁琐、成本较高等问题。而且,基于FPGA 的数字日历与传统系统相比,在设计灵活、开发速度、降低成本、计时精度、功能实现上都得到大幅度提升,能够更好地满足人们日常生活的需要。   本文介绍如何利用VHDL 硬件描述语言设计一个具有年、月、日、星期、时、分、秒计时显示功能,时间调整功能和整点报时功能的数字日历。在Quartus Ⅱ开发环境下,采用自顶向下的设计方法,建立各个基本模块,再构建成一个完整的基于FPGA 设计的数字日历的顶层模块,然后对其进行编译、仿真、引脚锁定,最终下载到可编
[电源管理]
基于FPGA的数字<font color='red'>日历</font>设计
一种新型的时钟日历芯片DS12C887
摘要: 简要介绍了美国DALLAS公司的新型时钟日历芯片DS12C887的功能特性和内部控制寄存器参数,给出了DS12C887与8031单片机的电路连接图,同时给出了用C51编写的初始化程序和获取内部时间的程序。 关键词: 时钟 单片机 DS12C887 1 器件特性 DS12C887实时时钟芯片功能丰富,可以用来直接代替IBM PC上的时钟日历芯片DS12887,同时,它的管脚也和MC146818B、DS12887相兼容。 由于DS12C887能够自动产生世纪、年、月、日、时、分、秒等时间信息,其内部又增加了世纪寄存器,从而利用硬件电路解决子“千年”问题; DS12C887中自带有锂电池,外部掉电时,其内
[单片机]
一种新型的时钟<font color='red'>日历</font>芯片DS12C887
数字钟
数字钟是一种用数字电路技术实现时、分、秒计时的钟表。与机械钟相比具有更高的准确性和直观性,具有更长的使用寿命,已得到广泛的使用。数字钟的设计方法有许多种,例如可用中小规模集成电路组成电子钟,也可以利用专用的电子钟芯片配以显示电路及其所需要的外围电路组成电子钟,还可以利用单片机来实现电子钟等等。这些方法都各有其特点,其中利用单片机实现的电子钟具有编程灵活,以便于功能的扩展。 工作原理 单片机 通过了 3 只 74HC164 串行-并行转换芯片后,驱动时钟屏幕,因为时钟屏幕的极性是共阴极, 所以必须使用“ 74 HC ”电路而不能使用“74 LS ”电路,后者的高电平驱动能力很差!这里的3只7 4HC164 芯片,自身属于串行输
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved