找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 34565|回复: 14
打印 上一主题 下一主题
收起左侧

利用STC89C51单片机和LCD1602电子显示屏实现电子时钟设计

  [复制链接]
跳转到指定楼层
楼主
ID:429225 发表于 2018-11-23 19:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   数字钟实际上是一个对标准频率(1HZ)进行计数的数字电路。振荡器产生的时钟信号经过分频器形成秒脉冲信号,秒脉冲信号输入计数器进行计数,并把累计结果以“时”、“分”、“秒”的数字显示出来。秒计数器电路计满60后触发分计数器电路,分计数器电路计满60后触发时计数器电路,当计满24小时后又开始下一轮的循环计数。一般由振荡器、分频器、计数器、译码器、数码显示器等几部分组成。
振荡电路:主要用来产生时间标准信号,因为时钟的精度主要取决于时间标准信号的频率及稳定度,所以采用石英晶体振荡器。
分频器:因为振荡器产生的标准信号频率很高,要是要得到“秒”信号,需一定级数的分频器进行分频。
计数器:有了“秒”信号,则可以根据60秒为1分,24小时为1天的进制,分别设定“时”、“分”、“秒”的计数器,分别为60进制,60进制,24进制计数器,并输出一分,一小时,一天的进位信号。
译码显示:将“时”“分”“秒”显示出来。将计数器输入状态,输入到译码器,产生驱动数码显示器信号,呈现出对应的进位数字字型。
由于计数的起始时间不可能与标准时间(如北京时间)一致,故需要在电路上加一个校时电路可以对分和时进行校时。另外,计时过程要具有报时功能,当时间到达整点前10秒开始,蜂鸣器1秒响1秒停地响5次。
为了使数字钟使用方便,在设计上使用了一个变压器和一个整流桥来实现数字钟电能的输入,使得可以方便地直接插入220V的交流电就可以正常地使用了。


目    录

1 设计目的
2 设计任务
3 总体方案设计
4 单元电路设计、参数计算和元器件选择
5 仿真结果
6 结 束 语              20
参考文献              21
附    录              22
附录1 电路原理图              2
附录2 系统仿真图              24

数字钟系统

1 设计目的      
随着科学技术的不断发展,人们对时间计量的精度要求越来越高。高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟 石晶表 石英钟 都采用了石英技术,因此走时精度高,稳定性好,使用方便;另一方面《数字电子技术》是一门实践性很强的的,只靠短短的课堂教学,学生只能略懂一些肤浅的表面知识,通过设计,学生亲自动手去做,在发现问题和解决问题中,才能够更好的理解《数字电子技术》的理论知识,提干我们的知识运用能力和实验技术,增强实践能力,为我们将来在技术领域的发展奠定了一定的实践基础。
本次电子技术基础设计选题是数字钟的设计。主要原理是由晶体振荡电路产生多谐振荡,经过分频器分频后输出稳定的秒脉冲,作为时间基准。秒计数器满60向分计数器进位,分计数器满60向小时计数器进位,小时计数器以24为一个周期,并实现小时高位具有零熄灭的功能。计数器的输出经译码器送到显示器,可在相应位置正确显示时、分、秒。计时出现误差或者调整时间可以用校时电路进行时、分的调整。
2 设计任务

2.1  电子钟设计内容

利用STC89C51单片机和LCD1602电子显示屏实现电子时钟,可由按键进行调时和12/24小时切换。

2.2  电子钟设计要求

1.能实现年、月、日、星期、时、分、秒的显示;

2.能实现调时功能;

3.能实现12/24小时制切换;

4.能实现8:00—22:00整点报时功能。

2.3  系统运行流程

程序首先进行初始化,在主程序的循环程序中首先调用数据处理程序,然后调用显示程序,在判断是否有按键按下。若有按键按下则转到相应的功能程序执行,没有按键按下则调用时间程序。若没到则循环执行。计时中断服务程序完成秒的计时及向分钟、小时的进位和星期、年、月、日的进位。调时闪烁中断服务程序用于被调单元的闪烁显示。调时程序用于调整分钟、小时、星期、日、月、年,主要由主函数组成通过对相关子程序的调用,如图所示。实现了对时间的设置和修改、LCD显示数值等主要功能。相关的调整是靠对功能键的判断来实现的。


3总体方案设计
数电方案一:
如图所示,数字时钟系统的结构可分为六个部分,由振荡电路、分频电路、计数电路(分为秒计数电路、分计数电路、时计数电路)、译码显示电路以及附加功能电路(校时校分电路、整点报时电路)组成。

用数电进行设计结构复杂,易于出错。

单片机方案二:
3.1 程序设计及调试

根据单片机设计内容和要求,完成Protues仿真电路的设计和用Keil软件编写程序,并进行仿真模拟调试。

对设计过程进行总结,完成设计文档。

3.2  数字钟系统方框图

                           3-1  总体图

3.3数字钟系统流程图


3-2主流图                                 3-3 键盘扫描流程图              

3-4时钟流程图

4  单元电路设计、参数计算和元器件选择

4.1  主要器件

1. STC89C51单片机;

2.LCD1602液晶显示屏

4.2主要器件简介

1STC89C51单片机简介

STC89C51是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时钟频率为80MHz,片内含8K Bytes的可反复擦写1000次的Flash只读程序存储器,器件兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。



2LCD1602液晶显示屏简介

LCD1602可以显示2行16个字符,有8位数据总线D0—D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。

LCD1602引脚说明如下表所示:

                LCD液晶显示器各引脚功能及结构

编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
双向数据口
2
VDD
电源正极
10
D3
双向数据口
3
VL
对比度调节
11
D4
双向数据口
4
RS
数据/命令选择
12
D5
双向数据口
5
R/W
读写/选择
13
D6
双向数据口
6
E
模块使能端
14
D7
双向数据口
7
D0
双向数据口
15
BLK
背光源地
8
D1
双向数据口
16
BLA
背光源正极

VDD:电源正极,4.5V—5.5V,通常使用5V电压;

VL:LCD对比度调节端,电压调节范围为0—5V。接正极时对比度最弱,接地电源时对比度最高,但对比度过高会产生“鬼影”,因此通常使用一个10K的电位器来调整对比度,或者直接串接一个电阻到地;

RS:MCU写入数据或者指令选择端。MCU要写入指令时,使RS为低电平;MCU要写入数据时,使RS为高电平;

R/W:读写控制端。R/W为高电平时,读取数据;R/W为低电平时,写入数据;

EN:LCD模块使能信号控制端。写数据时,需要下降沿触发模块。

D0—D7:8为数据总线,三态双向。如果MCU的I/O口资源紧张的话,该模块也可以只使用4位数据线D4—D7接口传送数据。

A:LED背光正极。需要背光时, A串接一个限流电阻接VDD, K接地。

K:LED背光地端。

4.3  最小系统

复位时单片机的初始化操作,只要给RST引脚加上两个机器周期以上的高电平信号,就可以使STC89C51单片机复位。本次采用的是12M晶振,按钮复位电路。

图4-1  最小系统


4.4   LCD显示电路

LCD显示屏的D0到D7与单片机P0口相连,LCD显示屏EN口与单片机P3.4口相连,RS与P3.5相连。通过滑动变阻器改变LCD显示屏的显示对比度。

图4-2   LCD显示电路

4.5  键盘输入电路

本次设计采用独立键盘,键盘按下时,相应的I/O口电平由高变低,一次检测按键是否被按下。4个独立按键与单片机P3.0—P3.3口相连。

                   图4-3   键盘输入电路

4.6  蜂鸣器和LED灯电路

蜂鸣器的作用为准点报时产生报警声,LED在秒钟为偶数时或者功能键被按下时亮。蜂鸣器与单片机P2.2口相连,LED灯与单片机P2.3口相连。


5  仿真结果

用Keil和Protues进行仿真调试,仿真结果完全达到预期目的

图5-1总体电路图


6  结束语

本次设计,即将告一段落,但收获却是弥足珍贵。一分耕耘,一分收获。部亲自去尝试,你很难去体验那份开心。我们经过了这半年对单片机由一无所知到逐步了解,现在开始了一些小的制作。设计是一项好的方向,让我们去自我提高,很有裨益。 实验开始前,同组的同伴就开始了收集资料,尝试着去努力实现一些功能。起初,我对单片机知道很少,还是经过看看细节性的东西,才渐渐有些入门。当然,实验的过程中也遇到了许多的难题。在设计过程中,从仿真电路的设计,源程序的书写和修改以及实物电路的焊接中都遇到了不少问题,但在我们的共同努力下解决了,并且从中学到了不少知识。我们在设计过程中还不断提出自己的疑点以及新的想法,联系实际应用,将课本上学习的东西运用到实际中,这些都令我们受益匪浅。
  • 实现电子钟的数码显示

在这一过程中,显示部分总是会出现这样那样的问题。

   2、按键问题

我的设计中,大部分功能选择是通过按键开关实现的。在仿真中发现,调整数值时,有时按键反应太快,按一次,跳了几下,使设置时间很不方便。但是仿真多了之后,找到了按键(实际上是按鼠标)的节奏,对按键的掌控力提高了不少,不怎么会出现跳变的情况了。有些开关我采用了长按键的方式来防抖,效果不错,但是每次都要长按键,调整效率太低,我没有普及。本来想把所有的按键都加延时防抖电路,但仿真中感觉对键盘的控制力没提高多少。


参考文献

[1] 《单片机原理及应用(第二版)》      高等教育出版社

[2] 《新概念51单片机C语言教程》      电子工业出版社

附    录
附录1  系统仿真图




附录2  系统源程序
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit lcdrs=P3^5;  //定义1602液晶RS端
  5. sbit lcden=P3^4;//定义1602液晶LCDEN端
  6. sbit s1=P3^0;   //定义按键--功能键
  7. sbit s2=P3^1;              //定义按键--增加键
  8. sbit s3=P3^2;              //定义按键--减小键
  9. sbit s4=P3^3;              //定义按键--闹钟键
  10. sbit beep=P2^2; //定义蜂鸣器端
  11. sbit led=P2^3;  //定义LED灯端
  12. uchar count,s1num,s4num;
  13. char year,month,day,week,miao,shi,fen,pshi;
  14. uchar code table[]=" 20  -  -   ";//定义初始上电时液晶默认显示状态
  15. void delay(uint z)  //延时函数
  16. {
  17.               uint x,y;
  18.               for(x=z;x>0;x--)
  19.                             for(y=110;y>0;y--);
  20. }
  21. void zhuanhuan()
  22. {
  23.               if(shi==0)
  24.                   pshi=12;
  25.               if(shi<=12&&shi>=1)
  26.                   pshi=shi;
  27.     if(shi>12)
  28.                   pshi=shi-12;                                                                        
  29. }                                                                                                                                                
  30. void di()//蜂鸣器发声函数
  31. {
  32.               beep=0;
  33.               delay(300);
  34.               beep=1;
  35.               delay(300);
  36. }
  37. void write_com(uchar com)//液晶写命令函数
  38. {
  39.               lcdrs=0;
  40.               lcden=0;
  41.               P0=com;
  42.               delay(5);
  43.               lcden=1;
  44.               delay(5);
  45.               lcden=0;            
  46. }
  47. void write_date(uchar date)//液晶写数据函数
  48. {
  49.               lcdrs=1;
  50.               lcden=0;
  51.               P0=date;
  52.               delay(5);
  53.               lcden=1;
  54.               delay(5);
  55.               lcden=0;            
  56. }
  57. void _shi()              //写"AM"、"PM"函数
  58. {
  59.    if(shi>=12)
  60.    {
  61.               write_com(0x80+0x40+1);//写出"PM"
  62.               write_date('P');
  63.               write_date('M');
  64.    }
  65.    else
  66.    {
  67.               write_com(0x80+0x40+1);//写出"AM"
  68.               write_date('A');
  69.               write_date('M');
  70.    }
  71. }
  72. void write_ymd(uchar add1,uchar date1)//写年月日函数
  73. {
  74.               uchar shi,ge;
  75.               shi=date1/10;//分解一个2位数的十位和个位
  76.               ge=date1%10;
  77.               write_com(0x80+add1);//设置显示位置
  78.               write_date(0x30+shi);//送去液晶显示十位
  79.               write_date(0x30+ge); //送去液晶显示个位
  80. }
  81. void write_sfm(uchar add,uchar date)//写时分秒函数
  82. {
  83.               uchar shi,ge;
  84.               shi=date/10;//分解一个2位数的十位和个位
  85.               ge=date%10;
  86.               write_com(0x80+0x40+add);//设置显示位置
  87.               write_date(0x30+shi);//送去液晶显示十位
  88.               write_date(0x30+ge); //送去液晶显示个位
  89. }
  90. void write_week(char week)                 //写液晶星期显示函数
  91. {
  92.               write_com(0x80+12);
  93.               switch(week)
  94.               {
  95.                             case 1:              write_date('M');delay(5);
  96.                                                         write_date('O');delay(5);
  97.                                                         write_date('N');
  98.                                                         break;
  99.                             case 2:              write_date('T');delay(5);
  100.                                                         write_date('U');delay(5);
  101.                                                         write_date('E');
  102.                                                         break;
  103.                             case 3:              write_date('W');delay(5);
  104.                                                         write_date('E');delay(5);
  105.                                                         write_date('D');
  106.                                                         break;
  107.                             case 4:              write_date('T');delay(5);
  108.                                                         write_date('H');delay(5);
  109.                                                         write_date('U');
  110.                                                         break;
  111.                             case 5:              write_date('F');delay(5);
  112.                                                         write_date('R');delay(5);
  113.                                                         write_date('I');
  114.                                                         break;
  115.                             case 6:              write_date('S');delay(5);
  116.                                                         write_date('A');delay(5);
  117.                                                         write_date('T');
  118.                                                         break;
  119.                             case 7:              write_date('S');delay(5);
  120.                                                         write_date('U');delay(5);
  121.                                                         write_date('N');
  122.                                                         break;
  123.               }
  124. }
  125. void writeym()
  126. {
  127.    day=1;
  128.    month++;
  129.    if(month==13)
  130.    {
  131.               month=1;
  132.               year++;
  133.               if(year==100)
  134.                   year=0;
  135.               write_ymd(3,year);//年若变化则重新写入
  136.               }
  137.               write_ymd(6,month);//月若变化则重新写入
  138. }
  139. void init()//初始化函数
  140. {
  141.     uchar num;
  142.               lcden=0;
  143.               year=13;//初始化种变量值
  144.               month=6;
  145.               day=21;
  146.               week=5;
  147.               shi=13;
  148.               fen=59;
  149.               miao=58;
  150.               count=0;
  151.               s1num=0;
  152.               s4num=0;
  153.               write_com(0x38);//初始化1602液晶
  154.               write_com(0x0c);
  155.               write_com(0x06);
  156.               write_com(0x01);
  157.               write_com(0x80);//设置显示初始坐标
  158.               for(num=0;num<15;num++)//显示年月日星期
  159.               {
  160.                             write_date(table[num]);
  161.                             delay(5);
  162.               }
  163.                             delay(5);
  164.                             write_com(0x80+0x40+6);//写出时间显示部分的两个":"
  165.                             write_date(':');
  166.                             delay(5);
  167.                             write_com(0x80+0x40+9);
  168.                             write_date(':');
  169.                             delay(5);
  170.               write_week(week);
  171.               write_ymd(3,year);//分别送去液晶显示
  172.               write_ymd(6,month);
  173.               write_ymd(9,day);
  174.               write_sfm(10,miao);//分别送去液晶显示
  175.               write_sfm(7,fen);
  176.               write_sfm(4,shi);
  177.               TMOD=0x01;//设置定时器0工作模式1
  178.               TH0=(65536-50000)/256;//定时器装初值
  179.               TL0=(65536-50000)%256;
  180.               EA=1;              //开总中断
  181.               ET0=1;              //开定时器0中断
  182.               TR0=1;              //启动定时器0
  183. }
  184. void keyscan()//按键扫描函数
  185. {
  186.               if(s1==0)            
  187.               {
  188.                             delay(5);
  189.                             if(s1==0)//确认功能键被按下
  190.                             {            
  191.                                 s1num++;//功能键按下次数记录
  192.                                           while(!s1);//释放确认                                         
  193.                                           if(s1num==1)//第一次被按下时
  194.                                           {
  195.                                               TR0=0;  //关闭定时器
  196.                                                         write_com(0x80+3);//光标定位到年位置
  197.                                                         write_com(0x0f); //光标开始闪烁
  198.                                           }
  199.                                           if(s1num==2)//第二次按下光标闪烁定位到月位置
  200.                                           {
  201.                                                         write_com(0x80+6);
  202.                                           }
  203.                                           if(s1num==3)//第三次按下光标闪烁定位到日位置
  204.                                           {
  205.                                                         write_com(0x80+9);
  206.                                           }
  207.                                           if(s1num==4)//第四次按下光标闪烁定位到星期位置
  208.                                           {
  209.                                                         write_com(0x80+12);
  210.                                           }
  211.                                           if(s1num==7)//第七次被按下时光标定位到秒位置
  212.                                           {
  213.                                                         write_com(0x80+0x40+10);
  214.                                           }
  215.                                           if(s1num==6)//第六次按下光标闪烁定位到分位置
  216.                                           {
  217.                                                         write_com(0x80+0x40+7);
  218.                                           }
  219.                                           if(s1num==5)//第五次按下光标闪烁定位到时位置
  220.                                           {
  221.                                                         write_com(0x80+0x40+4);
  222.                                           }
  223.                                           if(s1num==8)//第七次按下
  224.                                           {
  225.                                                         s1num=0;//记录按键数清零
  226.                                                         write_com(0x0c);//取消光标闪烁
  227.                                                         TR0=1;              //启动定时器使时钟开始走
  228.                                           }                           
  229.                             }
  230.               }
  231.               if(s1num!=0)//只有功能键被按下后,增加和减小键才有效
  232.               {
  233.                             if(s2==0)
  234.                             {
  235.                                           delay(5);
  236.                                           if(s2==0)//增加键确认被按下
  237.                                           {
  238.                                                         while(!s2);//按键释放
  239.                                                         if(s1num==1)//若功能键第一次按下
  240.                                                         {
  241.                                                                       year++; //则调整年加1
  242.                                                                       if(year==100)//若满100后将清零
  243.                                                                                     year=0;
  244.                                                                       write_ymd(3,year);//每调节一次送液晶显示一下
  245.                                                                       write_com(0x80+3);//显示位置重新回到调节处
  246.                                                         }
  247.                                                         if(s1num==2)//若功能键第二次按下
  248.                                                         {
  249.                                                                       month++;//则调整月加1
  250.                                                                       if(month==13)//若满12后将置一
  251.                                                                                     month=1;
  252.                                                                       write_ymd(6,month);//每调节一次送液晶显示一下
  253.                                                                       write_com(0x80+6);//显示位置重新回到调节处
  254.                                                         }
  255.                                                         if(s1num==3)//若功能键第三次按下
  256.                                                         {
  257.                                                                       day++;//则调整日加1
  258.                                                                       if(year%4==0&&month==2)
  259.                                                                       {
  260.                                                                           if(day==30)//若满29后将置一
  261.                                                                                     day=1;
  262.                                                                       }
  263.                                                                       if(year%4!=0&&month==2)
  264.                                                                       {
  265.                                                                           if(day==29)//若满28后将置一
  266.                                                                                     day=1;
  267.                                                                       }
  268.                                                                       if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  269.                                                                       {
  270.                                                                           if(day==32)//若满31后将置一
  271.                                                                                     day=1;
  272.                                                                       }
  273.                                                                       if(month==4||month==6||month==9||month==11)
  274.                                                                       {            
  275.                                                                                     if(day==31)//若满30后将置一
  276.                                                                                     day=1;
  277.                                                                       }
  278.                                                                       write_ymd(9,day);;//每调节一次送液晶显示一下
  279.                                                                       write_com(0x80+9);//显示位置重新回到调节处
  280.                                                         }
  281.                                                         if(s1num==4)//若功能键第四次按下
  282.                                                         {
  283.                                                                       week++;//则调整星期加1
  284.                                                                       if(week==8)//若满8后将置一
  285.                                                                                     week=1;
  286.                                                                       write_week(week);//每调节一次送液晶显示一下
  287.                                                                       write_com(0x80+12);//显示位置重新回到调节处
  288.                                                         }
  289.                                                         if(s1num==7)//若功能键第七次按下
  290.                                                         {
  291.                                                                       miao++; //则调整秒加1
  292.                                                                       if(miao==60)//若满60后将清零
  293.                                                                                     miao=0;
  294.                                                                       write_sfm(10,miao);//每调节一次送液晶显示一下
  295.                                                                       write_com(0x80+0x40+10);//显示位置重新回到调节处
  296.                                                         }
  297.                                                         if(s1num==6)//若功能键第二次按下
  298.                                                         {
  299.                                                                       fen++;//则调整分钟加1
  300.                                                                       if(fen==60)//若满60后将清零
  301.                                                                                     fen=0;
  302.                                                                       write_sfm(7,fen);//每调节一次送液晶显示一下
  303.                                                                       write_com(0x80+0x40+7);//显示位置重新回到调节处
  304.                                                         }
  305.                                                         if(s1num==5)//若功能键第五次按下
  306.                                                         {                                                                     
  307.                                                                       shi++;
  308.                                                                       if(shi==24)//若满24后将清零
  309.                                         {
  310.                                                                          shi=0;
  311.                                                                       }
  312.                                                                          if(s4num==0)
  313.                                                                          {                                                                                                                                                
  314.                                                                             write_sfm(4,shi);;//每调节一次送液晶显示一下
  315.                                                                             write_com(0x80+0x40+4);//显示位置重新回到调节处
  316.                                                                          }                                                                        
  317.                                                                          if(s4num==1)
  318.                                                                          {
  319.                                                                                          zhuanhuan();
  320.                                                                             _shi();
  321.                                                                             write_sfm(4,pshi);;//每调节一次送液晶显示一下
  322.                                                                             write_com(0x80+0x40+4);//显示位置重新回到调节处
  323.                                                                }                                                                     
  324.                                                }
  325.                                           }
  326.                             }
  327.               }
  328.                             if(s3==0)
  329.                             {
  330.                                           delay(5);
  331.                                           if(s3==0)//确认减小键被按下
  332.                                           {
  333.                                                         while(!s3);//按键释放
  334.                                                         if(s1num==1)//若功能键第一次按下
  335.                                                         {
  336.                                                                       year--;//则调整秒减1
  337.                                                                       if(year==-1)//若减到负数则将其重新设置为99
  338.                                                                                     year=99;
  339.                                                                       write_ymd(3,year);//每调节一次送液晶显示一下
  340.                                                                       write_com(0x80+3);//显示位置重新回到调节处
  341.                                                         }
  342.                                                         if(s1num==2)//若功能键第二次按下
  343.                                                         {
  344.                                                                       month--;//则调整分钟减1
  345.                                                                       if(month==0)//若减到负数则将其重新设置为59
  346.                                                                                     month=12;
  347.                                                                       write_ymd(6,month);//每调节一次送液晶显示一下
  348.                                                                       write_com(0x80+6);//显示位置重新回到调节处
  349.                                                         }
  350.                                                         if(s1num==3)//若功能键第二次按下
  351.                                                         {
  352.                                                                       day--;//则调整日加1
  353.                                                                       if(year%4==0&&month==2)
  354.                                                                       {
  355.                                                                           if(day==0)//若满29后将置一
  356.                                                                                     day=29;
  357.                                                                       }
  358.                                                                       if(year%4!=0&&month==2)
  359.                                                                       {
  360.                                                                           if(day==0)//若满28后将置一
  361.                                                                                     day=28;
  362.                                                                       }
  363.                                                                       if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  364.                                                                       {
  365.                                                                           if(day==0)//若满31后将置一
  366.                                                                                     day=31;
  367.                                                                       }
  368.                                                                       if(month==4||month==6||month==9||month==11)
  369.                                                                       {            
  370.                                                                                     if(day==0)//若满30后将置一
  371.                                                                                     day=30;
  372.                                                                       }
  373.                                                                       write_ymd(9,day);;//每调节一次送液晶显示一下
  374.                                                                       write_com(0x80+9);//显示位置重新回到调节处
  375.                                                         }
  376.                                                         if(s1num==4)//若功能键第二次按下
  377.                                                         {
  378.                                                                       week--;//则调整小时减1
  379.                                                                       if(week==0)//若减到负数则将其重新设置为23
  380.                                                                                     week=7;
  381.                                                                       write_week(week);//每调节一次送液晶显示一下
  382.                                                                       write_com(0x80+12);//显示位置重新回到调节处
  383.                                                         }
  384.                                                         if(s1num==7)//若功能键第一次按下
  385.                                                         {
  386.                                                                       miao--;//则调整秒减1
  387.                                                                       if(miao==-1)//若减到负数则将其重新设置为59
  388.                                                                                     miao=59;
  389.                                                                       write_sfm(10,miao);//每调节一次送液晶显示一下
  390.                                                                       write_com(0x80+0x40+10);//显示位置重新回到调节处
  391.                                                         }
  392.                                                         if(s1num==6)//若功能键第二次按下
  393.                                                         {
  394.                                                                       fen--;//则调整分钟减1
  395.                                                                       if(fen==-1)//若减到负数则将其重新设置为59
  396.                                                                                     fen=59;
  397.                                                                       write_sfm(7,fen);//每调节一次送液晶显示一下
  398.                                                                       write_com(0x80+0x40+7);//显示位置重新回到调节处
  399.                                                         }
  400.                                                         if(s1num==5)//若功能键第二次按下
  401.                                                         {
  402.                                                                       shi--;
  403.                                                                       if(shi==-1)//若满24后将清零
  404.                                                                          shi=23;
  405.                                                                          if(s4num==0)
  406.                                                                          {                                                                                                                                             
  407.                                                                             write_sfm(4,shi);;//每调节一次送液晶显示一下
  408.                                                                             write_com(0x80+0x40+4);//显示位置重新回到调节处                                                                                       
  409.                                                                          }
  410.                                                                          if(s4num==1)
  411.                                                                          {                                                                        
  412.                                     zhuanhuan();
  413.                                                                             _shi();
  414.                                                                             write_sfm(4,pshi);;//每调节一次送液晶显示一下
  415.                                                                             write_com(0x80+0x40+4);//显示位置重新回到调节处
  416.                                                                }                                                                     
  417.                                                }
  418.                             }
  419.               }
  420.               if(s1num==0)
  421.               {
  422.                 if(s4==0)            
  423.                 {
  424.                             delay(5);
  425.                             if(s4==0)//确认功能键被按下
  426.                             {            
  427.                                 s4num++;//功能键按下次数记录
  428.                                           while(!s4);//释放确认                                         
  429.                                           if(s4num==1)//第一次被按下时
  430.                                           {
  431.                                               zhuanhuan();
  432.                                                         _shi();
  433.                                                         write_sfm(4,pshi);
  434.                                           }                                         
  435.                                           if(s4num==2)//第二次按下
  436.                                           {
  437.                                                         s4num=0;//记录按键数清零
  438.                                                         write_com(0x80+0x40+1);
  439.                                                         write_date(' ');
  440.                                                         write_date(' ');
  441.                                                         write_sfm(4,shi);
  442.                                           }                           
  443.                             }
  444.       }
  445.               }   
  446. }
  447. void main()//主函数
  448. {
  449.               init();//首先初始化各数据                           
  450.               while(1)//进入主程序大循环
  451.               {
  452.                             keyscan();//不停的检测按键是否被按下
  453.                             if(s1num!=0)
  454.                                led=0;
  455.                             else                 
  456.                                led=miao%2;            
  457.                             if((shi>7&&shi<23)&&(fen==0)&&(miao==0))
  458.                             {
  459.                             di();                           
  460.                             }                                                      
  461.               }
  462. }
  463. void timer0() interrupt 1//定时器0中断服务程序
  464. {
  465.               TH0=(65536-50000)/256;//再次装定时器初值
  466.               TL0=(65536-50000)%256;
  467.               count++;                            //中断次数累加
  468.               if(count==20) //20次50毫秒为1秒
  469.               {
  470.                             count=0;
  471.                             miao++;
  472.                             if(miao==60)//秒加到60则进位分钟
  473.                             {
  474.                                           miao=0;//同时秒数清零
  475.                                           fen++;
  476.                                           if(fen==60)//分钟加到60则进位小时
  477.                                           {
  478.                                                         fen=0;//同时分钟数清零
  479.                                                         shi++;                                                      
  480.                                                         if(shi==24)//小时加到24则小时清零
  481.                                                         {
  482.                                                                       shi=0;
  483.                                                                       week++;
  484.                                                                          if(week==8)
  485.                                                                          {
  486.                                                                              week=1;
  487.                                                                          }
  488.                                                                          write_week(week);//星期若变化则重新写入
  489.                                                                       day++;
  490.                                                                          if(year%4==0&&month==2)//判断是否为闰年的2月
  491.                                                                          {
  492.                                                                             if(day==30)
  493.                                                                                       {
  494.                                                                                          writeym();                                                                                                                                                                                                                                                                        
  495.                                                                                       }
  496.                                                                                       write_ymd(9,day);//日若变化则重新写入
  497.                                                                          }
  498.                                                                          if(year%4!=0&&month==2)//判断是否为平年的2月
  499.                                                                          {
  500.                                                                             if(day==29)
  501.                                                                                       {
  502.                                                                                          writeym();                                                                                                                                                                       
  503.                                                                                       }
  504.                                                                                       write_ymd(9,day);//日若变化则重新写入
  505.                                                                          }
  506.                                                                          if(month!=2&&month!=4&&month!=6&&month!=9&&month!=11)
  507.                                                                          {
  508.                                                                             if(day==32)
  509.                                                                                       {
  510.                                                                                          writeym();                                                                                                                                                                       
  511.                                                                                       }
  512.                                                                                       write_ymd(9,day);//日若变化则重新写入
  513.                                                                          }
  514.                                                                          if(month==4||month==6||month==9||month==11)
  515.                                                                          {
  516.                                                                             if(day==31)
  517.                                                                                       {
  518.                                                                                          writeym();                                                                                                                                                                       
  519.                                                                                       }
  520.                                                                                       write_ymd(9,day);//日若变化则重新写入
  521.                                                                          }
  522.                                                         }
  523.                                                         if(s4num==1)
  524.                                                           {
  525.                                                              zhuanhuan();
  526.                                                                       _shi();                                                      
  527.                                                              write_sfm(4,pshi);//12小时制小时若变化则重新写入
  528.                                                           }
  529.                                                         else write_sfm(4,shi);//24小时制小时若变化则重新写入                                                      
  530.                                           }
  531.                                           write_sfm(7,fen);//分钟若变化则重新写入
  532.                             }
  533.                             write_sfm(10,miao);//秒若变化则重新写入            
  534.               }            
  535. }
复制代码
本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬,文件下载:
以上图文的Word格式文档下载(内容和本网页上的一模一样,方便大家保存):
数字钟.doc (652.49 KB, 下载次数: 262)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:432657 发表于 2019-4-29 09:06 | 只看该作者
那走了老哥
回复

使用道具 举报

板凳
ID:563001 发表于 2019-6-15 12:22 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

地板
ID:554935 发表于 2019-6-20 12:14 | 只看该作者
键盘电路那里能不能不加电源和电阻,去掉会对整体程序有影响吗
回复

使用道具 举报

5#
ID:571770 发表于 2019-6-25 15:48 | 只看该作者
回复

使用道具 举报

6#
ID:575093 发表于 2019-7-3 12:15 来自手机 | 只看该作者
刚刚下载了,挺好的
回复

使用道具 举报

7#
ID:13396 发表于 2019-11-11 21:02 | 只看该作者
挺好的,谢谢了。
回复

使用道具 举报

8#
ID:513345 发表于 2019-11-17 17:37 | 只看该作者
P3^3不是闹钟键吗?没有定时闹钟的功能
回复

使用道具 举报

9#
ID:647564 发表于 2019-11-22 22:53 | 只看该作者
学习了
回复

使用道具 举报

10#
ID:668121 发表于 2019-12-19 11:26 | 只看该作者
写AM,PM那里有重复定义怎么解决
回复

使用道具 举报

11#
ID:773695 发表于 2020-6-9 10:35 | 只看该作者
可不可以时间为系统当前时间
回复

使用道具 举报

12#
ID:947923 发表于 2021-7-3 21:19 | 只看该作者
请问,为什么我的不能用啊,那个lcd1602的定义有什么用?
回复

使用道具 举报

13#
ID:1035047 发表于 2022-6-16 01:07 | 只看该作者
so楊 发表于 2021-7-3 21:19
请问,为什么我的不能用啊,那个lcd1602的定义有什么用?

我的也是
回复

使用道具 举报

14#
ID:1035047 发表于 2022-6-16 01:08 | 只看该作者
so楊 发表于 2021-7-3 21:19
请问,为什么我的不能用啊,那个lcd1602的定义有什么用?

keil显示这个程序是错的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表