带闹钟的电子钟(单片机)
课 程 设 计
带闹钟的电子钟
系 别 : 计算机科学与技术系
专业(班级): 计算机科学与技术2011级本班
作者(学号):
指导教师:
完成日期:
汪静([1**********]) 张自军 2013年12月05日
二○一二年12月28日
前 言
20世纪末,电子技术获得了飞速的发展。在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高。同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。 时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。但是,一旦重要事情,一时的耽误可能酿成大祸。例如,许多火灾都是由于人们一时忘记了关闭煤气或是忘记充电时间。所以有必要制作一个定时系统。随时提醒这些容易忘记时间的人。 而钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、定时启闭电路、定时开关烘箱、通断动力设备,甚至各种定时电气的自动启用等等。所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。
随着生活水平的提高,人们越来越追求人性化的事物。传统的时钟已不能满足人们的需求。而现代的时钟不仅需要模拟电路技术和数字电路技术而且更需要单片机技术,增加数字钟的功能。利用软件编程尽量做到硬件电路简单稳定,减小电磁干扰和其他环境干扰, 减小因元器件精度不够引起的误差,但是数字钟还是可以改进和提高如选用更精密的元器件。但与机械式时钟相比已经具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
数字钟通过数字电路实现时、分、秒。数字显示的计时装置, 广泛用于个人家庭、车站、码头办公室等公共场所成为人们日常生活中不可少的必需品。由于数字集成电路的发展和石英晶体振荡器的广泛应用, 使得数字钟的精度远远超过老式钟表。
多功能数字钟的应用非常普遍。由单片机作为数字钟的核心控制器,通过它的时钟信号进行实现计时功能,将其时间数据经单片机输出,利用显示器显示出来。通过键盘可以进行校时、定时等功能。输出设备显示器可以用液晶显示技术和数码管来显示技术。
本系统利用单片机实现具有计时、校时等功能的数字时钟,是以单片机AT89C51为核心元件同时采用LED 数码管显示器动态显示“时”、“分”、“秒”的现代计时装置。另外具有校时功能,秒表功能,和定时器功能,利用单片机实现的数字时钟具有编程灵活,便于功能的扩充等优点。
目 录
前 言 ................................................................. 1
摘 要 ................................................................. 1 ABSTRACT .............................................. 错误!未定义书签。
第1章 课题的背景 ..................................................... 2
1.1 课题的来源 ......................................................... 2
1.2 课题研究的目的和意义 ............................................... 2
1.3应解决的主要问题及达到的技术要求 ................................... 2
第2章 方案的选择和论证................................................. 3
2.1 单片机型号的选择 ................................................... 3
2.2 按键的选择 ......................................................... 3
2.3 显示器的选择 ....................................................... 3
2.4 计时部分的选择 ..................................................... 3
2.5 发音部分的设计 ..................................................... 4
2.6 显示器驱动电路 ..................................................... 4
2.7 电源的选择 ......................................................... 4
第3章 数字电子钟的设计原理和方法 . ...................................... 5
3.1 设计原理 ........................................................... 5
3.2 硬件电路的设计 ..................................................... 5
3.2.1 AT89C51单片机简介 ............................................. 5
3.2.2 键盘电路的设计 ................................................. 6
3.2.3 段码驱动电路 ................................................... 6
3.2.4 蜂鸣器驱动电路 ................................................. 6
3.3 软件部分的设计 ..................................................... 7
3.3.1 主程序部分的设计 .............................................. 7
3.3.2 中断定时器的设置 ............................................... 7
3.3.3 闹钟子函数 ..................................................... 8
3.3.4 计时函数 ....................................................... 9
3.3.4 键盘扫描函数 .................................................. 11
3.3.5 时间和闹钟的设置 .............................................. 11
第4章 实验结果 ....................................................... 13
总 结 ................................................................ 14
致 谢 ................................................................ 15
参考文献 .............................................................. 16
附 录 ................................................................ 17
摘 要
单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。而51单片机是各单片机中最为典型和最有代表性的一种。
本设计以AT89C51芯片为核心,辅以必要的外围电路,设计了一个结构简单,功能齐全的电子时钟,它由5V 直流电源供电。在硬件方面,除了CPU 外,使用六个四段、两个两段、一个一段的LED 数码管来进行显示,LED 采用的是动态扫描显示,使用74LS245芯片进行驱动。通过LED 能够较为准确地显示时、分、秒。四个简单的按键实现对时间的调整。软件方面采用C 语言编程。整个电子钟系统能完成时间的显示、调时、校时和三组定时闹钟并附带上调节温度的功能。
选用单片机最小系统应用程序, 添加比较程序、时间调整程序及蜂鸣程序,通过时间比较程序触发蜂鸣,实现闹钟功能,完成设计所需求的软件环境。介绍并使用Keil 单片机模拟调试软件,测试程序的可行性并用Proteus 进行仿真。
关键词:单片机,定时器,中断,闹钟,LED
第1章 课题的背景
1.1 课题的来源
随着生活水平的提高,人们越来越追求人性化的事物,传统的时钟已不能满足人们的需求。现代的时钟不仅需要模拟电路技术而且需要数字电路技术和单片机技术,增加时钟的功能。数字电子钟可利用软件编程尽量做到硬件电路简单稳定,减小电磁干扰和其他环境干扰, 减小因元器件精度不够引起的误差;尽管如此数字钟还是可以改进和提高,比如选用更精密的元器件。但与机械式时钟相比已经具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
1.2 课题研究的目的和意义
20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。 时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。但是,一旦重要事情,一时的耽误可能酿成大祸。例如,许多火灾都是由于人们一时忘记了关闭煤气或是忘记充电时间等造成的。而钟表的数字化给人们生产生活带来了极大的方便。数字钟是通过数字电路实现时, 分, 秒数字显示的计时装置, 广泛用于个人家庭、车站、码头办公室等公共场所, 成为人们日常生活中不可少的必需品。由于数字集成电路的发展和石英晶体振荡器的广泛应用, 使得数字钟的精度, 远远超过老式钟表, 钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能,诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烤箱、通断动力设备、甚至各种定时电气的自动启用等。所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。
1.3应解决的主要问题及达到的技术要求
本设计应解决的主要问题有两大方面,即硬件电路设计和软件设计两大方面。其中硬件电路部分又可分为四个模块:键盘模块、显示模块、计时模块和发声模块。硬件电路部分致力于低成本、低功耗和易实现性。软件部分则应做到代码的精简、准确、易读懂。最后通过硬软件的结合实现数字钟的精确计时、校时、三组闹钟设置和定时报警功能。
第2章 方案的选择和论证
2.1 单片机型号的选择
通过对多种单片机性能的分析,最终认为AT89C51是最理想的电子时钟开发芯片。AT89C51是一种带4K 字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,器件采用ATMEL 高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,ATMEL 的AT89C51是一种高效微控制器,而且它与MCS-51兼容,且具有4K 字节可编程序存储器和1000次擦写循环,数据保留时间为10年,是最好的选择。
2.2 按键的选择
方案一:4×4矩阵式键盘。如果选择此方案,那么在修改时钟或设置闹铃时间时就可以直接从键盘输入,方便、快捷,但程序较为复杂。
方案二:独立式按键。如果设置过多按键,将会占用较多I/O口,而且会给布线带来不便,因此,此方案适用于按键较少的情况。如果选择此方案,由于按键较少,在修改时间或设置闹铃时间时就不能直接输入,只能通过加或减完成,稍为麻烦一些,但其程序简单。
由于并不需要经常修改时间和设置闹铃时间,而且方案二的程序简单,按键少、成本低,因此,选择方案二。
2.3 显示器的选择
方案一:液晶显示器。如果选择此方案,将会降低系统的功耗,这样就可以用电池供电,便于携带。但液晶显示器的驱动电路复杂,使用起来有一定的难度。
方案二:用数码管作为显示器。数码管的驱动电路简单,使用方便,如果选择了此方案,那么在夜间看时间的时候就不需要有光源,非常方便。其缺点是功耗较大。
由于数码管使用起来较为方便,在夜间看时间也很方便,因此我选择了方案二。
2.4 计时部分的选择
如果使用时钟芯片,系统就不怕掉电且时间精确。但这种芯片比较贵,况且,设计本系统主要是为了学习单片机程序的编写和调试以及设计硬件电路的一些方法,因此采用软件的方法来计时而没有采用价格较高的时钟芯片。
2.5 发音部分的设计
通过三极管放大后驱动蜂鸣器工作,再通过软件这时产生等时时间方波驱动蜂鸣器发出间断嘀声,这样就可以省去硬件振荡电路,降低成本。
2.6 显示器驱动电路
由于通过数码管公共及的电流较大且避免过多地使用分立元件,采用了一片74LS245来驱动段码,用P3口作位码驱动。
2.7 电源的选择
如果是用电池供电,就比较方便携带,但是本系统,采用了数码管作为显示器,功耗较大,需要经常更换电池。况且,本系统的体积较大,即使使用电池供电也不能随身携带,因此,用电池供电不大合适,所以用5V 外部稳压电源来供电。
第3章 数字电子钟的设计原理和方法
3.1 设计原理
系统原理图如下;
图3-1 系统原理图 3.2 硬件电路的设计
3.2.1 AT89C51单片机简介
AT89C51是一款单片封装的微控制器,适合于许多要求高集成度、低成本的场合。可以满足多方面的性能要求。AT89C51采用了高性能的处理器结构,指令执行时间只需2到4个时钟周期。6倍于标准51单片机器件。AT89C51集成了许多系统级的功能,这样可大大减少元件的数目和电路板面积并降低系统的成本。
AT89C51单片机内部主要有以下部件:8031CPU 、振荡电路、总线控制部件、中断控制部件、片内Flash 存储器、并行I/O接口、定时器和串行I/O接口。
图3-2 AT89C51单片机
3.2.2 键盘电路的设计
键盘采用4个独立按键配以4个上拉电阻实现对时钟和闹钟的设定及修改。 图3-3 独立按键 图3-4 键盘输入电路
3.2.3 段码驱动电路
由于通过数码管公共及的电流较大且避免过多地使用分立元件,采用了一片74LS245来驱动段码,用P3口作位码驱动。
图3-5 段码驱动器74LS245
3.2.4 蜂鸣器驱动电路
发音部分是通过三极管放大驱动蜂鸣器工作,再通过软件这时产生等时时间方波驱动蜂鸣器发出间断嘀声,这样就可以省去硬件振荡电路,降低成本。
图3-6 蜂鸣器驱动电路
3.3 软件部分的设计
3.3.1 主程序部分的设计
程序部分主要采用了程序结构的模块化设计,避免了一些函数的不必要的重复书写,使程序变得单间易懂。程序在执行时,主程序要须通过调用子函数就可完成相应的功能 。主程序流程图如下图3-7。
图3-7 主程序流程图
3.3.2 中断定时器的设置
数字电子钟设计中主要使用定时器T0中断ET0,利用ET0中断进行计时时间的自增,从而实现计时功能。
AT89C51有两个通用定时/计数器。两者均可配置为定时器或事件计数器。另外增加了定时器T0/T1,溢出时T0/T1脚自动翻转的功能选项。 用作“定时器”功能时,每经过一个机器周期,寄存器值加1。 用作“计数器”功能时,寄存器在对应的外部输入管脚T0/T1上每发生一次1到0的跳变时加1。使用该功能时,外部输入每个机器周
期被采样一次。
图3-8 定时器工作原理[1]
设计中采用了中断方式1作为定时中断,其定时计数初值的设置可由以下公式计算得到,中断服务流程图如下图3-9。
X =216-t cy
X :计数初值 t:定时时间 T cy :机器周期 [1]
图3-9 中断服务流程图
3.3.3 闹钟子函数
闹钟时间的判别主要是通过设定时间与实时时间对逐位对比确定是否进行闹铃。 其工作流程图如下图3-10。
图3-10 闹铃判断流程图
3.3.4 计时函数
计时函数部分,主要是通过单片机定时中断来计时,复产生一次中断标志位flag 加1,当flag 加满20次为1秒,然后把flag 清0把秒存储单元加1。然后再依次判断分、时。其流程图如下图3-11。
图3-11 计时流程图
3.3.4 键盘扫描函数
这些函数主要是判断是否有按键按下,并根据相应按键按下的情况调用相关函数执行,其相关流程图如下图3-12。
图3-12 键盘扫描流程图
3.3.5 时间和闹钟的设置
此部分主要是通过判断cnt 在不同值时通过调用加1、减1子函数对时间和闹钟的时、分、秒进行设置。在闹钟设置时,判断按键S4按下情况我,进行闹钟的开启与关闭,相关流程图如下图3-13。
图3-13 时间/闹钟设置流程图
第4章 实验结果
此电子闹钟设计是利用Proteus 仿真软件进行仿真,基本上实现了课程设计要求实现的功能。
硬件部分设置了的三个按键S1、S2、S3、S4。当按键S1第一次按下时,停止计时进入闹钟1的秒设置,当按键S1第二、第三次按下时,分别进入闹钟1的分设置和时设置,当按S1第四 、第五、第六次按下时分别进入闹钟2的秒、分、时设置,当按S1第七 、第八、第九次按下时分别进入闹钟3的秒、分、时设置,当按S1第十 、第二一、第十二次按下时分别进入时间的秒、分、时设置,在S1按下的各阶段,可用按键S2、S3进行时间和闹铃时间的时、分、秒进行加减设置;当按键S1第十三次按下时恢复到时间显示功能。当显示的时间和定时设置的时间一致时,蜂鸣器发出等时间断蜂鸣声,闹铃时间设置为60秒。在各个闹钟设置阶段,如果有S4按下,则相应闹钟功能关闭或开启;如在闹铃时有S4按下则提前停止闹铃。
另外,闹铃电路有音乐闹钟的扩展的功能(可以将蜂鸣器换成扬声器再加一段音乐程序即可实现) 。因时间有限,扩展功能还未能及时实现,比如音乐闹铃。
图3-14 运行仿真图
通过自己的不懈努力,我终于完成了毕业设计任务书上的任务要求。功能上基本达标:时钟的显示,调时功能、校时功能、闹铃功能、闹钟设功能。其精确度完全可以满足日常生活显示时间的需要;调时功能,方便快捷;校时功能保证了时钟准确和可靠性,闹钟响铃还有扩展成音乐闹钟的余地。硬件设施合乎要求,软件设计可以配合硬件实现要求的功能。但是由于时间比较短,前期设计出现部分不足:如位选闪烁功能不能实现、闹钟的开启与关闭、间断蜂鸣声等。这些只是软件设计时相应功能部分还不完善造成。不过经仔细思考和程序的完善,最终将软件设计改进,并完全可以很好实现所有要求的功能。
可见技术在不断进步,机械式时钟已经被淘汰,取而代之的是具有高度准确性和直观性且无机械装置,具有更长的使用寿命等优点的数字时钟。数字时钟更具人性化,更能提高人们的生活质量,更受人们欢迎。
无可否认机械时代已经过去,电子时代已经到来。做为新时代的我们,更应该提高自身能力,适应新时代的发展。知识来自实践,多去生活中探询所需要的。对于上述所提到的研究课题,我们应尽量考虑到人的因素,增强时钟的实用性和操作性,为使用者提供切实的方便,营造一种舒适的生活氛围。所以,在设计的时候,应该从多方面、多角度去考虑问题,而且应该进一步提高时钟的质量。
另外,在本次设计的过程中,我发现很多的问题,虽然以前没有做过这样的设计但通过这次设计我学会了很多东西,单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,比如写一个程序看其功能很少认为编写程序简单,但到编程的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。
从这次的课程设计中,我们真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的练习的过程中才能提高,我想这就是我在这次课程设计中的最大收获。
经过几个月的实习调查收集数据资料、整理材料、写作论文,我终于可以顺利的完成论文了。
首先要感谢我的指导老师陈老师,他指引我论文的写作的方向和架构,并对本文初稿进行仔细批阅,指正出其中不当之处,使我有了思考的方向,他的循循善诱的教导和不拘一格的思路给予我无尽的启迪,他的严谨细致、一丝不苟的作风,将一直是我工作、学习中的榜样。
通过此次的论文,我学到了很多知识,在论文的写作过程中,我不仅收集到了论文所需的资料数据,而且学到了很多书本上没有的知识。并且由原先的被动的接受知识转换为主动的寻求知识,我想这可以说是学习方法上的一个很大的突破。
在论文的写作过程中也学到了做任何事情所要有的态度和心态,首先做学问要一丝不苟,对于发展过程中出现的任何问题和偏差都不要轻视,要通过正确的途径去解决,在做事情的过程中要有耐心和毅力,不要一遇到困难就打退堂鼓,只要坚持下去就可以找到思路去解决问题的。
总之,此次论文的写作过程,我收获了很多,为大学四年划上了一个完美的句号,也为将来的人生之路做一个很好的铺垫。
再次感谢我的大学和所有帮助过我并给我鼓励的老师和同学,谢谢你们!
2010年6月
参考文献
[1]李全利、 迟荣强, 单片机原理及接口技术[M],北京:高等教育出版社,2004
[2]凌玉华,单片机原理及应用系统设计[M],长沙:中南大学出版社,2006
[3]张毅刚,MCS-51单片机应用设计[M],哈尔宾:哈尔宾工业大学出版社,1997
[4]胡汉才,单片机原理及应用[M],北京:清华大学出版社,2004
[5]何立明,单片机应用系统设计[M],北京:北京航空航天大学出版社,1990
[6]王荣良,计算机接口技术[M],北京:电子工业出版社,2003
[7]陈光东,单片机微型计算机原理与接口技术[M],武汉:华中理工大学出版社,1998
[8]王幸之、钟爱琴、王雷、王闪,AT89系列单片机原理与接口技术[M],北京:北京航空航天大学出版社,2004
[9]张道德,单片机接口技术(C51版)[M],北京:中国水利水电出版社,2007
[10]王为青、程国钢,单片机Keil CX51应用开发技术[M],北京:人民邮电出版社,2007
[11]张靖武、周灵彬,单片机系统的Proteus 设计与仿真[M],北京:电子工业出版社,2007
[12]ATMEL. 8-bit Microcontroller with 4K Bytes Flash AT89C51.2000
[13]ATMEL.8-bit Microcontroller with 32K Bytes Flash AT89C51RC.2000
附 录
相关的程序代码:
#include
#define uint unsigned int
#define uchar unsigned char
#define v_s 10
#define u_s 49996 //经校准后的50MS 初值; 计算方法如下: sbit wx5=P2^1;
sbit wx6=P2^0;
sbit wx7=P2^2;
sbit LVSE =P3^5; //绿色运行灯
sbit HONGSE =P3^6; //红色停止灯
sbit HUANGSE=P3^7; //黄色调闹钟灯
sbit DQ=P3^0;
uint temp, temp1,temp2, xs;
uchar d[8]; //设置显示变量暂存区
/******延时程序*******/
void delay1(unsigned int m)
{
unsigned int i,j;
for(i=m;i>0;i--)
for(j=110;j>0;j--);
}
void delay2(unsigned int m)
{
while(m--);
}
void Init_DS18B20()
{
unsigned char x=0;
DQ = 1; //DQ复位 ds18b20通信端口
delay2(8); //稍做延时
DQ = 0; //单片机将DQ 拉低
delay2(80); //精确延时大于480us
DQ = 1; //拉高总线
delay2(4);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay2(20);
}
uchar ReadOneChar()
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 高电平拉成低电平时读周期开始
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80; //
delay2(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0; //从高电平拉至低电平时, 写周期的开始
DQ = dat&0x01; //数据的最低位先写入
delay2(5); //60us到120us 延时
DQ = 1;
dat>>=1; //从最低位到最高位传入
}
}
/**************读取ds18b20当前温度************/
void ReadTemperature()
{
unsigned char a=0;
unsigned b=0;
unsigned t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay2(10); // this message is very important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay2(10);
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp1=b
temp1+=(a&0xf0)>>4; //低8位中的高4位值加上高8位中后三位数的值 temp1室温整数值
temp2=a&0x0f; //小数的值
temp=((b*256+a)>>4); //当前采集温度值除16得实际温度值 }
void wenduxianshi() //温度显示
{
d[5]=temp/10;
d[6]=temp%10;
d[7]=13;
}
sbit beep=P1^0; //闹铃音输出端
sbit N1=P1^7; //调整项选择
sbit N2=P1^4; //定闹启动
sbit N3=P1^6; //加1调整
sbit N4=P1^5; //减1调整
uint i,j; //延时函数用变量
uchar z=0,r=0; //按键计数变量
uchar s,a,u,us,ms,hs,HD,LD,TD; //过渡变量
uchar T,b; //加、减键值返回变量
uchar minute,hour,m_m,h_h; //时间变量
uchar count,second=0,n_m=0,n_h=0,q=0; //标志变量
/***不显示小数点的0-9显示段码+黑屏码********************/
//低电平有效
uchar SEG7[14]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0x3f,0xc6};
uchar Wei[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
void delay(uchar p){
for(i=0;i
for(j=0;j
{;}}
}
void Choice_set()
{
if (N1==0)//选择键
{
delay(20);
if(N1==0)
{
r++;
if(r>4){r=0;}
while(!N1);
}
}
}
void Alarm_R()
{
if (N2==0)//选择键
{
delay(20);
if(N2==0)
{
z++;
if(z>1)
{z=0;
}
while(!N2);
}
}
}
uchar Adjustment(b,T)
{
if(N3 == 0)
{
delay(20);
if(N3 == 0)
{ //如果按动上调键
T++; //数字加
if(b==1){if(T>59) {T=0;}}//分钟设定
if(b==0){if(T>23) {T=0;}}//小时设定
while(!N3);
}
}
if(N4 == 0)
{
delay(20);
if(N4 == 0)
{ //如果按动下调键
T--; //数字减
if(b==1){if(T
if(b==0){if(T
while(!N4);
}
}
return(T);
}
void Display()
{
for(a=0;a
{
P0=0xff;
P0=SEG7[d[a]]; //送显示数据并转换成段码显示
P2=Wei[a]; //给相应位数码块送电
delay1(3);
}
}
void zhuan_h(void)
{
if(hour>0&&hour
if(hour>12){h_h=hour%12;}
m_m=minute;
d[0]=h_h/10;
d[1]=h_h%10;
d[3]=m_m/10;
d[4]=m_m%10;
Display();
}
void Normal_t()
{
TR0=1;LVSE=0; HONGSE=1;HUANGSE=1;
if(s==0)d[2]=0x0a; //中间位g 段横杠闪动显示为正常走时状态 else d[2]=0x0b;
zhuan_h();
}
void hh_s(void)
{
TR0=0;LVSE=1; HONGSE=0;HUANGSE=1;
second=0;
hour=Adjustment(0,hour);
d[0]=hour/10;
d[1]=hour%10;
d[2]=0x0c;
d[3]=10;
d[4]=10;
Display();
}
void mm_s(void)
{
TR0=0;LVSE=1; HONGSE=0; HUANGSE=1;
second=0;
minute=Adjustment(1,minute);
d[0]=10;
d[1]=10;
d[2]=0x0c;
d[3]= minute/10;
d[4]=minute%10;
Display();
}
void nh_s(void)
{
TR0=0;LVSE=1; HONGSE=1;HUANGSE=0;
second=0;
n_h=Adjustment(0,n_h);
d[0]=n_h/10;
d[1]=n_h%10;
d[2]=0x0c; //中间位(g 段+点) 闪动显示为正常走时状态
d[3]=10;
d[4]=10;
Display();
}
void nm_s(void)
{
TR0=0;LVSE=1; HONGSE=1; HUANGSE=0;
second=0;
n_m=Adjustment(1,n_m);
d[0]=10;
d[1]=10;
d[2]=0x0c;
d[3]= n_m/10;
d[4]= n_m%10;
Display();
}
void Beep_Sound(void)
{
beep=~beep;
}
void n_s(void)
{
TR0=1;
if(s==0)d[2]=0x0c; //g 和小数点亮
else d[2]=0x0b; //g 和小数熄灭
zhuan_h();
if((hour==n_h) && (minute==n_m))
{Beep_Sound();}
}
/*************************************************** 定时器0中断子函数
12T 芯片,12MHz 晶体, 定时50MS
***************************************************/ void clock_T0(void) interrupt 1
{
TH0=(65536-u_s)/256;
TL0=(65536-u_s)%256;
if(count++==19) //经实测19次中断后定时约1S
{
count=0; //次数归0
s=~s;
second++; //秒标志加1
if(second==60)
{
second=0; //60S后秒标志归0
minute++; //分标志加1
if(minute==60)
{
minute=0; //60分后分标志归0
hour++; //小时标志加1
if(hour==24)
{
hour=0; //12小时后小时标志归0
second--; //辅助校准调整
}
}
}
}
}
/*********主函数***********************************/ main()
{
N1=1;N2=1;N3=1;N4=1;beep=0;
IE=0x8a; //开启总中断允许定时器0/1响应中断
TMOD=0x11; //设置定时器0/1的工作于Mode1模式计数满值65536 TH0=(65536-u_s)/256; //计数器高8位填值
TL0=(65536-u_s)%256; //计数器高8位填值
while(1)
{
ReadTemperature();
wenduxianshi();
Choice_set();
Alarm_R();
if(r==0){Normal_t();} //正常走时状态
if(r==1){nh_s();} //调闹--时
if(r==2){nm_s();} //调闹--分
if(r==3){hh_s();} //调时
if(r==4){mm_s();} //调分
if(z==0&&r==0){Normal_t();TR1=0;} //正常走时闹铃关状态 if(z==1&&r==0){n_s();} //正常走时闹铃开状态
}
}