89C51单片机最小系统设计(电子时钟_秒表_按键计数的单片机设计) 2
- 格式:doc
- 大小:910.00 KB
- 文档页数:14
武汉大学电子信息学院电子系统综合设计课程论文基于89C51单片机的数字钟设计专业:年级:作者:指导教师:2012 年6 月5 日目录1 作品的背景与意义.................................... 错误!未定义书签。
2 功能指标设计 (1)3 作品方案设计 (1)3.1总体方案的选择 (1)3.1.1 单片机的型号选择 (1)3.1.2 数码管选择及显示原理 (2)3.1.3 整体功能实现 (2)3.2主控模块89C51 (2)3.3显示方案比较 (2)4 硬件设计 (3)4.1设计思路 (3)4.1.1 电源电路部分 (3)4.1.2 显示部分 (3)4.1.3 键盘部分 (3)4.2 设计内容 (4)4.3 设计要求 (4)4.4 设备及工作环境 (4)4.5 硬件结构及原理图 (4)4.5.1 功能 (4)4.5.2 系统板上硬件连线... . (5)5 软件设计 (6)5.1主程序流程图 (6)5.2显示模块流程图 (7)6 系统测试 (7)6.1测试环境 (8)6.2测试步骤 (8)6.3测试结论 (8)6.2.1 测试数字钟的基本功能 (8)6.2.2 测试数字钟的闹钟功能 (8)6.2.3 测试数字钟的万年历功能 (8)7 实验总结 (8)参考文献 (9)附录1 系统电路图 (10)附录2 系统软件代码 (10)附录3 系统器件清单 (10)1 作品的背景及意义数字钟开始迅速发展起来。
现代的电子时钟是基于单片机的一种计时工具,采用延时程序产生一定的时间中断,用于一秒的定义,通过计数方式进行满六十秒分钟进一,满六十分小时进一,满二十四小时小时清零。
从而达到计时的功能,是人民日常生活不可缺少的工具。
数字式电子钟用集成电路计时时,译码代替机械式传动,用LED 显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时、分、秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。
摘要随着电子技术的发展,电子技术在各个领域的运用也越来越广泛,人对它的认识也逐步加深。
秒表计时器秒表计时器常常用于体育竞赛及各种其他要求有较精确时间的各领域中。
其中启/停开关的使用方法与传统的机械计时器相同,即按一下启/停开关,启动计时器开始计时,再按一下启/停开关计时终止。
而复位开关可以在任何情况下使用,即使在计时过程中,只要按一下复位开关,计时应立即终止,并对计时器清零。
本设计就是利用所学到的电子元器件将脉冲源用数码管显示出来,以制承诺简易的秒表。
以单片机为核心,设计一个秒表,具有计时功能,按键有启动计时、数据清零、停止、时间显示。
采用3个LED数码管显示时间,计时范围设置为0~99.9秒,即精确到0.1秒,用按键控制秒表的“开始”、“暂停”、“复位”,按“开始”按键,开始计时;按“暂停”按键,系统暂停计时;再按“开始”键,系统继续计时;数码管显示当前计时值;按“复位”按键,系统清零。
毕业论文(设计)原创性声明本人所呈交的毕业论文(设计)是我在导师的指导下进行的研究工作及取得的研究成果。
据我所知,除文中已经注明引用的内容外,本论文(设计)不包含其他个人已经发表或撰写过的研究成果。
对本论文(设计)的研究做出重要贡献的个人和集体,均已在文中作了明确说明并表示谢意。
作者签名:日期:毕业论文(设计)授权使用说明本论文(设计)作者完全了解**学院有关保留、使用毕业论文(设计)的规定,学校有权保留论文(设计)并向相关部门送交论文(设计)的电子版和纸质版。
有权将论文(设计)用于非赢利目的的少量复制并允许论文(设计)进入学校图书馆被查阅。
学校可以公布论文(设计)的全部或部分内容。
保密的论文(设计)在解密后适用本规定。
作者签名:指导教师签名:日期:日期:注意事项1.设计(论文)的内容包括:1)封面(按教务处制定的标准封面格式制作)2)原创性声明3)中文摘要(300字左右)、关键词4)外文摘要、关键词5)目次页(附件不统一编入)6)论文主体部分:引言(或绪论)、正文、结论7)参考文献8)致谢9)附录(对论文支持必要时)2.论文字数要求:理工类设计(论文)正文字数不少于1万字(不包括图纸、程序清单等),文科类论文正文字数不少于1.2万字。
单片机系统课程设计成绩评定表设计课题基于89C51的数字电子时钟设计学院名称:电气工程学院专业班级:学生姓名:学号:指导教师:设计地点:设计时间:单片机系统课程设计课程设计名称:基于89C51的数字电子时钟设计专业班级:学生姓名:学号:指导教师:课程设计地点:课程设计时间:2014-01-01~2015-01-12单片机系统课程设计任务书目录1 引言 (5)2 设计目的 (5)3 系统方案与总体结构设计 (5)3.1系统方案设计 (5)3.2数字时钟框图设计 (6)4数字时钟的硬件构成 (8)4.1 选用芯片简介 (8)4.2 LED数码显示器简介 (12)5各个模块工作原理及原理图 (12)5.1计时模块 (13)5.2数字时钟控制模块 (13)5.3振荡模块 (14)5.4显示模块 (14)6系统软件设计 (15)6.1软件设计的要点 (15)6.2 AT89C51内部定时器/计数器0的使用方法 (15)6.3 程序设计流程图 (16)7系统调试与总结 (17)7.1电路调试 (17)7.2软件调试 (17)8结论与心得 (18)附录A系统原理图 (18)附录B 源程序 (20)参考文献 (26)1 引言数字时钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,无机械装置,具有更长的使用寿命。
数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字时钟的精度,远远超过老式钟表,使其得到了广泛的使用。
该课程设计为数字电子钟的设计。
以AT89C51为核心,配合8位7段共阴极LED数码管显示实时数据,按键可以进行数据调整,为用户提供长期、连续、可靠、稳定的工作环境。
该数字电子钟有时分秒显示功能以及时间的调整的功能。
系统软件设计主要实现参数设置、串行口数据接收、指令发送以及数据的显示和存储,并且实现键盘、液晶显示器等各模块的功能,采用汇编语言编程。
关键词:数字电子钟单片机汇编语言2 设计目的深化和扩充在单片机原理及相关课程方面的基本知识、基本理论和基本技能熟悉设计过程,了解设计步骤,掌握设计内容,培养设计电路、实现软件编程和编写设计说明书能力的目的,为今后从事相关方面的实际工作打下良好基础。
AT89C51单片机电子时钟的设计1.硬件设计首先,我们需要选择合适的外设硬件进行设计。
以下是一些常见的硬件组件:-AT89C51单片机-蜂鸣器-DS1302时钟模块-按键开关和对应的电阻液晶模块的连接方式如下:-VSS->GND-VDD->VCC-V0->电位器-RS->P0.7-R/W->P0.6-E->P0.5-DB0-DB7->P2.0-P2.7蜂鸣器的连接方式如下:-正极->P3.0-负极->GNDDS1302时钟模块的连接方式如下:-VCC->VCC-GND->GND-CE->P1.7-IO->P1.6-SCLK->P1.5按键开关的连接方式如下:-第一个按键->P3.1-第二个按键->P3.2-第三个按键->P3.32.软件设计在软件设计方面,我们将使用C语言编程来编写程序。
首先,我们需要定义和初始化必要的变量,例如小时、分钟和秒钟等计时变量。
然后,我们需要编写一个初始化函数来配置单片机的各种外设和寄存器。
在这个函数中,我们需要设置计时器/计数器、I/O口和中断等。
接下来,我们需要编写一个定时器中断函数,来更新计时变量并实现计时功能。
我们可以使用定时器中断来定期更新秒钟,并在需要时更新小时和分钟。
在主循环中,我们需要编写代码来控制液晶模块、蜂鸣器和按键开关等外设。
通过液晶模块,我们可以实现显示时间的功能。
通过蜂鸣器,我们可以实现头每秒发出一次滴答声的功能。
通过按键开关,我们可以实现设置时间的功能。
3.程序实现以下是AT89C51单片机电子时钟的程序框架:```c#include <reg51.h>#include <intrins.h>//定义和初始化计时变量unsigned char second = 0;unsigned char minute = 0;unsigned char hour = 0;//初始化函数void ini//配置计时器/计数器,设置定时器中断//配置I/O口和中断等//...//定时器中断函数//更新计时变量//...//主函数void mai//初始化init(;//主循环while (1)//控制液晶模块//控制蜂鸣器//控制按键开关//...}```在具体的代码实现中,我们需要根据液晶模块、蜂鸣器和按键开关等外设的具体规格和功能来编写相应的代码。
单片机课程设计报告单片机秒表系统课程设计班级:课程名称:秒表设计成员:实训地点:北校机房实训时间:6月4日至6月15日目录1课程设计的目的和任务1.1 单片机秒表课程设计的概述1.2课程设计思路及描述1.3 课程设计任务和要求2硬件与软件的设计流程2.1系统硬件方案设计2.2所需元器件3 程序编写流程及课程设计效果3.1源程序及注释3.2原理图分析3.3课程设计效果4 心得体会1. 课程设计的目的和任务1.1单片机秒表课程设计的概述一、课程设计题目秒表系统设计——用STC89C51设计一个4位LED数码显示“秒表”,显示时间为000.0~9分59.9秒,每10毫秒自动加一,每1000毫秒自动加一秒。
二、增加功能增加一个“复位”按键(即清零),一个“暂停”和“开始”按键。
三、课程设计的难点单片机电子秒表需要解决几个主要问题,一是有关单片机定时器的使用;二是如何实现LED的动态扫描显示;三是如何对键盘输入进行编程;四是如何进行安装调试。
四、课程设计内容提要本课程利用单片机的定时器/计数器定时和记数的原理,结合集成电路芯片8051、LED数码管以及课程箱上的按键来设计计时器。
将软、硬件有机地结合起来,使得系统能够正确地进行计时,数码管能够正确地显示时间。
其中本课程设计有三个开关按键:其中key1按键按下去时开始计时,即秒表开始键,key2按键按下去时数码管清零,复位为“00.00”. key3按键按下去时数码管暂停。
五、课程设计的意义1)通过本次课程设计加深对单片机课程的全面认识复习和掌握,对单片机课程的应用进一步的了解。
2)掌握定时器、外部中断的设置和编程原理。
3)通过此次课程设计能够将单片机软硬件结合起来,对程序进行编辑,校验。
4)该课程通过单片机的定时器/计数器定时和计数原理,设计简单的计时器系统,拥有正确的计时、暂停、清零,并同时可以用数码管显示,在现实生活中应用广泛,具有现实意义1.2课程设计思路及描述该课程设计要求进行计时并在数码管上显示时间,则可利用MCS-51系列单片机的芯片AT89C51的P3.2,P3.3,RST作为按键的入口;定时器T1作为每0.1秒加一的定时器。
HEBEINONGJI摘要:秒表是一种常用的测时仪器,数字秒表是一种准确度比较高的计时仪器。
数字秒表在现代社会生活的各个领域里应用越来越多,如文体比赛、各种活动计时等。
本文主要研究如何用AT89C51单片机控制一块2片的七段数码管,数码管自动显示从00~99,然后反复循环,也可以99~00进行倒计时。
用C语言在Keil软件上编制程序代码,用Proteus软件对系统进行仿真。
关键词:七段数码管;AT89C51;C语言程序基于AT89C51单片雌制的数字秒表的设计苏州健雄职业技术学院赵素玲1控制要求使用AT89C51单片机控制一个2片的七段数码管,循环从00〜99进行自动显示。
在此时间是可以根据要求进行调整的,并不一定是间隔时间为1秒。
程序中延时子函数的延时时间的改变很容易就能进行时间长短的调整。
该程序还很容易实现从99〜00的倒计时,这种功能可以通过按钮开关的选择来实现,但是加上了按钮程序,程序就变得更复杂、更长。
由于篇幅限制在本文中没有使用按钮程序,所以倒计时的程序是单独给出的。
系统的具体要求有以下四点:(1)以AT89C51芯片为核心控制器,加上外围辅助电路,设计出系统仿真电路图;(2)根据要求用Keil软件编写出C语言程序代码;(3)用一个2位的七段数码管自动的从00-99正计时循环显示;(4)用一个2位的七段数码管自动的从99-00倒计时循环显示。
2系统硬件电路设计2.1系统仿真电路图设计图1电路仿真图系统仿真电路图主要由AT89C51单片机芯片、电源、地、石英晶体振荡电路、复位电路、两片七段共阴极数码管组成。
两个电容C2、C3(30PF)与Xl(石英晶体)组成了石英晶体振荡电路。
电阻R1(1K)、电容C1(22UF)构成复位电路。
P1口控制2位七段数码管,P1口输出字形码,由于P1口作为输出口必须接上拉电阻。
若是选用其他的三个口作为输出口则不需要接上拉电阻,这是由AT89C51单片机自身的特点决定的。
目录第一章电子时钟的总体设计 (3)1.1 设计目的 (3)1.1.1 课程设计 (3)1.1.2 AT89C51芯片的串口功能 (3)1.1.3用keil软件进行编程与调试 (3)1.2 设计任务 (3)1.3 设计思路 (4)第二章硬件系统的设计 (5)2.1 电路原理图设计 (5)2.1.1 电子钟的硬件电路框图 (5)2.2 AT89C51引脚及其功能 (5)2.2.1 AT89C51的原理及说明 (5)2.2.2 引脚功能 (6)2.3 驱动部件 (7)2.4 显示部分 (8)第三章软件系统的设计 (9)3.1 电子钟的主程序 (10)3.2 电子钟的显示子序 (11)3.3 定时器中断服务程序 (12)3.4 电子时钟设计程序清单 (14)3.5 程序进行编译仿真 (18)3.5.1 89C51程序 (18)3.5.2 用PROTEUS ISIS进行电子万年历的仿真测试 (19)第四章对89C51设计的电子时钟的总结 (21)参考文献 (22)摘要本次实训是基于AT89C51单片机电子钟的设计,对时、分、秒的显示的控制,时、分、秒用六位数码管显示LED数码管时钟电路采用24小时计时方式。
该电路采用AT89C51单片机,使用5V电池供电,只使用一个按键进行复位状态的控制以及正常显示等状态。
LED 显示采用静态扫描方式实现,采用6M晶振。
最常见的电子钟通常使用单片机模块控制,一种用单片机原理实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有硬件成本低、计时准确、更长的使用寿命特点,因此得到了广泛的使用。
本次设计通过用单片机为主控制,通过电路仿真而实现。
首先使用Proteus Professional软件进行绘制硬件电路图,用keil软件进行编程与调试,最终生成hex文件,传入单片机内部,从而实现仿真效果。
第一章电子时钟的总体设计1.1 设计目的1.1.1 课程设计使我们能够深入理解单片机系统的工作原理接口电路的设计及调试方法,培养综合运用所学理论知识分析和解决实际问题的能力。
一、电子时钟、秒表与计数器得设计1、实现得功能:1)有key0,key1两个功能按键,复位后,数码管会默认显示时钟模式HH、MM。
(HH表示小时,MM表示分钟),key0短按一次就进入到了秒表模式,数码管显示格式S、SS、S,(分别表示百秒,秒,毫秒)key0再短按一次就进入到了计数器模式,数码管显示格式CCCC(分别为千位百位十位个位)。
key0再短按一次,又进入到了时钟显示模式,就这样由key0控制模式得转换。
2)有RST复位键,本身电路设计有上电自动复位功能,按下RST后,电路复位。
3)有ckey0,ckey1两个计数按键,按下ckey0,计数加一,按下ckey1,计数减一。
4) 电子时钟与秒表时间计时方法就是采用89S52内部计时器0得一种工作方式(详见后面得代码分析),通过计时器0中断来控制时间得运行.5)计数器就是采用外部中断0与外部中断1这两个外部中断实现加1与减1得操作.(1)电子时钟模式:(以下“长按”表示按下按键得时间大于1秒,“短按”表示按下得时间小于0、7 秒)1)长按key1一次,会进入到调整分钟得模式,短按key1一次,分钟会加一。
第二次长按key1,会进入到调整小时得模式,短按key1一次,小时加一.第三次长按key1,重新回到时钟显示模式,这时再短按key1,时间不会变化2)长按key0一次,会进入到显示秒得模式(2)秒表模式:1)由key0控制进入秒表模式后,短按key1一次,秒表计时开始,再短按key1一次计时结束2)长按key1一次,秒表清零(3)计数器模式1)按ckey0一下,计数加一,数码管相应得显示得数值加一,按ckey1一下,计数减一,数码管相应得显示得数值减一,由于数码管得位数限制,最大只能显示到9999,此时按下ckey0无反应;考虑到实际计数功能,没有设置负数,所以最小显示0000,这时按下ckey1,无反应。
2)长按key1一次计数器清零。
2、电路原理图(1)使用片内振荡器(2)具有上电复位与手动复位两个功能(3)key0,key1分别接P1、0与P1、1引脚(4)由P0、0~P0、7输出到七段数码显示管(5)由P2、0~P2、3接三极管,驱动共阳七段数码显示管(6) ckey0,ckey1接P3、2与P3、3两个引脚,为两个外部中断4.电路焊接实物图(1)正面(2)反面:由于显影、腐蚀过程做得不好,导致电路板过度腐蚀,但就是经过修改之后,电路可以正常运行,并无大碍,只就是不美观。
课程设计2:设计一个数字时钟。
要求如下:1.利用51开发板上LED数码管,LED灯,按键等设备,设计一个电子时钟。
2.电子钟使用4位数码管显示小时(24小时制)和分钟,秒可以使用LED灯或其他形式表现。
3.具有设置时钟功能,设置时间时,时间停止计时。
需要设置的位置数码管处于闪烁状态,如你想设置小时的数值时,显示小时的数码管需要处于闪烁状态,而显示分钟的数码管不可以处于闪烁状态,应处于正常显示状态。
4.按键可以选择独立键盘或矩阵键盘。
5.其他扩展功能(选做,能力强的可以做):如闹钟,时制切换等。
一.key.c#include "reg52.h"#include "key.h"extern unsigned char min_flag ;//标志位,控制分数码管闪烁extern unsigned char hour_flag ;//标志位,控制时数码管闪烁extern unsigned char shi ;extern unsigned char fen ;unsigned char key_flag = 0;//标志位,有按键被按下unsigned char key_con = 0;//控制位,控制按键(K1)被按下/*独立按键P12连接到51单片机P1端口k1对应的端口为P1.3k2对应的端口为P1.2k3对应的端口为P1.1k4对应的端口为P1.0*/code unsigned char arr[]={0xf7,0xfb,0xfd,0xfe};unsigned char read_key(unsigned char key){unsigned char i;for(i=0;i<8;i++){if(!(key & 1)){return i+1;}key>>=1; //key = key >> 1 ;}return 0;}void key_scan2(void){unsigned char temp;//键盘扫描temp = key4_scan();if(temp){if(!key_flag){if(temp==4)//K1被按下{key_con++;if(key_con==1) //第一次按下调整小时的数值{hour_flag=1;min_flag =0;}else if(key_con==2) //第二次按下调整分的数值{hour_flag=0;min_flag =1;}else //第三次按下取消调整{hour_flag=0;min_flag =0;key_con = 0;}}if(temp == 3) //增加数值{if(hour_flag){shi++;if(shi>23){shi = 0;}}else if(min_flag){fen++;if(fen>59){fen = 0;}}}if(temp == 2) //减少数值{if(hour_flag){shi--;if(shi>250){shi = 23;}}else if(min_flag){fen--;if(fen>250) //非负数,减的时候不会小于0{fen=59;}}}}key_flag = 1;}else{key_flag = 0;}}/*扫描独立键盘,输入参数:无返回值:有键按下时:返回对应的数字没有按键:返回0*/unsigned char key4_scan(void){unsigned char temp;P1 = 0xf;if(P1 != 0xf)//有按键被按下{temp = P1 & 0xf;//1110return read_key(temp);}return 0;}unsigned char sub_key_scan(unsigned char key) {unsigned char temp;P1 = key; //判断第一行temp = P1 >> 4;if(temp != 0xf){return read_key(temp);}return 0;}/*矩阵键盘硬件连接:P13连接到51单片机P1端口P1.0对应P13的1脚P1.1对应P13的2脚P1.2对应P13的3脚……P1.7对应P13的8脚输入参数:无返回值:有键按下时:返回对应的数字没有按键:返回0*/unsigned char key16_scan(void){unsigned char temp;unsigned char i=0;P1 = 0xf0;if(P1 != 0xf0)//有按键被按下{for(i=0;i<4;i++)//用函数扫描4行{temp = sub_key_scan(arr[i]);if(temp){return temp+(i*4);}}}return 0;}二.Key.h#ifndef KEY_H#define KEY_Hunsigned char key4_scan(void); unsigned char key16_scan(void);void key_scan2(void);#endif三.Led_reg.c#include "reg52.h"/*P2连接位码,P2.0连接Q4B,P2.1连接Q3B,P2.2连接Q2B,P2.3连接Q1B P0端口连接段码,P0.0连接A,。
一、电子时钟、秒表和计数器的设计1、实现的功能:1)有key0,key1两个功能按键,复位后,数码管会默认显示时钟模式HH.MM 。
(HH表示小时,MM表示分钟),key0短按一次就进入到了秒表模式,数码管显示格式S.SS.S,(分别表示百秒,秒,毫秒)key0再短按一次就进入到了计数器模式,数码管显示格式CCCC(分别为千位百位十位个位)。
key0再短按一次,又进入到了时钟显示模式,就这样由key0控制模式的转换。
2)有RST复位键,本身电路设计有上电自动复位功能,按下RST后,电路复位。
3)有ckey0,ckey1 两个计数按键,按下ckey0,计数加一,按下ckey1,计数减一。
4) 电子时钟和秒表时间计时方法是采用89S52内部计时器0的一种工作方式(详见后面的代码分析),通过计时器0中断来控制时间的运行。
5)计数器是采用外部中断0和外部中断1这两个外部中断实现加1和减1的操作。
(1)电子时钟模式:(以下“长按”表示按下按键的时间大于1秒,“短按”表示按下的时间小于0.7 秒)1)长按key1一次,会进入到调整分钟的模式,短按key1一次,分钟会加一。
第二次长按key1,会进入到调整小时的模式,短按key1一次,小时加一。
第三次长按key1,重新回到时钟显示模式,这时再短按key1,时间不会变化2)长按key0一次,会进入到显示秒的模式(2)秒表模式:1)由key0控制进入秒表模式后,短按key1一次,秒表计时开始,再短按key1一次计时结束2)长按key1一次,秒表清零(3)计数器模式1)按ckey0一下,计数加一,数码管相应的显示的数值加一,按ckey1一下,计数减一,数码管相应的显示的数值减一,由于数码管的位数限制,最大只能显示到9999,此时按下ckey0无反应;考虑到实际计数功能,没有设置负数,所以最小显示0000,这时按下ckey1 ,无反应。
2)长按key1一次计数器清零。
2、电路原理图(1)使用片内振荡器(2)具有上电复位和手动复位两个功能(3)key0,key1分别接P1.0和P1.1引脚(4)由P0.0~P0.7输出到七段数码显示管(5)由P2.0~P2.3接三极管,驱动共阳七段数码显示管(6) ckey0,ckey1接P3.2和P3.3两个引脚,为两个外部中断4.电路焊接实物图(1)正面(2)反面:由于显影、腐蚀过程做得不好,导致电路板过度腐蚀,但是经过修改之后,电路可以正常运行,并无大碍,只是不美观。
(4)电路板工作时。
此时为显示时钟的秒显示时钟显示秒表显示计数器5、程序设计分析(1)程序代码#include<Reg51.h>sbit key0=P1^0;sbit key1=P1^1; //定义key0,key1接口unsigned char flag,con,mcount; //flag为计数到一秒时给时钟发的信号unsigned char count = 0;unsigned char seccount =0; //作为时钟的秒的计量单位unsigned char hour = 0; //时钟的时unsigned char min = 0; //时钟的分unsigned char sec = 0; //时钟的秒unsigned char keypress0,keypress1,mode,ms,s,ss,start;unsigned charDisplaynum[]={0x14,0xd7,0x4c,0x45,0x87,0x25,0x24,0x57,0x04,0x05, 0x10,0xd3,0x48,0x41,0x83,0x21,0x20,0x53,0x00,0x01,0xff,0xfb};//数码管十六进制译码表unsigned char controlnum[]={0x08,0x04,0x02,0x01}; //控制四个数码管显示unsigned char DisplayBuff[]={0x00, 0x00, 0x00, 0x00}; //每个数码管的值void display_state(); //数码管显示子程序void keyscan(); //键盘扫描子程序void timer(); //秒表子程序unsigned char count1,flag1,t_adjust=0,tm_adjust=0;unsigned charbKey0Pressed = 0, bKey1Pressed = 0;unsigned char ucStatus = 0;void main(){TMOD = 0x01; //定时器0工作在模式1,GATE=0,C/t=0,16位模TH0= (2^16-5000)/256;//定时器0 预存值,TL0= (2^16-5000)%256;TR0= 1; //定时器0 启动ET0= 1; //定时器中断0 允许EA= 1; //开中断IT0=1; //外部中断0下降沿触发IT1=1; //外部中断1 下降沿触发EX0=1; //外部中断0允许EX1=1; //外部中断1允许PX1=1; //外部中断1 为高优先级中断while(1) //死循环,{if(flag == 1) //时钟显示{flag = 0;sec++;if(sec ==60){sec = 0;min++;if(min ==60){min = 0;hour ++;if(hour == 24){hour = 0;}}}}display_state();keyscan();timer();}}//////////////////////////////////ISR中断服务程序,每5ms产生一个定时器0 中断void Display() interrupt 1{TH0 = (2^16-5000)/256;TL0 = (2^16-5000)%256;seccount ++;mcount ++;keypress0++;keypress1++;P2=0x00; //P2口先清零P0 = Displaynum[DisplayBuff[count]]; //P0口输出P2 = controlnum[count]; //P2口输出count++;if(count==4)count=0;if(seccount == 200) //200*5ms=1s{ seccount =0;flag =1; //每过1秒给时钟信号加一秒}}///////////////////////////////////////////void display_state(){if(mode == 0) //时钟模式,显示时间{DisplayBuff[0] = hour/10;DisplayBuff[1] = (hour%10)+10; //“+10”是为了显示加点的数字DisplayBuff[2] = min/10;DisplayBuff[3] = min%10;}if(mode == 1) //秒表模式,显示秒表{DisplayBuff[0] = ss +10; //“+10”是为了显示加点的数字DisplayBuff[1] = s/10;DisplayBuff[2] = (s%10)+10;DisplayBuff[3] = ms;}if(mode == 2) // 计数器模式,显示计数{DisplayBuff[0] = count1/1000; //千位DisplayBuff[1] = (count1-(count1/1000)*1000)/100; //百位DisplayBuff[2] = (count1-(count1/100)*100)/10; //十位DisplayBuff[3] = count1%10; //个位}if(mode==3) //显示时钟的秒,{DisplayBuff[0] = 20; //第一位不显示DisplayBuff[1] = 21; //第二位显示一个点DisplayBuff[2] = sec/10;//显示秒的十位DisplayBuff[3] = sec%10;//显示秒的个位}}//**************////键盘扫描子程序////**************//void keyscan(){if(!key0 && bKey0Pressed == 0) //检测到key0按下{keypress0 = 0;bKey0Pressed = 1; //防止重入此判断while(!key0); //如果没放开,就等下去}if(key0 && bKey0Pressed == 1) //检测到key0放开{bKey0Pressed = 0; //防止重入此判断if (keypress0<120) //如果是短按{if(ucStatus == 0x02){ucStatus = 0x00;mode = 0; //时钟模式t_adjust=0;}else if(ucStatus == 0x00){ucStatus = 0x01;mode = 1; //秒表模式}else if(ucStatus == 0x01){ucStatus = 0x02;mode = 2; //计数模式}}else if(keypress0>200) //如果是长按mode=3; //显示时钟的秒的模式}////////////////////////////////if(mode == 0) //进入时钟模式后{if(!key1 && (bKey1Pressed == 0)){ keypress1 = 0;bKey1Pressed = 1;while(!key1);}if(key1 && (bKey1Pressed == 1)){bKey1Pressed = 0;if(keypress1 >= 200) //如果是长按{t_adjust++;if(t_adjust==3)t_adjust=0;}else if(keypress1 < 120) 如果是短按switch (t_adjust){case 1:{ //调整分min++;sec = 0;if(min == 60)min = 0;}break;case 2: { //调整时hour ++ ;sec = 0;if(hour == 24)hour = 0;}break;default:break;}}}else if(mode == 1) //进入秒表模式{if(!key1 && bKey1Pressed == 0){keypress1 = 0;bKey1Pressed = 1;while(!key1);}if(key1 && bKey1Pressed == 1){bKey1Pressed = 0;if(keypress1 < 120) //短按{if(flag1==0) { start=2;flag1=1;} //start=2代表秒表开始计时else {start=0;flag1=0;} //start=0,秒表停止计时}else if(keypress1>200) //长按start=1; //秒表清零}}}void timer() //秒表子程序{if(mode==1) //进入秒表模式才执行{if(start==1) //清零{ms = 0;s = 0;ss = 0;mcount=0;}if(start==2) //秒表开始计时{if(mcount==20) //20*5ms=0.1s{mcount=0;ms++;if(ms == 10) // 10*0.1s=1s,s++{ms = 0;s ++;if(s == 100) //100s{s = 0;ss ++;if(ss == 10){ss = 0;s = 0;ms = 0;}}}}}if(start==0);//秒表停止}}//////////////////////void it0(void) interrupt 0 using 1 //外部中断0 服务程序{if(mode==2) //只有在计数模式才执行{count1++; //每响应一次,计数加一if(count1==10000) //超出四位时,不能再加count1 =9999;}}void it2(void) interrupt 2 using 2 //外部中断0 服务程序{if(mode==2) //只有在计数模式才执行{if(count1!=0){count1--;} //计数减一,不显示负数,当减到零时便不能再减 }}。