基于AT89C2051六位数字钟11

更新时间:2023-10-07 15:01:02 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

毕业设计(论文)说明书

题 目: AT89C2051六位数字钟 学 院 广州市机电高级技工 专 业: 机电一体化 年 级: 10机电高职2 学 号: 11 设计人: 黄天伟 指导教师: 年 月:

1

目 录

1 引言 ··································· 1 2 数字钟的系统概述 ····························· 1

2.1 总体方案设计 ·············································································································· 2 3 AT89C2051单片机及其引脚说明 ······················· 3

3.1 内部结构 ····················································································································· 4

3.2 程序保密 ····················································································································· 4 3.3 软硬件的开发 ·············································································································· 4 3.4 引脚说明 ····················································································································· 4 3.5 主要性能 ····················································································································· 5 4 电路的硬件设计 ······························ 6

4.1 复位电路 ····················································································································· 6 4.2 时钟电路 ····················································································································· 6 4.3 按键电路 ······················································································································ 7 4.4 迅响电路及输入、输出电路 ··························································································· 7 4.5 数码管显示电路 ··········································································································· 9

4.5.1 LED数码管结构及工作原理 ·············································································· 9 4.5.2 显示原理 ············································································································· 9 4.6稳压电路 ······················································································································ 9 5 软件设计 ································ 10

5.1 主程序系统结构 ··········································································································· 9 5.2 软件任务分析 ··············································································································· 9 5.3 软件流程图··················································································································· 9 6安装与调试 ······························· 10

6.1 安装、焊接到电路板上 ····························································································· 10 6.2 测试与调试················································································································· 11 7 结束语 ································· 18 参考文献 ································· 18

2

致谢 ··································· 19 附录 1 ·································· 19 附录 2 ·································· 19

基于

AT89C2051六位数字钟

摘要:本设计论文介绍了用AT89C2051单片机控制的数字钟的硬件结构与软件设计。此数字钟是一个将“时”、“分”、“秒”显示于人的视觉器官的计时装置。它的计时周期为24小时,显示满刻度为23时59分59秒,另外应有校时功能。电路由时钟脉冲发生器、时钟计数器、译码驱动电路和数字显示电路以及时间调整电路组成。用晶体振荡器产生时间标准信号,这里采用石英晶体振荡器。根据60秒为1分、60分为1小时、24小时为1天的计数周期,分别组成两个60进制(秒、分)、一个24进制(时)的计数器。构成秒、分、时的计数,实现计时的功能。显示器件选用LED七段数码管。在译码显示电路输出的驱动下,显示出清晰、直观的数字符号。针对数字钟会产生走时误差的现象,在电路中就设计有有校准时间功能的电路。

关键词:单片机,AT89C2051,数字钟,计时

英文摘要

Based on SCM multi-purpose digital clock design

(Institute of Economic and Technological,Anhui Agricultural University, Hefei 230036) Abstract: The paper mainly presents the hardware and software design of the digital clock using AT89C2051. This digital clock is a time-device, which can display \Its time period is 24 hours and the full scale of the display is 23 hours, 59 minutes, 59 seconds and it has the function of time adjustment. The circuit consists of the clock pulse generator, the clock counter, decoding drive circuit, digital display circuit and the time adjustment circuit. It generates time standard signal using crystal oscillator, here is the quartz crystal oscillator. Because 60 seconds is 1 minute, 60 minutes is 1 hour and 24 hours is 1 day, we uses two counters of 60 parts and a counter of 12 part separately to constitute the count of percentage of second, second, minute, and hour. So it can realize time function. Display component selects seven-segment numerical tube LED. Driven by decoding output circuit, it can display showing clear and intuitive figures. Due to walking error of digital clock, we design time calibration circuit in the system.

Key words:Single-chip microcomputer, AT89C2051, Digital clock,Time

3

1 引言

钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、定时启闭电路、定时开关烘箱、通断动力设备,甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。

随着数字集成电路的出现和飞速发展,以及石英晶体振荡器的广泛应用,使得数字钟的精度稳定度远远超过了老式的机械表,用数字电路实现对“时”、“分”、“秒”数字显示的数字钟在数字显示方面,目前已有集成的计数、译码电路,它可以直接驱动数码显示器件,也可以直接采用才COMS--LED光电组合器件,构成模块式石英晶体数字钟。本设计主要是用中、小规模集成电路设计的一台能显示时、分、秒的数字电子钟。是由晶振电路产生1HZ标准信号,分、秒为00--59六十进制计数器,时为00--23二十四进制计数器,可手动校正,且具有整点报时功能。因此,研究数字钟及扩大其应用,有着非常现实的意义。

2 数字钟的系统概述

2.1总体方案设计

数字电子钟是用数字电路实现“时”、“分”、“秒”数字显示的计时装置,主要由振荡器、分频器、计数器、译码显示器、校时电路等部分组成。而数字钟想准确的计时则是由振荡器产生的时脉冲送到分频器,分频电路将时标信号分成每秒一次的方波信号。秒脉冲发生器产生频率稳定很高的秒脉冲,秒脉冲被送到一个六十进制秒计数器计数,将计数结果送至秒个位和十位译码器,译码结果分别由两只七段数码管以十进制数形式显示来。当秒六十进制计数器累计到第59秒时,若再来一个秒脉冲,秒计数器的进位输出就产生进位脉冲(分计数脉冲),同时,秒计数器的十位和个位都复位到零。分计数脉冲又被送到分六十进制计数器计数,经译码电路译码后数码管显示相应的分数。当计满59分59秒时,若再来一个秒脉冲,则分计数器便向时计数器送出时计数脉冲,同时,分、秒计数器均复位到零。时计数器是一个二十四进制计数器,当计数显示23时59分59秒时,若再来一个秒脉冲,则时、分、秒计数器都应回到零,并显示(00:00:00)表示已到达午夜零点,第二天开始继续计数。其主要的功能模块如图2-1所示。

4

图2-1系统结构框图

3 AT89C2051单片机及其引脚说明

AT89C2051是美国ATMEL公司生产的低电压、高性能CMOS 8位单片机,片内含2k bytes的可反复擦写的只读程序存储器(PEROM)和128bytes的随机数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C2051单片机在电子类产品中有广泛的应用。

图3-1 AT89C2051

3.1 内部结构

AT89C2051是一带有2K字节闪速可编程可擦除只读存储器(EEPROM)的低电压,高性能8位CMOS微处理器。它采用ATMEL的高密非易失存储技术制造并和工业标准MCS-51指令集和引脚结构兼容。通过在单块芯片上组合通用的CPLI和闪速存储器,ATMEL的AT89C2051是一强劲的微型处理器,它对许多嵌入式控制应用提供一定高度灵活和成本低的解决办法。

5

AT89C2051提供以下标准功能:2K字节闪速存储器,128字节RAM,15根I/O口,两个16位定时器,一个五向量两级中断结构,一个全双工串行口,一个精密模拟比较器以及两种可选 的软件节电工作方式。空闲方停止CPU工作但允许RAM、定时器/计数器、串行工作口和中断系统继续工作。掉电方式保存RAM内容但振荡器停止工作并禁止有其它部件的工作到下一个硬件复位。 3.2 程序保密

AT89C2051设计有2个程序保密位,保密位1被编程之后,程序存储器不能再被编程除非做一次擦除,保密位2被编程之后,程序不能被读出。 3.3 软硬件的开发

AT89C2051可以采用下面两种方法开发应用系统。

1.由于89C2051内部程序存贮器为Flash,所以修改它内部的程序十分方便快捷,只要配备一个可以编程89C2051的编程器即可。调试人员可以采用程序编辑-编译-固化-插到电路板中试验这样反复循环的方法,对于熟练的MCS-51程序员来说,这种调试方法并不十分困难。但是做这种调试不能够了解片内RAM的内容和程序的走向等有关信息。

2.将普通8031/80C31仿真器的仿真插头中P1.0~P1.7和P3.0~P3.6引出来仿真2051,这种方法可以运用单步、断点的调试方法,但是仿真不够真实,比如,2051的内部模拟比较器功能,P1口、P3口的增强下拉能力等等。 3.4 引脚说明

6

图3-2 AT89C20151

1.VCC:电源电压。 2.GND:地。

3.P1口:P1口是一个8位双向I/O口。口引脚P1.2~P1.7提供内部上拉电阻,P1.0和P1.1要求外部上拉电阻。P1.0和P1.1还分别作为片内精密模拟比较器的同相输入(ANI0)和反相输入(AIN1)。P1口输出缓冲器可吸收20mA电流并能直接驱动LED显示。当P!口引脚写入“1”时,其可用作输入端,当引脚P1.2~P1.7用作输入并被外部拉低时,它们将因内部的写入“1”时,其可用作输入端。当引脚P1.2~P1.7用作输入并被外部拉低时,它们将因内部的上拉电阻而流出电流。

4.P3口:P3口的P3.0~P3.5、P3.7是带有内部上拉电阻 的七个双向I/O口引脚。P3.6用于固定输入片内比较器的输出信号并且它作为一通用I/O引脚而不可访问。P3品缓冲器可吸收20mA电流。当P3口写入“1”时,它们被内部上拉电阻拉高并可用作输入端。用作输入时,被外部时拉低的P3口脚将用上拉电阻而流出电流。P3口还接收一些用于闪速存储器编程和程序校验的控制信号。

5.RST:复位输入。RST一旦变成高电平所有的I/O引脚就复位到“1”。当振荡器正在运行时,持续给出RST引脚两个机器周期的高电平便可完成复位。每一个机器周期需12个振荡器或时钟周期。

6.XTAL1:作为振荡器反相器的输入和内部时钟发生器的输入。 7.XTAL2:作为振荡器反相放大器的输出。 3.5主要性能

7

1.和MCS-51产品兼容;

2.2KB可重编程FLASH存储器(10000次); 3.2.7-6V电压范围; 4.全静态工作:0Hz-24MHz; 5.2级程序存储器保密锁定; 6.128*8位内部RAM; 7.15条可编程I/O线; 8.两个16位定时器/计数器; 9.6个中断源; 10.可编程串行通道;

11.高精度电压比较器(P1.0,P1.1,P3.6); 12.直接驱动LED的输出端口。

4 电路的硬件设计

4.1复位电路

AT89C2051单片机的复位是由外部的复位电路来实现的。复位引脚RST通过一个

斯密特触发器与复位电路相连,斯密特触发器用来抑制噪声,在每个机器周期的S5P2,斯密特触发器的输出电平由复位电路采样一次,然后才能得到内部复位操作所需要的信号。

上电复位电路是—种简单的复位电路,只要在RST复位引脚接一个电容到VCC,接一个电阻到地就可以了。上电复位是指在给系统上电时,复位电路通过电容加到RST复位引脚一个短暂的高电平信号,这个复位信号随着VCC对电容的充电过程而回落,所以RST引脚复位的高电平维持时间取决于电容的充电时间。为了保证系统安全可靠的复位,RST引脚的高电平信号必须维持足够长的时间。

图4-1 复位电路

上电自动复位是通过外部复位电路的电容充电来实现的。只要VCC的上升时间不超过1ms,就可以实现自动上电复位

8

4.2 时钟电路

时钟是单片机的心脏,单片机各功能部件的运行都是以时钟频率为基准,有条不紊的一拍一拍地工作。因此,时钟频率直接影响单片机的速度,时钟电路的质量也直接影响单片机系统的稳定性。常用的时钟电路有两种方式:一种是内部时钟方式,另一种为外部时钟方式。本文用的是内部时钟方式。

图4-2 时钟电路

AT89C2051单片机内部有一个用于构成振荡器的高增益反相放大器,该高增益反向放大器的输入端为芯片引脚XTAL1,输出端为引脚XTAL2。这两个引脚跨接石英晶体振荡器和微调电容,就构成一个稳定的自激振荡器。 4.3 按键电路

按键的开关状态通过一定的电路转换为高、低电平状态。按键闭合过程在相应的I/O端口形成一个负脉冲。闭合和释放过程都要经过一定的过程才能达到稳定,这一过程是处于高、低电平之间的一种不稳定状态,称为抖动。抖动持续时间的常长短与开关的机械特性有关,一般在5-10ms之间。为了避免CPU多次处理按键的一次闭合,应采用措施消除抖动。本文采用的是独立式按键,直接用I/O口线构成单个按键电路,每个按键占用一条I/O口线,每个按键的工作状态不会产生互相影响。按键 S1~S3 采用复用的方式与显示部分的 P3.5、P3.4、P3.2 口复用。其工作方式为,在相应端口输出高电平时读取按键的状态并由单片机消除抖动并赋予相应的键值。

9

图4-3 按键电路

4.4 迅响电路及输入、输出电路

迅响电路由有源蜂鸣器和 PNP 型三极管组成。其工作是当 PNP 型三极管导通后有源蜂鸣器立即发出定频声响。驱动方式为独立端口驱动,占用P3.7端口。

输出电路是与迅响电路复合作用的,其电路结构为有源蜂鸣器,5.1K定值电阻R6,排针J3并联。当有源蜂鸣器无迅响时J3输出低电平,当有源蜂鸣器发出声响时J3输出高电平,J3可接入数字电路等各种需要。驱动方式为迅响复合输出,不占端口。

输入电路是与迅响电路复合作用的,其电路结构是在迅响电路的 PNP 型三极管的基极电路中接入排针J2。引脚排针可改变单片机I/O口的电平状态,从而达到输入的目的。驱动方式为复合端口驱动,占用P3.7端口。

图4-4 迅响电路及输入、输出电路

4.5数码管显示电路

4.5.1 LED数码管结构及工作原理

LED数码管(LED Segment Displays)是由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。每一笔划都是对应一个字母表示 DP是小数点。下图为常用LED数码管内部引脚图。

10

图4-4-1 LED数码管正面个字段引脚

LED数码管根据LED的接法不同分为共阴和共阳两类 共阳极LED数码管的内部结构原理图:

图4-4-2 共阳极LED数码管的内部结构原理图

共阴极LED数码管的内部结构原理图:

图4-4-3 共阴极LED数码管的内部结构原理图

LED数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数位,因此根据LED数码管的驱动方式的不同,可以分为静态式和动态式两类。

1.静态显示驱动

静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的

11

I/O埠进行驱动,或者使用如BCD码二-十进位*器*进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O埠多,如驱动5个数码管静态显示则需要5×8=40根I/O埠来驱动,要知道一个89S51单片机可用的I/O埠才32个呢。故实际应用时必须增加*驱动器进行驱动,增加了硬体电路的复杂性。

2.动态显示驱动:

数码管动态显示介面是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划\的同名端连在一起,另外为每个数码管的公共极COM增加位元选通控制电路,位元选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位元选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位元就显示出字形,没有选通的数码管就不会亮。

透过分时轮流控制各个LED数码管的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位元数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极体的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示资料,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O埠,而且功耗更低。

4.5.2 显示原理

显示部分主要器件为3只两位一体共阳极数码管,驱动采用 PNP 型三极管驱动,各端口配有限流电阻,驱动方式为动态扫描,占用 P3.0~P3.5 端口,段码由P1.0~P1.6输出。冒号部分采用 4 个 Φ3.0的红色发光二极管,驱动方式为独立端口P1.7驱动。

12

图4-4-5 数码管电路

4.6 稳压电路

78L05是一个线性的稳压器,不论其输入端接多少伏电源,其输出是固定的5伏,主要给小容量的器件提供电源。因为是线性稳压,所以其输出波形杂波比较严重,而且其输出会复制输入的波形出来。所以前后都要滤波,在输入端加电容时相当于平滑电容。起到一个滤波的作用,提高IC工作稳定性。输出端加电容是为本地器件提供能量的存储器件,它能使稳压器的输出均匀化,降低负载需求。

图4-5 稳压电路

本设计采用了单片机AT89C2051为核心器件,它与C51相比除少了P0、P2口外指令完全相同。在电路中P1口输出段码数据,接六位数码管的段码引脚,P3口作扫描控制,控制各位数码管的显示情况!并配合所有的外围电路,具有上电复位的功能,无手动复位功能。

5 软件设计

5.1 主程序系统结构

13

图5-1 软件系统结构

5.2 软件任务分析

软件任务分析和硬件电路设计结合进行,哪些功能由硬件完成,哪些任务由软件完成,在硬件电路设计基本定型后,也就基本上决定下来了[9]。

软件任务分析环节是为软件设计做一个总体规划。从软件的功能来看可分为两大类:一类是执行软件,它能完成各种实质性的功能,如测量,计算,显示,打印,输出控制和通信等,另一类是监控软件,它是专门用来协调各执行模块和操作者的关系,在系统软件中充当组织调度角色的软件。这两类软件的设计方法各有特色,执行软件的设计偏重算法效率,与硬件关系密切,千变万化。

软件任务分析时,应将各执行模块一一列出,并为每一个执行模块进行功能定义和接口定义(输入输出定义)。在各执行模块进行定义时,将要牵扯到的数据结构和数据类型问题也一并规划好。

各执行模块规划好后,就可以监控程序了。首先根据系统功能和键盘设置选择一种最适合的监控程序结构。相对来讲,执行模块任务明确单纯,比较容易编程,而监控程序较易出问题。这如同当一名操作工人比较容易,而当一个厂长就比较难了。

软件任务分析的另一个内容是如何安排监控软件和各执行模块。整个系统软件可分为后台

14

程序(背景程序)和前台程序。后台程序指主程序及其调用的子程序,这类程序对实时性要求不是太高,延误几十ms甚至几百ms也没关系,故通常将监控程序(键盘解释程序),显示程序和打印程序等与操作者打交道的程序放在后台程序中执行;而前台程序安排一些实时性要求较高的内容,如定时系统和外部中断(如掉电中断)。也可以将全部程序均安排在前台,后台程序为“使系统进入睡眠状态”,以利于系统节电和抗干扰。

5.3 软件流程图

图5-3 程序设计流程图

程序里先定义两个中断定时器T0和T1,一个作为秒记数用,另一个做为调整时闪烁用。编程时先将P1和P3口数据清零,然后P1和P3口作动态扫描显示,由于人的眼睛有延迟性,当扫描频率非常高时人就感觉数码管一直亮着,而同时记数器在遵循时间的变化方式执行着秒到了60分加一,分到了60小时加一,小时到了24就归零。P3.7作为时间调整按钮当长按按住2秒以上进入校准时间状态及换档和退出,快速点触用于调节时间数值,归零是复位按钮。

6 安装与调试

15

6.1 安装、焊接元件到电路板上

按照先低后高,先小后大,先卧式后立式的顺序,正确插入元件,其高低、极性要符合规定。

1.先从最低元件安装。应先安装、焊接跳线机及电阻,用电阻多余的脚做跳线,电阻引脚不分正负,焊接时间最好控制在2-3秒。 2.安装、焊接瓷片电容。瓷片电容部分正负极。 3.安装、焊接轻触开关

4.安装、焊接三极管。三极管的外形基本一样,注意分青,且方向要和电路板上的方向一致。

5.安装、焊接12MHZ晶振。晶振没有正负极。

6.安装、焊接电解电容,装的时候要躺着安装,立着会影响发光二极管的显示不整齐。 7.安装、焊接20脚IC插座,从用一小缺口或小圆点标记的地方以逆时针数依次为1-20脚,安装时要注意缺口和电路上的缺口相一致。20只引脚都插到位后,先用手指按住,固定对角两只引脚,防止插入的引脚掉出来,再把板放到桌面上把剩下的引脚焊好。焊好后不要急于插入单片机芯片,因为还有其他元件焊接,防止电烙铁带静电击坏单片机芯片。 8.安装、焊接蜂鸣器。

9.安装、焊接LED。LED和普通二极管一样,有正负极之分,不能装错。 安装、焊接数码管。认识数码管内部结构。 6.2 调试

1.功能按键 S1为功能选择按键 2.功能及操作

操作时,连续短时间(小于1秒)按动S1,即可在以上的6个功能中连续循环。中途如果长按(大于2秒)S1,则立即回到时钟功能的状态。

S1按纽用于校准时间,按住2秒以上进入时间校准、换档、退出,快速点触用于调节时间数值。

16

7 结束语

在四个多月的设计,一个基本完整AT89C2051六位数字钟完成了。设计完此毕业设计,首先让自己对AT89C2051六位数字钟设计的掌握有了进一步的加深和巩固,能够更熟练的应用各种元件功能。还要掌握了解AT89C2051六位数字钟设计的元件分布和电路分布,还有它的效能和其他~!AT89C2051六位数字钟是以单片机(AT89C2051)为核心的数字时钟,结合相关的元器件,再配以相应的软件,达到制作简易数字时钟的目的,其硬件部分难点在于元器件的选择、分布及焊接,程序的调试!

参考文献

[1] 石生,电路基本分析[M]高等教育出版社. 2008,9:64~66. [2] 何立民,高级单片机教程[M]北航出版社. 2009,6:218~220. [3] 李振声,实验电子技术[M]国防工业出版社. 2007,7:73~75.

[4] 李全利,单片机原理与应用技术[M]高等教育出版社. 2009,6:81~84. [5] 刘守义,单片机应用技术[M]西安电子科技大学出版社. 2008,4:7~19.

[6] 任为民,电子技术基础课程设计[M]中央广播电视大学出版社. 2003,10:80~87. [7] ATMEL,Microcontroller Data book[M]. 2002,9:38~41.

[8] Mark1,Montrose.PRINTED Circuit Board Design Techniques for EMC compliance.IEE Press series[M].2000,11:44~48.

致 谢

在校几年学习时光已经接近尾声,在此我想对我的母校,我的老师和同学们表达我由衷的谢意。感谢我的家人对我学习的默默支持;感谢我的母广州机电学校给了我在学校年深造的机会,让我能继续学习和提高;感谢的广州机电学校老师和同学们几年来的关心和鼓励。老师们课堂上的激情洋溢,课堂下的谆谆教诲;同学们在学习中的认真热情,生活上的热心主动,所有这些都让我的几年充满了感动。 这次毕业论文设计我得到了很多老师和同学的帮助,其中我的论文指导老师刘贤文老师对我的关心和支持尤为重要。每次遇到难题,我最先做的就是向刘老师寻求帮助,而刘老师每次不管忙或闲,总会抽空来找我面谈,然后一起商量解决的办法。刘老师平日里工作繁多,但我做毕业设计的每个阶段,从选题到查阅资料,论文提纲的确定,中期论文的修改,后期论文格式调整等各个环节中都给予了我悉心的指导。这几个月以来,刘老师不仅在学业上给我以精心指导,同时还在思想给我以无微不至的关怀,在此谨向刘老师致以诚挚的谢意和崇高的敬意。同时,本篇毕业论文的写作也得到了陈桂森,韩东胜等同学的热情帮助。感谢在整个毕业设计期间和我密切合作的同学,和曾经在各个方面给予过我帮助的伙伴们,在此,我再一次真诚地向帮助过我的老师和同学表示感谢!。

培养教育我的机电学校,机电浓厚的学术氛围,舒适的学习环境我将终生难忘!祝母校蒸蒸日上,永创辉煌!感谢我以最大的毅力完成了四年大学学习,在这个环境里我能洁身自爱,出淤泥而不染保持一颗纯洁的心,真的是很不容易!祝自己身体健康,权财两旺!家里红旗不倒,外面彩旗飘飘! 感谢多位指导我的老师!

感谢我的班主任王俊良老师,谢谢他在这两年中为我们全班所做的一切,他不求回报,无私奉献的精神很让我感动,再次向他表示由衷的感谢。

附录1

元器件清单:

17

名称 单片机 三端稳压集成电路 石英晶体振荡器 2位共阳数码管 红色0.4寸 LED1 LED2 LED3 发光二极管 LED LED LED LED 瓷介电容器 30 30 104 104 电解电容 晶体三极管 10uF 100uF 9012 9012 9012 9012 9012 9012 D1 D2 D3 D4 C2 C3 C4 C5 C1 C6 Q1 Q4 Q3 Q2 Q5 Q6 集成电路插座 数字钟专用电路板 9012 Q7 资料 A4 - 20脚 50mm*50mm 2位排针 12MHZ Y1 型号\\规格 AT89C2051 78LO5 元器件编号 U1 U2 名称 碳膜电阻 220 220 220 220 1K 1K 1K 1K 1K 1K 2K 2K 5.1K 10K 间距2.54 R6 R7 R8 R9 R2 R10 R11 R13 R14 R15 R17 R18 R16 R1 J1 J2 J3 / - 220 R5 型号\\规格 220 220 元器件编号 R3 R4 18

附录2

电路原理图

程序主要代码:

#include

code senen_seg[10]={0x81,0xe7,0x92,0xa2,0xe4,0xa8,0x88,0xe3,0x80,0xa0}; bit

key1_enter=0,key2_enter=0,key3_enter=0,countdown_mark=0,stopwatch_mark=0,count_mark=0,bell_mark=0;

unsigned char program=0,program_variable=0,count_bit=0,count=0; unsigned char hour=10,minute=10,second=0; unsigned char delayed_hour=22,delayed_minute=10,delayed_second=0;

unsigned char count_hour=0,count_minute=0,count_second=0; unsigned char count_time=0,count_count=0; void delay(unsigned int t) {

unsigned int i,j; for(i=0;i

void time0_init(void){ EA=0; TR0=0;

TMOD=0x01; TH0=0xec;

19

TL0=0x73; ET0=1; TR0=1; EA=1; } static void timer0_isr(void) interrupt TF0_VECTOR using 1 {

TR0=0; TH0=0xec; TL0=0x73; TR0=1;

count_time++; if(count_time>=199){ count_time=0; second++;

if(second>=60){ second=0; minute++;

if(minute>=60){ minute=0; hour++;

if(hour>=24)hour=0; } } }

if(delayed_hour==hour && delayed_minute==minute && second<4) P3_7=0; else P3_7=1;

if(countdown_mark==1){ count_count++;

if(count_count>=199 && (count_second!=0|count_minute!=0|count_hour!=0)){ count_count=0; count_second--;

if(count_second>=60){ count_second=59; count_minute--;

if(count_minute>=60){ count_minute=59; count_hour--;

if(count_hour>=100) count_hour=99; } } }

if(count_second==0&&count_minute==0&&count_hour==0&&count_count<=12000)

P3_7=0;

else P3_7=1;

20

case 2: program=4; break; case 3: count_bit++; if(count_bit>=7)count_bit=0; break; case 4: switch(count_bit){ case 0: count_second+=1; break; case 1: count_second+=10; break; case 2: count_minute+=1; break; case 3: count_minute+=10; break; case 4: count_hour+=1; break; case 5: count_hour+=10; break; case 6: break; } if(count_hour>=100) count_hour-=100; if(count_minute>=60) count_minute-=60; if(count_second>=60) count_second-=60; break; } if(count_bit==6) countdown_mark=1; else countdown_mark=0; }

break;

case 4: count_hour=0; count_minute=0; count_second=0;

while(program==4){ switch(show_key()){ case 0: break; case 1: program=0; break; case 2: program=5; break; case 3: stopwatch_mark=~stopwatch_mark; break; case 4: if(stopwatch_mark==0){ count_hour=0; count_minute=0; count_second=0;

26

} break; } }

break; case 5: count_hour=0;

count_minute=0; count_second=0;

while(program==5){ switch(show_key()){ case 0: break; case 1: program=0; break; case 2: program=0; break; case 3: count_second++; if(count_second>=100){ count_second=0; count_minute++; if(count_minute>=100){ count_minute=0; count_hour++; if(count_hour>=100)count_hour=0; } } break; case 4: count_hour=0;

count_minute=0; count_second=0; break; } if(P3_7==0){ while(P3_7==0) show_key(); count_second++; if(count_second>=100){ count_second=0; count_minute++; if(count_minute>=100){ count_minute=0; count_hour++; if(count_hour>=100)count_hour=0; } } } }

27

break; }

if(program!=3) countdown_mark=0; if(program!=4) stopwatch_mark=0;

28

if(count_count>=15000) count_count=14000; }

if(stopwatch_mark==1){ count_count++;

if(count_count>=2){ count_count=0; count_second++;

if(count_second>=100){ count_second=0; count_minute++;

if(count_minute>=60){ count_minute=0; count_hour++;

if(count_hour>=60) count_hour=0; } } } } }

unsigned char show_key (void){ unsigned char x=0,y=0; switch (program){

case 0: P1&=senen_seg[second]; break;

case 1: if(count_time>=90) P1&=senen_seg[second]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_second]; break;

case 3: if(count_bit>=0) P1&=senen_seg[count_second]; else P1=0xff; break;

case 4: P1&=senen_seg[count_second]; break;

case 5: P1&=senen_seg[count_second]; break; }

P3_3=0; delay(10);

if(P3_5==0){ key1_enter=1;

if(count<=254)count++; }

if(P3_4==0) key2_enter=1; if(P3_2==0) key3_enter=1;

21

P3_3=1; P1|=0xff;

switch (program){

case 0: P1&=senen_seg[second/10]; break;

case 1: if(count_time>=90) P1&=senen_seg[second/10]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_second/10]; break;

case 3: if(count_bit>=1) P1&=senen_seg[count_second/10]; else P1=0xff; break;

case 4: P1&=senen_seg[count_second/10]; break;

case 5: P1&=senen_seg[count_second/10]; break; } P3_1=0; delay(10); P3_1=1; P1|=0xff;

switch (program){

case 0: P1&=senen_seg[minute]; break;

case 1: if(count_time>=90) P1&=senen_seg[minute]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_minute]; break;

case 3: if(count_bit>=2) P1&=senen_seg[count_minute]; else P1=0xff; break;

case 4: P1&=senen_seg[count_minute]; break;

case 5: P1&=senen_seg[count_minute]; break; }

P3_2=0; delay(10); P3_2=1; P1|=0xff;

switch (program){

case 0: P1&=senen_seg[minute/10]; break;

22

case 1: if(count_time>=90) P1&=senen_seg[minute/10]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_minute/10]; break;

case 3: if(count_bit>=3) P1&=senen_seg[count_minute/10]; else P1=0xff; break; case 4: P1&=senen_seg[count_minute/10]; break;

case 5: P1&=senen_seg[count_minute/10]; break; }

P3_5=0; delay(10); P3_5=1; P1|=0xff;

switch (program){

case 0: P1&=senen_seg[hour]; break;

case 1: if(count_time>=90) P1&=senen_seg[hour]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_hour]; break;

case 3: if(count_bit>=4) P1&=senen_seg[count_hour]; else P1=0xff; break;

case 4: P1&=senen_seg[count_hour]; break;

case 5: P1&=senen_seg[count_hour]; break; }

P3_0=0; delay(10);

if(P3_4==1 && key2_enter==1){

x=3; 3

key2_enter=0; }

P3_0=1; P1|=0xff;

switch (program){

case 0: P1&=senen_seg[hour/10]; break;

23

case 1: if(count_time>=90) P1&=senen_seg[hour/10]; break;

case 2: if(delayed_hour==24) P1=0xfe; else P1&=senen_seg[delayed_hour/10]; break;

case 3: if(count_bit>=5)P1&=senen_seg[count_hour/10]; else P1=0xff; break;

case 4: P1&=senen_seg[count_hour/10]; break;

case 5: P1&=senen_seg[count_hour/10]; break; }

P3_4=0; delay(10);

if(P3_5==1 && key1_enter==1){ if(count>=127) x=1; else x=2; key1_enter=0; count=0; }

if(P3_2==1 && key3_enter==1){

x=4; key3_enter=0; } P3_4=1; P1|=0xff;

if(program<=1 && count_time>=100) P1&=0xff; if(program<=1 && count_time<=100) P1&=0x7f; if(program==2) P1&=0x7f; if(program==3) P1&=0xff; if(program==4) P1&=0x7f; if(program==5) P1&=0xff; y=x; x=0; return y; }

void main(){ P1=0xff; P3=0xff; time0_init(); while(1){

switch(program){

case 0: while(program==0){ switch(show_key()){

24

case 0: break; case 1: program=0; break; case 2: program=1; break; } }

break; case 1: while(program==1){ switch(show_key()){ case 0: break; case 1: program=0; break; case 2: program=2; break; case 3: hour++; if(hour>=24)hour=0; break; case 4: minute++; if(minute>=60)minute=0; break; } }

break;

case 2: while(program==2){ switch(show_key()){ case 0: break; case 1: program=0; break; case 2: program=3; break; case 3: delayed_hour++; if(delayed_hour>=25)delayed_hour=0; break; case 4: delayed_minute++; if(delayed_minute>=60)delayed_minute=0; break; } }

break;

case 3: while(program==3){ switch(show_key()){ case 0: break; case 1: program=0; break;

25

本文来源:https://www.bwwdw.com/article/d43d.html

Top