电子时钟设计1
西安文理学院机械与材料工程学院
课程设计报告
专业班级 13级自动化一班
课 程 微机原理与接口技
题 目 定时闹钟设计
学 号 0803130104
学生姓名 程梁润
指导教师 雷俊红
2016年 11月
西安文理学院机械与材料工程学院
课程设计任务书
学生姓名 程梁润 专业班级 13级自动化1班 学 号 0803130104 指导教师 雷俊红 职 称 讲 师 教研室 自动化
课 程 微机原理与接口技术 题目
定时闹钟设计 任务与要求
设计任务:利用51单片机结合七段LED显示器设计一个简易的定时闹铃时钟,可以放在
宿舍或教室使用,由于用七段LED显示器显示数据,在夜晚或黑暗的场合也可以使用。
可以设置现在的时间及显示闹铃设置时间,若时间到则发出一阵声响。
设计要求:
1.使用6位七段LED显示器来显示现在的时间;
2.显示格式为“时时分分秒秒”;
3.具有4个按键来做功能设置,可以设置现在的时间及显示闹铃设置时间;
4.时间到则发出一阵声响,可通过按键复位;
5.对单片机系统设计的过程进行总结,认真书写课程设计报告并按时上交。
开始日期 2016.10.22 完成日期 2016.11.20
2016年 11月 20日
西安文理学院机械与材料工程学院
自动化专业电子技术课程设计评分表
学生姓名:
题 目: 程梁润 专业班级: 13级自动化1班 定时闹钟设计
学 号: 0803130104
目 录
第一章 设计任务和要求………………………………………4
1.1单片机课程设计内容………………………………………4
1.2单片机课程设计要求………………………………………4
第二章 系统硬件设计…………………………………………5
2.1 系统方框图 ………………………………………………5
2.2 最小系统 …………………………………………………9
2.3 LED显示电路………………………………………………9
2.4 键盘输入电路 ……………………………………………10
2.5 蜂鸣器和LED灯电路 ……………………………………10
第三章 系统软件设计…………………………………………12
3.1 主程序设计流程图…………………………………………12
3.2 按键设置子程序……………………………………………13
3.3 定时器中断子程序…………………………………………15
第四章 仿真电路图与仿真结…………………………………16
第五章 课程设计总结…………………………………………17 参考文献…………………………………………………………18 附录A……………………………………………………………19 附录B……………………………………………………………20
第一章 设计任务和要求
1.1 单片机课程设计内容
利用51单片机结合七段LED显示器设计一个简易的定时闹铃时钟,可以放在宿舍或教室使用,由于用七段LED显示器显示数据,在夜晚或黑暗的场合也可以使用。可以设置现在的时间及显示闹铃设置时间,若时间到则发出一阵声响。
1.2 单片机课程设计要求
1.使用6位七段LED显示器来显示现在的时间;
2.显示格式为“时时分分秒秒”;
3.具有4个按键来做功能设置,可以设置现在的时间及显示闹铃设置时间;
4.时间到则发出一阵声响,可通过按键复位;
5.对单片机系统设计的过程进行总结,认真书写课程设计报告并按时上交。
第二章 系统硬件设计
2.1 系统方框图
图2.1 系统方框图
上图中:
STC89C51单片机简介
经过多种单片机性能的分析及现有实验设备的限制,在本设计中单片机芯片采用了AT89S51单片机芯片。AT89S51是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机片内含4k bytes的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器既可在线编程(ISP)也可用传统方法进行编程既通用8位微处理器于单片机芯片中,ATMEL公司的功能强大,低价位AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
STC89C51是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时钟频率为80MHz,片内含8K Bytes的可反复擦写1000次的Flash只读程序存储器,器件兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。
引脚说明:
Vcc: 电源电压
GND:接地
P0口:P0口是一组8位漏极开路型双向I/O口,即地址/数据总线复用口。作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
图2.2 AT89S51引脚图
P1口:P1口是一个带有内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作为输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。Flash编程和程序校验期间,P1接收低8地址。
P2口:P2口是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作为输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX @DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数
据存储器(例如执行MOVX @Ri指令)时,P2口线上的内容(即特殊功能寄存器(SFR)区中P2寄存器的内容),在整个访问期间不改变。Flash编程和程序校验期间,P2亦接收高位地址和其他控制信号。
P3口:P3口是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”,它们被内部上拉电阻拉高并可作为输入端口。作输入端时,被外部拉低的P3口将用上拉电阻输出电流。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能。
P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号。
表2.1 P3口第二功能
RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。WDT溢出将使该引脚输出高电平,设置SFR AUXR的DISRT0位(地址8EH)可打开或关闭该功能。DIRT0位缺省为RESET输出高电平打开状态。
ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。即使不访问外部存储器,ALE仍以时钟振荡频率的1/6输出固定的正脉冲信号,因此可对外输出时钟或用以定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。对Flash存储器编程期间,该引脚还用于出入编程脉
冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,单片机执行外部程序时,应设置ALE无效。
/PSEN:程序储存允许(/PSEN)输出是外部程序存储器的读选通信号,当AT89S51由外部程序存储器取指令(或数据)使,每个机器周期两次/PSEN有效,即输出两个脉冲。当访问外部数据存储器。没有两次有效的/PSEN信号。
EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接VCC端),CPU则执行内部程序存储器中的指令。Flash存储器编程时,该引脚加上+12V的编程电压VPP。
XTAL1:振荡器反相放大器及内部时钟发生器的输入端。
XTAL2:振荡器反相放大器的输出端。
显示模块:
7段数码管一般由8个发光二极管组成,其中由7个细长的发光二极管组成
数字显示,另外一个圆形的发光二极管显示小数点。
当发光二极管导通时,相应的一个点或一个笔画发光。控制相应的二极管导通,就能显示出各种字符,尽管显示的字符形状有些失真,能显示的数符数量也有限,但其控制简单,使有也方便。发光二极管的阳极连在一起的称为共阳极数码管,阴极连在一起的称为共阴极数码管。
发光二极管(LED是一种由磷化镓(GaP)等半导体材料制成的,能直接将电能转变成光能的发光显示器件。当其内部有一一电流通过时,它就会发光。
7段数码管每段的驱动电流和其他单个LED发光二极管一样,一般为5~10mA;正向电压随发光材料不同表现为1.8~2.5V不等。
7段数码管的显示方法可分为静态显示与动态显示,下面分别介绍。
(1)静态显示
所谓静态显示,就是当显示某一字符时,相应段的发光二极管恒定地寻能可截止。这种显示方法为每一们都需要有一个8位输出口控制。对于51单片机,可以在并行口上扩展多片锁存74LS573作为静态显示器接口。
静态显示器的优点是显示稳定,在发光二极管导通电注一定的情况下显示器的亮度高,控制系统在运行过程中,仅仅在需要更新显示内容时,CPU才执行一次显示更新子程序,这样大大节省了CPU的时间,提高了CPU的工作效率;缺点是位数较多时,所需I/O口太多,
硬件开销太大,因此常采用另外一种显示方式——动态显示。
(2)动态显示
所谓动态显示就是一位一位地轮流点亮各位显示器(扫描),对于显示器的每一位而言,每隔一段时间点亮一次。虽然在同一时刻只有一位显示器在工作(点亮),但利用人眼的视觉暂留效应和发光二极管熄 灭时的余辉效应,看到的却是多个字符“同时”显示。显示器亮度既与点亮时的导通电流有关,也与点亮时间和间隔时间的比例有关。调整电流和时间参烽,可实现亮度较高较稳定的显示。若显示器的位数不大于8位,则控制显示器公共极电位只需一个8位I/O口(称为扫描口或字位口),控制各位LED显示器所显示的字形也需要一个8位口(称为数据口或字形口)。
动态显示器的优点是节省硬件资源,成本较低,但在控制系统运行过程中,要保证显示器正常显示,CPU必须每隔一段时间执行一次显示子程序,这占用了CPU的大量时间,降低了CPU工作效率,同时显示亮度较静态显示器低。
综合以上考虑,由于温度显示为精确到小数点后两位,故只需4个数码管,又考虑到CPU工作效率与电源效率,本毕业设计采用静态显示。为共阳极显示。
2.2 最小系统
复位时单片机的初始化操作,只要给RST引脚加上两个机器周期以上的高电平信号,就可以使STC89C51单片机复位。本次采用的是12M
晶振,按钮复位电路。
图2.3 最小系统仿真电路
2.3 LED显示电路
LED显示的D0到D7与单片机P0口相连,通过滑动变阻器改变LED显示屏的显示。
图2.4 LED显示仿真电路
2.4 键盘输入电路
本次设计采用独立键盘,键盘按下时,相应的I/O口电平由高变低,一次检测按键是否被按下。4个独立按键与单片机P1.0—P1.3口相连。其中K1为“设置时间”键,K2为“增加”键,K3为“减小”键,K4
为“设置闹钟”键。
图2.5 按键仿真电路
2.5 蜂鸣器和LED灯电路
在AT89S51外围的一个管口上加蜂鸣器,通过软件与硬件的结合可实现定时闹钟功能。蜂鸣器的作用为准点报时产生报警声,LED在秒钟为偶数时或者功能键被按下时亮。蜂鸣器与单片机P2.2口相连,LED灯与单片机P2.3口相连。
图2.6 蜂鸣器仿真电路
第三章 系统软件设计
系统的软件设计也是工具系统功能的设计。单片机软件的设计主要包括执行软件(完成各种实质性功能)的设计和监控软件的设计。单片机的软件设计通常要考虑以下几个方面的问题:
(1)根据软件功能要求,将系统软件划分为若干个相对独立的部分,设计出合理的总体结构,使软件开发清晰、简洁和流程合理;
(2)培养良好的编程风格,如考虑结构化程序设计、实行模块化、子程序化。既便于调试、链接,又便于移植和修改;
(3)建立正确的数学模型,通过仿真提高系统的性能,并选取合适的参数;
(4)绘制程序流程图;
(5)为程序加入注释,提高可读性,实施软件工程;
(6)注意软件的抗干扰设计,提高系统的可靠性。
3.1 主程序设计流程图
这次的数字电子钟设计用到很多子程序,它们的流程图如下所示。
主程序是先开始,然后启动定时器,定时器启动后在进行按键检测,检测完后,就可
以显示时间。
图3.1 主程序流程图
3.2 按键设置子程序
按键处理是先检测秒按键是否按下,秒按键如果按下,秒就加1;如果没有按下,就检测分按键是否按下,分按键如果按下,分就加1;如果没有按下,就检测时按键是否按下,时按键如果按下,时就加1;如果没有按下,就把时间显示出来。
图3.2 按键处理流程图
定时器中断时是先检测1秒是否到,1秒如果到,秒单元就加1;如果没到,就检测1分钟是否到,1分钟如果到,分单元就加1;如果没到,就检测1小时是否到,1小时如果到,时单元就加1,如果没到,就显示时间。
图3.3 定时器中断流程图
工作原理 :
数字电子钟是一个将“ 时”,“分”,“秒”显示于人的视觉器官的计时装置。它的计时周期为24小时,显示满刻度为23时59分59秒,另外还有校时功能。因此,一个基本的数字钟电路主要由显示器“时”,“分”,“秒”和单片机,还有校时电路组成。8个数码管的段选接到单片机的P0口,位选接到单片机的P2口。数码管按照数码管动态显示的工
作原理工作,将标准秒信号送入“秒单元”,“秒单元”采用60进制计数器,每累计60秒发出一个“分脉冲”信号,该信号将作为“分单元”的时钟脉冲。“分单元”也采用60进制计数器,每累计60分钟,发出一个“时脉冲”信号,该信号将被送到“时单元”。“时单元”采用24进制计时器,可实现对一天24小时的累计。显示电路将“时”、“分”、“秒”通过七段显示器显示出来。校时电路时用来对“时”、“分”、“秒”的显示数字进行校对调整。
3.3 定时器中断子程序
中断技术在单片系统中有着十分重要的作用,它不仅可以提高单片机CPU的效率,也可以对突发事件处理。所谓中断就是当CPU正在执行程序A时,发生了另一个急需处理的事件B,这是CPU暂停当前执行的程序A,立即转去执行处理事件B的程序,处理完事件B后,再返回到程序A继续执行,这个过程被叫做中断。关于中断的概念有下列几个名词:(1)程序A称为主程序,(2)处理事件B的程序称为中断服务程序,(3)主程序中转向中断服务程序的地方称为断点,(4)引起中断的原因即事件B称为中断源,(5)转去执行中断服务程序称为中断响应。关于中断的概念可以打个如下的比喻。领导(CPU)在自己的房间办公(执行主程序),下属(外设)有问题打电话来请示(中断源),领导停下正在进行的工作,通过电话给下属做指示(执行中断服务程序),指示完后,领导挂断电话,继续做自己的工作(返回主程序继续执行)。
中断是一个过程,当中央处理器CPU在处理某件事情时,外部又发生了另一紧急事件,请求CPU暂停当前的工作而去迅速处理该紧急事件。处理结束后,再回到原来被中断的地方,继续原来的工作。引起中断的原因或发出中断请求的来源,称为中断源。 单片机一般允许有多个中断源,当几个中断源同时向CPU请求中断时,就存在CPU优先响应哪一个中断请求源的问题(优先级问题),一般根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求,于是便规定每一个中断源都有一个中断优先级别,并且CPU总是响应级别最高的中断请求。
当CPU正在处理一个中断源请求的时候,又发生了另一个优先级比它高的中断源请求,如果CPU能够暂时中止对原来中断处理程序的执行,转而去处理优先级更高的中断
源请求,待处理完以后,再继续执行原来的低级中断处理程序,这样的过程称为中断嵌套。
系统源程序见附录B。
第四章 仿真电路图与仿真结果
用Keil和Protues进行仿真调试,仿真结果完全达到预期目的。该电子钟的功能虽少,但是程序也比较为复杂,所以在编写程序和调试程序时出现了相对较多的问题。最后,鉴于以前学过的单片机知识,一步一步的完成各个子程序,终于得到了最后的程序。解决了软件问题。在写中断程序和显示程序时遇到了很多的问题,如调试时显示乱码等等。但是经过努力,程序还是成功了。
1.在测试中遇到LED数码管为不显示时,首先要仔细观察电路共阴共阳接法和程序显示部分。
2.LED数码管显示不正常,还有亮度不够,要注意电路是否存在上拉电子。若电路无误后,再查看烧写的程序是否正确,并对程序进行认真修改。
经过了多次的反复测试与分析,可以对电路原理及功能更加熟悉,同时提高了设计能力以及对电路的分析能力,同时在软件的编程方面得到更高的提高,对编程能力也得到了加强,同时对所学的只是得到了很到的提高与巩固。对于初学者来说,更是有更大的益处,能理论联系实际运用,学到更多的知识,真正将这门课程所包含的知识用于实际生活中的具体创造和设计中。
系统仿真总览图、原理图见附录A。
第五章 课程设计总结
通过这次单片机课程设计,发现了自身所学知识存在许多的不足和问题,同时也学到了不少东西,提高了动手能力。
在整个设计过程中,从设计方案的确定,到具体电路的设计,最后到总体电路的联接构建以及程序的编写,整个设计工程量的比较大的,单靠个人能力,很多方面考虑不周,有的地方甚至毫无头绪,想不出具体方案,因此,绝对不能心急,不明白的地方和其他的同学讨教,毕竟群策力办法要多些,让自己也多个机会,碰上是在不能解决的问题,就去找辅导老师,用过老师的指点,把问题彻底搞清楚并加以掌握。另外,在这次的设计过程中,我还查阅了很多相关设计的资料,通过参考和研究别人的一些设计,使得自己的设计思路更加清晰和周密,从而使设计出来的产品也更加完善和高质量。
尽管这次设计中遇到了很多问题,但是也都一一得以解决,比如软件设计时,遇到了很多问题,但是经过向同学讨教及想老师询问,静下心来思考,慢慢就理清了思路。通过这次设计,也使我知道了无论做任何事情,都要有一颗平常心,不要急着想要成功、走捷径,要一步一个脚印,把每一部都认认真真的做好来,才能取得最后的成功,同时也练就了我的耐心,做什么事情都要有耐心,不要遇到困难就退缩,而是要静下心来去寻找解决的方法,否则很难有最后的成功。在此过程中,充分发挥人的主观能动性,自主学习,学到了很多没有学到过的知识,另一方面,碰到问题注意与同学和老师写作、讨论、寻求解决的方案,最终完成作品,达到预期的目的。虽然这次设计的课题有些简单,但是要真的做进去还是有一定的困难的,但是经过自己的努力,得出最后的作品,我个人还是蛮有成就感的,更重要的是学到了平时没有学到的知识。因此,我自己觉得这次的课程设计对我而言算的上是一次全新的尝试,也是一个小小的成功,更是一次很好的锻炼,让我有了全方位的提高和进步。
参考文献
[1]《微机原理及单片机应用技术》 西安电子科技大学出版社
[2]《C语言程序设计教程》 人民邮电出版社
[3]佚名。单片机电子数字钟论文,豆丁网文档在线
[4] 张永枫。《单片机应用实训教程》,西安电子科技大学出版社
[5]AT89S51中文资料,电子驿站。
[6] 严天峰。《单片机应用系统设计与仿真调试》,北京航空航天大学出版社
[7] 佚名。毕业论文基于AT89S51单片机的数字时钟,豆丁网文档在线
附录A
系统仿真总览图
系统仿真总览图
原理图
附录B 系统源程序
#include //头文件
#define uchar unsigned char //宏定义
#define uint unsigned int//宏定义
//数码管位端口定义
sbit w1=P2^2;
sbit w2=P2^3;
sbit w3=P2^4;
sbit w4=P2^5;
sbit w5=P2^6;
sbit w6=P2^7;
////////按键/////////////////////
sbit key1=P3^4;//设置时间
sbit key2=P3^5;//加
sbit key3=P3^6;//减
sbit key4=P3^7;//闹钟
sbit beep=P1^0;//蜂鸣器
/////共阴数码管段信号编码////////
uchar code table[10]=//0---9
{0xFC,0x60,0xDA,0xF2,0x66,
0xB6,0xBE,0xE0,0xFE,0xF6};//
uchar num,miao,fen,shi;//计时 时分秒变量
uchar fen1,shi1;//闹钟变量
uchar d1,d2,d3,d4,d5,d6;//显示拆分数据
void delay(uint ms)//1ms 延时函数 数据保持用的
{
uchar x;
for(ms;ms>0;ms--)
for(x=110;x>0;x--);
}
void display()//显示函数
{
d1=shi/10;//小时
d2=shi%10;//
d3=fen/10;//
d4=fen%10;//分钟
d5=miao/10;//
d6=miao%10;//秒
w1=0;P0=table[d1];delay(10);//第1位显示数据
P0=0x00;w1=1;//关闭显示消除动态扫描阴影
w2=0;P0=table[d2]|0x01;delay(10);//第2位显示数据
P0=0x00;w2=1;//关闭显示消除动态扫描阴影
w3=0;P0=table[d3];delay(10);//第3位显示数据
P0=0x00;w3=1;//关闭显示消除动态扫描阴影
w4=0;P0=table[d4]|0x01;delay(10);//第4位显示数据
P0=0x00;w4=1;//关闭显示消除动态扫描阴影
w5=0;P0=table[d5];delay(10);//第5位显示数据
P0=0x00;w5=1;//关闭显示消除动态扫描阴影
w6=0;P0=table[d6];delay(10);//第6位显示数据
P0=0x00;w6=1;//关闭显示消除动态扫描阴影
}
void disp_set()//显示函数
{
d1=shi1/10;//小时
d2=shi1%10;//
d3=fen1/10;//
d4=fen1%10;//分钟
w1=0;P0=table[d1];delay(10);//第1位显示数据
P0=0x00;w1=1;//关闭显示消除动态扫描阴影
w2=0;P0=table[d2]|0x01;delay(10);//第2位显示数据
P0=0x00;w2=1;//关闭显示消除动态扫描阴影
w3=0;P0=table[d3];delay(10);//第3位显示数据
P0=0x00;w3=1;//关闭显示消除动态扫描阴影
w4=0;P0=table[d4]|0x01;delay(10);//第4位显示数据
P0=0x00;w4=1;//关闭显示消除动态扫描阴影
w5=0;P0=table[0];delay(10);//第5位显示数据
P0=0x00;w5=1;//关闭显示消除动态扫描阴影
w6=0;P0=table[0];delay(10);//第6位显示数据
P0=0x00;w6=1;//关闭显示消除动态扫描阴影
}
void didi()//滴滴声 设置时间时调用
{
uchar i;
beep=0;for(i=0;i
void didi1()//滴滴声 设置闹钟时调用
{
uchar i; //在括号里调用显示函数也是起到延时作用 音的时候数码管抖动
为了防止下响声
beep=0;for(i=0;i
void keyscan()//调时按键扫描函数
{
uchar k_flag,set_flag;
if(key1==0)//按键按下 一下所有按键执行的模式都是一样的 {
delay(10);//延时消除按键抖动
if(key1==0)//确定按键按下
{
k_flag=1;
didi();//滴滴声
}
while(key1==0)display();//等待按键松手
}
while(k_flag==1)//开始调整小时数据
{
display();
if(key1==0)
{
delay(10);//延时消抖
if(key1==0)
{
k_flag=2;
didi();//滴滴声
}
while(key1==0)display();
}
if(key2==0)
{
delay(10);
if(key2==0)
{
shi++;didi();//滴滴声
if(shi==24)shi=0;
}
while(key2==0)display();
}
if(key3==0)
{
delay(10);
if(key3==0) { if(shi==0)shi=24; shi--;didi();//滴滴声 } while(key3==0)display(); } } while(k_flag==2)//开始调整分钟数据 { display(); if(key1==0) { delay(10);//延时消抖 if(key1==0) { k_flag=3; didi();//滴滴声 } while(key1==0)display(); } if(key2==0) { delay(10); if(key2==0) { fen++;didi();//滴滴声 if(fen==60)fen=0; } while(key2==0)display(); } if(key3==0) { delay(10); if(key3==0) { if(fen==0)fen=60; fen--;didi();//滴滴声 } while(key3==0)display(); } }
while(k_flag==3)//开始调整秒数据
{
display();
if(key1==0)
{
delay(10);//延时消抖
if(key1==0)
{
didi();//滴滴声
didi();//滴滴声
k_flag=0;
}
while(key1==0)display();
}
if(key2==0)
{
delay(10);
if(key2==0)
{
didi();//滴滴声
miao++;
if(miao==60)miao=0;
}
while(key2==0)display();
}
if(key3==0)
{
delay(10);
if(key3==0)
{
didi();//滴滴声
if(miao==0)miao=60;
miao--;
}
while(key3==0)display();
}
}
///////设置定时时间/////////////////////////////////////////////// if(key4==0)
{
delay(10);
if(key4==0)
{ didi1();//滴滴声 set_flag=1; } while(key4==0)disp_set(); } while(set_flag==1) { disp_set(); if(key2==0) { delay(10); if(key2==0) { didi1();//滴滴声 shi1++; if(shi1==24)shi1=0; } while(key2==0)disp_set(); } if(key3==0) { delay(10); if(key3==0) { didi1();//滴滴声 if(shi1==0)shi1=24; shi1--; } while(key3==0)disp_set(); } if(key4==0) { delay(10); if(key4==0) { didi1();//滴滴声 set_flag=2; } while(key4==0)disp_set(); } } while(set_flag==2) { disp_set();
if(key2==0)
{
delay(10);
if(key2==0)
{ didi1();//滴滴声
fen1++;
if(fen1==60)fen1=0;
}
while(key2==0)disp_set();
}
if(key3==0)
{
delay(10);
if(key3==0)
{ didi1();//滴滴声
if(fen1==0)fen1=60;
fen1--;
}
while(key3==0)disp_set();
}
if(key4==0)
{
delay(10);
if(key4==0)
{
didi1();
didi1();//滴滴声
set_flag=0;
}
while(key4==0)disp_set();
}
}
}
void b_s()//报时
{
uchar i;
if((shi>=7)&&(shi
{
if((fen==0)&&(miao
{
beep=0;for(i=0;i
beep=1;for(i=0;i
保持响声
}
}
if((shi1!=0)||(fen1!=0))//都等于0的时候不是闹钟时间
{
if((shi1==shi)&&(fen1==fen)&&(miao
beep=0;for(i=0;i
}
}
void main()
{
TMOD=0x01;//定时器0 16位计时模式
TH0=(65536-50000)/256; //50ms定时
TL0=(65536-50000)%256; //50ms定时
EA=1;//开启总中断
ET0=1;//开启定时器中断
TR0=1;//开启定时器
while(1)
{
display();//显示函数
keyscan();//按键扫描函数
b_s();//报时
}
}
void T0_time() interrupt 1
{
TH0=(65536-50000)/256; //50ms定时
TL0=(65536-50000)%256; //50ms定时
num++;//加一次50ms定时
if(num==20)//1S
{
num=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
}
} shi++; if(shi==24)shi=0; } }