多功能电子时钟设计.doc 71页

  • 1.03 MB
  • 2022-04-22 13:43:58 发布

多功能电子时钟设计.doc

  • 71页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'多功能电子时钟设计67 多功能页眉要修改电子钟的设计与实现—硬件部分?摘要电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时钟精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。本设计主要为实现一款可正常显示时钟/日历、带有定时闹铃的多功能电子时钟。本文对当前电子钟开发手段进行了比较和分析,最终确定了采用单片机技术实现多功能电子时钟。改为:在对当前电子钟开发手段进行比较和分析的基础上确定采用单片机技术实现一款可正常显示时钟/日历、带有定时闹铃的多功能电子时钟。本设计应用AT89C51芯片作为核心,7位LED数码管显示,使用DS1302实时时钟日历芯片完成时钟/日历的基本功能,这种实现方法的优点是电路简单,性能可靠,实时性好,时间精度高,操作简单,编程容易。该电子时钟可以应用于一般的生活和工作中,也可通过改装,提高性能,增加新功能,从而给人们的生活和工作带来更多的方便。关键词:电子时钟;多功能;AT89C51;时钟日历芯片67 TheDesignwithInvestigationoftheMulti-functionElectronClock-TheDesignoftheHardwareAbstractTheelectronicclockmainlyusestheelectronictechnologymaketheclockcomputerization,thedigitization,withtheclockprecision,smallsize,friendlyinterface,scalableperformanceandothercharacteristics,waswidelyusedinlifeandwork.Thedesignforthemainimplementingaclock/calendarcanbedisplayednormal,collectingpersonalambienttemperature,withthetimingalarmofthemulti-functionelectronicclock.Comparingandanalysisingthedevelopmenttechnologyoftheelectronclock,thedesigndeterminestousetheMCUtechnologytorealizethemulti-functionalelectronclock.ThisdesignapplicationAT89C51asacorechips,7LEDdigitaldisplaying,usingDS1302real-timeclockchiptocompletethebasicfunctionoftheclock/calendar.Themethodhastheadvantageofbeingsimplecircuit,reliableperformance,goodreal-time,highprecisionofthetime,simplyoperation,easyprogramming.Theelectronicclockcanbeappliedtothegenerallivingandworking,canalsobemodifiedtoimproveperformance,addnewfunctions,andbringsmoreconvenienttopeople’slifeandwork.Keywords:Electronicclock;Multi-function;AT89C51;DS130267 67 第一章绪论时间是人类生活必不可少的重要元素,如果没有时间的概念,社会将不会有所发展和进步。从古代的水漏、十二天干地支,到后来的机械钟表以及当今的石英钟,都充分显现出了时间的重要,同时也代表着科技的进步。致力于计时器的研究和充分发挥时钟的作用,将有着重要的意义。1.1多功能电子时钟研究的背景和意义20世纪末,电子技术获得了飞速的发展。在其推动下,现代电子产品几乎渗透到了社会的各个领域,有力的推动和提高了社会生产力的发展与信息化程度,同时也使现代电子产品性能进一步提升,产品更新换代的节奏也越来越快。时间对人们来说总是那么宝贵,工作的忙碌性和繁杂容易使人忘记当前的时间。然而遇到重大事情的时候,一旦忘记时间,就会给自己或他人造成很大麻烦。平时我们要求上班准时,约会或召开会议必然要提及时间;火车要准点到达,航班要准点起飞;工业生产中,很多环节都需要用时间来确定工序替换时刻。所以说能随时准确的知道时间并利用时间,是我们生活和工作中必不可少的[1]。想知道时间,手表当然是一个很好的选择,但是,在忙碌当中,我们还需要一个“助理”及时的给我们提醒时间。所以,计时器最好能够拥有一个定时系统,随时提醒容易忘记时间的人。最早能够定时、报时的时钟属于机械式钟表,但这种时钟受到机械结构、动力和体积的限制,在功能、性能以及造价上都没办法与电子时钟相比。电子钟是采用电子电路实现对时、分、秒进行数字显示的计时装置,广泛应用于个人家庭,车站,码头办公室等公共场所,成为人们日常生活中不可少的必需品。67 由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、0按时自动打铃、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。1.1电子时钟的功能电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时间精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。当今市场上的电子时钟品类繁多,外形小巧别致。也有体型较大的,诸如公共场所的大型电子报时器等。电子时钟首先是数字化了的时间显示或报时器,在此基础上,人们可以根据不同场合的要求,在时钟上加置其他功能,比如定时闹铃,万年历,环境温度、湿度检测,环境空气质量检测,USB扩展口功能等。本设计电子时钟主要功能为:1.具有时间显示和手动校对功能,24小时制;2.具有年、月、日显示和手动校对功能;3.具有闹铃功能;4.具有贪睡功能;5.掉电后无需重新设置时间和日期;6.采用交直流供电电源。交流供电为主,直流电源为后备辅助电源,并能自动切换。67 第一章电子时钟设计方案分析电子闹钟既可以通过纯硬件实现,也可以通过软硬件结合实现,根据电子时钟里的核心部件——秒信号的产生原理,通常有以下两种形式:1.1FPGA设计方案现场可编程门阵列(FieldProgrammableGateArray,FPGA),是20世纪70年代发展起来的一种可编程逻辑器件,是目前数字系统设计的主要硬件基础。FPGA在结构上由逻辑功能块排列为阵列,并由可编程的内部连线连接这些功能块,来实现一定的逻辑功能。可编程逻辑器件的设计过程是利用EDA开发软件和编程工具对器件进行开发的过程。由于EDA技术拥有系统的模拟和仿真功能,可读性、可重复性、可测性非常好,所以利用EDA开发FPGA是目前比较流行的方式。当然,有时根据需要,也会应用MAX+plus开发集成环境进行设计。正因为FPGA在设计过程中方便、快捷,而且FPGA技术功能强大,能够应用其制作诸如基代码发生器、数字频率计、电子琴、电梯控制器、自动售货机控制系统、多功能波形发生器、步进电机定位控制系统、电子时钟等。应用FPGA能够将时钟设计为为四种类型:全局时钟、门控时钟、多级逻辑时钟和波动式时钟。多时钟系统能够包括上述四种时钟类型的任意组合[2][3][4]。1.2单片机设计方案67 单片机是微型机的一个主要分支,它在结构上的最大特点使把CPU、存储器、定时器和多种输入/输出接口电路集成在一块超大规模集成电路芯片上。就其组成和功能而言,一块单片机芯片就是一台计算机。单片机具有如下特点:有优异的性能价格比;1集成度高、体积小、有很高的可靠性;2控制功能强;3低功耗、低电压,便于生产便携式产品;4外部总线增加了I2C、SPI等串行总线方式,进一步缩小了体积,简化了结构;5单片机的系统扩展、系统配置较典型、规范,容易构成各种规模的应用系统。所以单片机的应用非常广泛,在智能仪表、机电一体化、实时控制、分布式多机系统以及人们的生活中均有用武之地。单片机应用的重要意义还在于,它从根本上改变了传统的控制系统设计思路和设计方法。从前必须由模拟电路或数字电路实现的大部分功能,现在已能用单片机通过软件方法来实现了。这种用软件代替硬件的控制技术,是对生产控制技术的一次革命。利用单片机的智能性,可方便地实现具有智能的电子钟设计。单片机均具有时钟振荡系统,利用系统时钟借助微处理器的定时器/计数器可实现电子钟功能。然而系统时钟误差较大,电子钟的积累误差也可能较大,所以可以通过误差修正软件加以修正,或者在设计中加入高精度时钟日历芯片,以精确时间。另外很多功能不同的单片机是兼容的,这就更便于实现产品的多功能性。67 第一章基于单片机的电子时钟硬件设计在比较了第二章的三种实现方案之后,考虑单片机货源充足、价格低廉,可软硬件结合使用,能够较方便的实现系统的多功能性,故采用单片机作为本设计的硬件基础。1.1主要IC芯片选择1.1.1微处理器选择目前在单片机系统中,应用比较广泛的微处理器芯片主要为8XC5X系列单片机。该系列单片机均采用标准MCS-51内核,硬件资源相互兼容,品类齐全,功能完善,性能稳定,体积小,价格低廉,货源充足,调试和编程方便,所以应用极为广泛。例如比较常用的AT89C2051单片机,带有2KBFlash可编程、可擦除只读存储器(E2PROM)的低压、高性能8位CMOS微型计算机。拥有15条可编程I/O引脚,2个16位定时器/计数器,6个中断源,可编程串行UART通道,并能直接驱动LED输出。仅仅是为了完成时钟设计或者是环境温度采集设计,应用AT89C2051单片机完全可以实现。但是将两种功能结合在一片单片机上,就需要更多的I/O引脚,故本设计采用具有32根I/O引脚的AT89C51单片机。AT89C51单片机是一款低功耗,低电压,高性能CMOS8位单片机,片内含4KB(可经受1000次擦写周期)的FLASH可编程可反复擦写的只读程序存储器(EPROM),器件采用CMOS工艺和ATMEI公司的高密度、非易失性存储器(NURAM)技术制造,其输出引脚和指令系统都与MCS-51兼容。片内的FLASH存储器允许在系统内可改编程序或用常规的非易失性存储器编程器来编程。因此,AT89C51是一种功能强,灵活性高且价格合理的单片机,可方便的应用在各个控制领域。67 AT89C51具有以下主要性能:1.4KB可改编程序Flash存储器;2.全静态工作:0——24Hz;3.128×8字节内部RAM;4.32个外部双向输入/输出(I/O)口;5.6个中断优先级;2个16位可编程定时计数器;6.可编程串行通道;7.片内时钟振荡器。此外,AT89C51是用静态逻辑来设计的,其工作频率可下降到0Hz,并提供两种可用软件来选择的省电方式——空闲方式(IdleMode)和掉电方式(PowerDownMode)。在空闲方式中,CPU停止工作,而RAM、定时器/计数器、串行口和中断系统都继续工作。在掉电方式中,片内振荡器停止工作,由于时钟被“冻结”,使一切功能都暂停,只保存片内RAM中的内容,直到下一次硬件复位为止[8]。图3.1AT89C51芯片PDIP封装引脚图AT89C67 51为适应不同的产品需求,采用PDIP、TQFP、PLCC三种封装形式,本系统采用双列直插PDIP封装形式,如图3.1。时钟日历芯片选择3.1.2.1常用时钟日历芯片比较在电子时钟设计中,常用的实时时钟芯片有DS12887、DS1216、DS1643、DS1302。每种芯片的主要时钟功能基本相同,只是在引脚数量、备用电池的安装方式、计时精度和扩展功能等方面略有不同。DS12887与DS1216芯片都有内嵌式锂电池作为备用电池;X1203引脚少,没有嵌入式锂电池,跟DS1302芯片功能相似,只是相比较之下,X1203与AT89S51搭配使用时占用I/O口较多。DS1643为带有全功能实时时钟的8K×8非易失性SRAM,集成了非易失性SRAM、实时时钟、晶振、电源掉电控制电路和锂电池电源,BCD码表示的年、月、日、星期、时、分、秒,带闰年补偿。同样,DS1643拥有28只管脚,硬件连接起来占用微处理器I/O口较多,不方便系统功能拓展和维护。故而从性价比和货源上考虑,本设计采用实时时钟日历芯片DS1302。3.1.2.2DS1302简介DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟日历芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小于31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后备电源进行涓细电流充电的能力。有主电源和备份电源双引脚,而且备份电源可由大容量电容(>1F)来替代。需要强调的是,DS1302需要使用32.768KHz的晶振。3.1.2.3DS1302引脚说明DS1302引脚图参照图3.2。67 图3.2DS1302芯片引脚图其的引脚功能参照表3.1。表3.1DS1302引脚功能说明引脚号名称功能1VCC1备份电源输入2X132.768KHz晶振输入3X232.768KHz晶振输出4GND地5RST控制移位寄存器/复位6I/O数据输入/输出7SCLK串行时钟8VCC2主电源输入3.1.2.4DS1302的控制字和读写时序说明在编程过程中要注意DS1302的读写时序。DS1302是SPI总线驱动方式。它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。要想与DS1302通信,首先要先了解DS1302的控制字。DS1302的控制字如表3.2。表3.2DS1302控制字(即地址及命令字节)BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT01RAMA4A3A2A1A0RD控制字的作用是67 设定DS1302的工作方式、传送字节数等。每次数据的传输都是由控制字开始。控制字各位的含义和作用如下:1.BIT7:控制字的最高有效位,必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。2.BIT6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;3.BIT5至BIT1(A4~A0):用A4~A0表示,定义片内寄存器和RAM的地址。定义如下:当BIT6位=0时,定义时钟和其他寄存器的地址。A4~A0=0~6,顺序为秒、分、时、日、月、星期、年的寄存器。当A4~A0=7,为芯片写保护寄存器地址。当A4~A0=8,为慢速充电参数选择寄存器。当A4~A0=31,为时钟多字节方式选择寄存器。当BIT6=1时,定义RAM的地址,A4~A0=0~30,对应各子地址的RAM,地址31对应的是RAM多字节方式选择寄存器。4.BIT0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。67 图3.3DS1302数据读写时序DS1302的数据读写方式有两种,一种是单字节操作方式,一种是多字节操作方式。每次仅写入或读出一个字节数据称为单字节操作,每次对时钟/日历的8字节或31字节RAM进行全体写入或读出的操作,称其为多字节操作方式。当以多字节方式写时钟寄存器时,必须按数据传送的次序依次写入8个寄存器。但是,当以多字节方式写RAM时,不必写所有31字节。不管是否写了全部31字节,所写的每一个字节都将传送至RAM。为了启动数据的传输,CE引脚信号应由低变高,当把CE驱动至逻辑1的状态时,SCLK必须为逻辑0,数据在SCLK的上升沿串行输入。无论是读周期还是写周期,也无论送方式是单字节传送还是多字节传送,都要通过控制字指定40字节中的哪个将被访问。67 在开始8个时钟周期把命令字(具有地址和控制信息的8位数据)装入移位寄存器之后,另外的时钟在读操作时输出数据,在写操作时输入数据,所有的数据在时钟的下降沿变化。所有写入或读出操作都是先向芯片发送一个命令字节。对于单字节操作,包括命令字节在内,每次为2个字节,需要16个时钟;对于时钟/日历多字节模式操作,每次为7个字节,需要72个时钟;而对于RAM多字节模式操作,每次则为32字节,需要多达256个时钟。这里仅给出单字节读写时序,如图3.3。多字节操作方式与其类似,只是后面跟的字节数不止一个。3.2.1.5DS1302的片内寄存器表3.3DS1302有关日历、时间的寄存器读寄存器写寄存器BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0范围81H80HCH10秒秒00-5983H82H10分分00-5985H84H010时时1-120-23AM/PM87H86H0010日日1-3189H88H0010月月1-128BH8AH00000周日1-78DH8CH10年年00-998FH8EHWP0000000—通过控制字对DS1302片内寄存器进行寻址之后,即可就所选中寄存器的各位进行操作。片内各寄存器及各位的功能定义如表3.3。DS1302有关日历、时间的寄存器共有10个,时钟/日历包含在其中的7个写/读寄存器内,这7个寄存器分别是秒、分、小时、日、月、星期和年。小时寄存器(85H、84H)的位7用于定义DS1302是运行于12小时模式还是24小时模式。当为12小时制式时,位5为“0”表示AM;为“1”表示PM。在24小时制式下,位5是第二个10小时位(20~23时)。 秒寄存器(81H、80H67 )的位7定义为时钟暂停标志(CH)。当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运行。一般在设置时钟时,可以停止其工作,设定完之后,再启动其工作。控制寄存器(8FH、8EH)的位7是写保护位(WP),其它7位均置为0。在任何片内时钟/日历寄存器和RAM,在写操作之前,WP位必须为0,否则将不可写入。当WP位为1时,写保护位防止对任一寄存器的写操作。因此,通过置写保护位,可以提高数据的安全性。另外,还有慢速充电控制寄存器和RAM寄存器。如表3.4。表3.4充电控制寄存器和RAM寄存器各位定义BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0充电控制寄存器TCSTCSTCSTCSDSDSRSRSRAM寄存器————————慢速充电寄存器控制着DS1302的慢速充电特性。寄存器的BIT4~BIT7(TCS)决定是否具备充电性能:仅在编码为1010的条件下才具备充电性能,其他编码组合不允许充电。BIT2和BIT3选择在VCC2和VCC1之间是一个还是两个二极管串入其中。如果编码DS是01,选择一个二极管;如果编码是10,选择两个二极管;其他编码将不允许充电。该寄存器的BIT0和BIT1用于选择与二极管相串联的电阻值。其中编码RS=01为2KΩ,RS=10为4KΩ,RS=11为8KΩ,而RS=00将不允许进行充电。因此,根据慢速充电寄存器的不同编码可得到不同的充电电流。其具体计算如公式3.1:I充电=(V0-VD-VE)/R(3.1)式中:V0——所接入的5.0V工作电压;VD——二极管压降,一个按0.7V计算;67 R——慢速充电控制寄存器0和1位编码决定的电阻值;VE——VCC1脚所接入的电池电压。RAM寄存器寻址空间一次排列的31字节静态RAM可为用户使用,备用电源位RAM提供了掉电保护功能。寄存器和RAM的操作通过命令字节的BIT6加以区别。当BIT6为“0”时对RAM区进行寻址;否则将对时钟/日历寄存器寻址。其操作方法与前述相同[9][10][11]。具体驱动程序参见附录A。1.1电子时钟硬件电路设计电子闹钟至少要包括秒信号发生器、时间显示电路、按键电路、供电电源、闹铃指示电路等几部分。另外,本设计要求该电子钟能够采集环境温度,所以还需要温度采集芯片。硬件电路框图参照图3.7。该系统使用AT89C51单片机作为核心,通过读取时钟日历芯片DS1302和温度传感器DS18B20的数据,完成此电子时钟的主要功能——时钟/日历和环境温度采集。使用比较通用的8段共阴数码管,做7位显示,分别显示时/年,分/月,秒/日,以及环境温度值。图3.7多功能电子时钟硬件系统框图67 键盘是为了完成时钟/日历的校对和日历/温度的显示功能。由于此电子时钟要求具有闹铃功能,所以设计有闹铃电路,进行声音响铃。整个电路使用了两种电源,+5V电源将为整个电路供电。而+3V电源仅作为DS1302的备用电源。当+5V电源被切断后,DS1302启用+3V电源,可以保持DS1302继续工作。当+5V电源恢复供电,LED依旧显示当前时间,而不会因为断电使系统复位到初始化时间,避免了重新校时的麻烦。具体电路图请参见附录C。1.1.1时钟电路设计系统时钟应用了实时时钟日历芯片DS1302,其连接如图3.8。该硬件电路设计简单,抗干扰能力强。如图,AT89C51单片机P1.7直接接DS1302的RST端,上电后,AT89C51的P1.7脚自动输出高电平。P1.5作为串行时钟接口,P1.6作为时钟数据的I/O。DS1302采用双电源供电,平时由+5V电源供电,当+5V掉电之后,由图中BT1(+3V备用电池)供电。特别需要注意X1和X2两端连接的晶振Y1,该晶振频率为32.768KHz。67 图3.8系统时钟电路1.1.1显示电路就时钟而言,通常可采用LCD显示或LED显示。对于一般的段式LCD,需要专门的驱动电路,而且LCD显示的可视性较差;对于具有驱动电路和微处理器接口的液晶显示模块(字符或点阵),一般采用并行接口,对微处理器的接口要求较高,占用资源多。另外,AT89C51本身没有专门的液晶驱动接口。LED结构简单,体积小,功耗低,响应速度快,易于匹配,寿命长,可靠性高,而且显示亮度高,价格便宜,市场上也有专门的时钟显示组合LED。故本设计中应用7位8段共阴LED实现显示部分,显示面板分布如图3.6。LED显示分动态显示和静态显示:动态显示方式的硬件电路简单。但设计上如果处理不当,易造成亮度低,闪烁问题。因此合理的设计既应保证驱动电路易实现,又要保证图像稳定,无闪烁。动态显示采用多路复用技术的动态扫描显示方式,复用的程度不是无限增加的,因为利用动态扫描显示使我们看到一幅稳定画面的实质是利用了人眼的暂留效应和发光二极管发光时间的长短,发光的亮度等因素。静态显示,是由微型计算机一次输出显示模型后,就能保持该显示结果,直到下次发送新的显示模型为止。静态显示驱动程序简单,且CPU占用率低,但每个LED数码管需要一个锁存器来锁存每一个显示位的笔段代码,硬件开销大,仅适合显示位数较少的场合。为了在显示部分节省单片机I/O口,故采用静态显示方式。电路图参见图3.10。74LS164是8位移位寄存器,应用该芯片驱动LED做显示部分,其优点在于连线简单,节省单片机I/O口,软件编程容易。关于74LS164的具体编程方法,请参见第四章4.2.5显示子程序设计部分[14][15]。67 图3.10显示面板LED分布图1.1.1按键电路设计根据功能需要,本时钟需要设置以下功能键:校对选择键,加1操作键,减1操作键,显示日期键,闹铃开关键。按照键盘与CPU的连接方式可分为独立式键盘和矩阵式键盘。独立式键盘是各个按键相互独立,每个按键占用一个I/O口线,每根I/O口线上的按键不会影响其他I/O口上按键工作状态。独立式键盘电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口,在按键数量较多时,I/O口线浪费较大,且电路结构复杂。矩阵式键盘适合按键较多时使用。由于本设计的电子钟最多需要7个按键,若采用矩阵式键盘时会有按键浪费,故采用的是独立式键盘。键盘电路如图3.11。对于内置了上拉电阻的I/O引脚来说,外接上拉电阻没有意义[15][16]。如图3.11。图3.11键盘电路67 其中K1、K2、K7为带自锁按键,每次按下后,其对应的P2.7、P2.6、P2.1管脚接地,从高电平被拉至低电平。只有再次按下,按键弹出,与之连接的单片机管脚才会重新被拉回高电平。K3、K4、K5、K6键为自动复位按键。每次按下后,会自动弹出。单片机管脚只有在按键按下时为低电平,按键弹出后重新恢复高电平。按键功能参见表3.8。表3.8按键功能表按键键名功能属性K1Calendar显示日历自锁K3FUN功能选择自动复位K4UP数值加一操作自动复位K5DOWN数值减一操作自动复位K6Enter/Snooze确认键/贪睡自动复位K7Alarm闹铃开关自锁按键操作说明如下:K1键:该键为带自锁按键,在正常显示时间状态下,每次将按键按下,LED数码管将显示日期;再次按下,按键弹出,重新显示时间。K3键:该键为自动复位键,在正常显示时间状态下,第一次按下后,开始校对小时,以后每次按下都会分别进入对分、秒、闹铃时、闹铃分、年、月、日的校对状态。K4键:该键为自动复位键,在校对状态下,每次按动该键,都会使相应校对位进行加1操作。例如:校对小时状态,每按一下,小时位加1,当加至小时最高值23时,再按K4键,小时位回0。调分、秒、年、月、日与皆之相同,只是各位最高值不同。K5键:该键为自动复位键,与K4键类似,不同之处是该键每次按下将使相应校对位进行减1操作。67 K6键:该键为自动复位键,在校对状态下,按下该键,从校对状态返回时间显示状态;在响铃状态下,按下该键,闹铃进入贪睡状态。K7键:该键为带自锁按键,按下后闹铃开启,弹出后闹铃关闭。1.1.1闹铃电路设计闹铃音乐可以直接采用蜂鸣器闹铃,如当前时刻与闹铃时间相同,单片机向蜂鸣器送出高电平,蜂鸣器发声。采用蜂鸣器闹铃结构简单,控制方便,但是发出的闹铃声音单一。也可以在编程的时候编写一段音乐程序,待闹铃时间到时,调用该音乐程序给扬声器,便响起音乐。不过该方法只能做一些简单音乐,并且音乐程序会占用很多单片机存储资源。还有一种方法是采用录音放音芯片1420做闹铃,先对录放音设备录入一段音乐,当到设定时间时,单片机控制录放音设备放音。采用录放音电路,铃声可以是预先设定的一段自己喜欢的音乐,符合电器设备人性化的要求。且1420芯片可以分段录音,还具有语音报时功能。另外,也可以购置一块音乐集成电路,加置在单片机和蜂鸣器之间,当单片机连接闹铃电路的管脚送出高电平时,音乐集成电路会给蜂鸣器特定脉冲,使蜂鸣器发声。此类集成电路体积较小,使用方便,不足的是音乐简单、单一。闹铃的音乐不是本设计中的重点,故采用最简单的方法,占用单片机一根I/O口P2.0,中间用PNP型三极管S9012连接P2.0和蜂鸣器。当P2.0引脚为低电平时,S9012的发射极和集电极导通,使蜂鸣器发声。当响铃标志位为“1”时,P2.0送一定频率脉冲,使蜂鸣器U11发出声音[16]。如图3.12。67 图3.12闹铃电路1.1.1复位电路设计复位是单片机的初始化操作,以便使CPU和系统中其他部件都处于一个确定的初始状态,并从这个状态开始工作。除了进入系统的正常初始化之外,当单片机系统在运行出错或操作错误使系统处于死锁状态时,也可按复位键重新启动。复位后,PC内容初始化为0000H,使单片机从0000H单元开始执行程序。单片机复位后,除了PC之外,还对片内的特殊功能寄存器有影响,它们的复位状态如表3.9所示。单片机复位后不影响内部RAM的状态[17]。89C51单片机复位信号的输入端是RST引脚,高电平有效。其有效时间持续24个时钟周期(2个机器周期)以上。RST端的外部复位电路有两种操作方式:上电自动复位和按键手动复位。上电自动复位是利用电容储电来实现的,如图3.13(a)所示。上电瞬间,RC电路充电,RST端出现正脉冲,随着充电电流的减少,RST的电位逐渐下降。按键手动复位有电平方式和脉冲方式两种。按键电平复位是相当于RST端通过电阻接高电平,如图3.13(b)所示;按键脉冲复位,利用RC微分电路产生正脉冲,如图3.13(c)所示[12]。出于应用方便,本设计采用按键电平复位电路。实际电路请参见附录C,复位按键为K8。67 表3.9单片机寄存器的复位状态表寄存器复位状态寄存器复位状态PC0000HTCON00HACC00HTH000HPSW00HTL000HSP07HTH100HDPTR0000HTL100HP1、P3FFHSCON00HIP××000000BSBUF不定IE0××00000BPCON0×××××××B(NMOS)TMOD00H0×××0000B(CHMOS)图3.13上电复位和按键复位电路67 第一章电子时钟软件设计C51单片机可以应用汇编语言和C语言进行编程。,汇编语言与机器指令一一对应所以用汇编语言编写的程序在单片机里运行起来效率较高。C语言程序可读性高,更便于理解。本设计使用C语言编程。1.1主程序设计第一次上电,系统先进行初始化,LED显示初始时间“14:28:00”,并开始走时。初始日期为2008年5月12日,此刻若按K1键,LED显示“080512”。单片机依次开始调用键盘扫描子程序、DS1302子程序、DS18B20子程序、闹铃子程序,经过延时,返回程序开头循环运行。主程序流程图如图4.1。图4.1多功能电子钟主程序流程图67 1.1子程序设计1.1.1实时时钟日历子程序设计该程序主要实现对DS1302写保护、充电,对年、月、日、时、分、秒等寄存器的读写操作。在读写操作子程序中都执行了关中断指令,因为在串行通信时对时序要求比较高,而且在此是用I/O口软件模拟串行时钟脉冲,所以在通信过程中最好保证传输的连续性,不要允许中断。其流程图如图4.2。图4.2实时时钟日历子程序流程图DS1302每次上电时自动处于暂停状态,必须把秒寄存器的位7置位0,时钟才开始计时。如果DS1302一直没有掉电,则不存在此问题。在进行写操作时,需要先解除写保护寄存器的“禁止”状态。当用多字节模式进行操作时,必须写够8字节。源程序见附录一。1.1.2显示子程序设计用74LS164驱动LED数码管静态显示电路,编程也很容易。只要将需要显示的数字编辑成对应的BCD码,逐位送入74LS164的A、B串行输入端,数码管将正常显示。关键之处是要实现根据键值显示不同的数字。67 为了方便实现按键显示,程序中调用的都是各个标志位,通过判断标志位的“真”、“假”来决定显示的内容。显示子程序流程图参见图4.4。源程序见附录一。1.1.1键盘扫描子程序单片机对键盘扫描的方法有随机扫描方式、定时扫描方式和中断扫描方式。在随机扫描方式中,CPU完成某特定任务后,即执行键盘扫描程序,以确定键盘有无按键输入,然后根据按键功能转去执行相应的操作。在执行键盘按键规定的功能中不理睬键盘输入。定时扫描方式与随机扫描方式基本相同,只是利用CPU内的定时中断,每隔一定时间扫描有无按键被按下,键盘反应速度较快,在处理按键功能过程中,可以通过键盘命令进行干预,如取消、暂停等操作。前两种扫描方式均会占用CPU大量时间。不管有没有键入操作,CPU总要在一定的时间内进行扫描,这对于单片机控制系统是很不利的。由于本设计中AT89C51单片机在系统中的主要任务是接受DS1302和DS18B20的数据并送出显示,完成时钟/日历校对和日期/温度显示控制。89C51单片机完全有能力完成以上工作,所以采用随机扫描键盘方式,系统也能够正常运行。程序流程如图4.5。单片机扫描完键盘,得到键值,并根据键值转入执行对应任务,以实现按键功能。如果没有按键按下,则程序扫描到Key=FFH,将键值Key清零,返回主程序。源程序见附录一。1.1.2闹铃子程序设计闹铃子程序最主要的任务是不断用时钟分(min)与时(hour)同设定的闹铃分(clk_min)与闹铃时(clk_hour)比较,只要满足min等于clk_min、hour等于clk_hour,响铃启动5分钟,并根据外部按键执行相应贪睡任务。该程序流程图参见图4.6。源程序见附录一。67 67 图4.4显示子程序流程图图4.5键盘扫描子程序67 67 图4.6闹铃子程序流程图图和图标要在同一页!67 第一章系统调试调试工作分硬件调试和软件调试两部分,调试方法介绍如下:首先,硬件调试主要是先搭建硬件平台,然后利用万用表等工具对电路检查,最后应用程序进行功能调试。硬件调试比较费时,需要细心和耐心,也需要熟练掌握电路原理。然后,可以直接应用一些编辑或仿真软件进行软件调试,比如单片机C51编辑软件Keil。该软件提供了一个集成开发环境uVision,它包括C编辑器、宏编辑器、连接器、库管理和一个功能强大的仿真调试器。通过编译、运行,可以检查程序错误。但应用此方法,仍需要十分了解所使用元器件的工作方式和管脚连接方式。在软件调试过程中要仔细耐心,即便是多写或少些一两个字符,都无法编译成功。而有时往往在Keil中编译、运行无错,但烧录到单片机中运行起来就会出错,很可能是编程时管脚或时序编辑得不对。还有一种方式,即应用仿真软件搭建电路的软件平台,再导入程序进行仿真调试。如果电路出错,可以在计算机上方便的修改电路,程序出错可以重新编辑程序,这种方法节时、省力,经济、方便。笔者应用的仿真软件为Proteus。总之,调试过程是一个软硬件相结合调试的过程,硬件电路是基础,软件是检测硬件电路和实现其功能的关键[13]。在调试过程中,首先必须明确调试顺序。例如:本设计是在单片机系统基础上建立起来的,所以必须先确定单片机基础电路能否正常工作。为了正确显示时间,接下来还要确定显示电路能否正常工作。硬件调试的过程,也是软件调试的过程。然后,要准备好调试的工具。67 硬件调试需要万用表、示波器等,软件调试一般需要诸如Keil等仿真编辑器。笔者根据自己实际制作该多功能电子时钟的经验,将调试过程介绍如下:1.1硬件调试1.1.1单片机基础电路调试单片机基础电路包括电源、单片机、外部时钟震荡电路、复位电路和外部接口电路。调试过程需要注意以下几点:1.检查电源是否完好。2.单片机电源要连接正确,并且保证AT89C51的31号引脚接高电平。AT89C51的31号引脚是外部程序存储器选择信号端,当该引脚为高电平时,单片机会一直从片内程序存储器内取指令。3.如果使用P0口做I/O口,要接上拉电阻。4.使用万用表排查电路中是否存在断路或者短路情况。笔者在制作外部接口电路时使用的是排针,焊接时容易出现管脚之间短路,所以在上电以前必须先排查电路。5.编辑一个使一组发光二极管循环点亮的程序并烧录到单片机内,上电运行,检查单片机是否正常工作,复位电路是否正确。笔者编辑了使一组P1口点亮8个发光二极管循环点亮的程序,程序代码如下:#includevoiddelay(void)//延时子程序{Unsignedchari,j,k;//延时时间根据变量i,j,k不同而改变for(i=50;i>0;i--)67 for(j=50;j>0;j--)for(k=250;k>0;i--);}voidmain(){unsignedintn;unsignedcharcodeledp[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};while(1){P1=0xFFH;//初始化P1口for(n=0;n<8;n++){P1=ledp[n];delay();}}}1.1.1显示电路调试本设计的显示电路使用了共阴LED和74LS164。在连接显示电路之前要明确共阴型8段LED的10个管脚与各段发光二极管的对应关系,熟悉74LS164管脚位置,然后才能开始进行连接[19]。在连接过程中,需要注意以下几点:1.LED数码管各管脚与74LS164各管脚的对应关系要十分清楚,所有LED数码管与74LS164的连接方式要统一。2.因为是移位显示,所以需要注意前一位74LS164的QH脚要与下一位74LS164的A、B脚连接。3.明确单片机管脚功能。本设计定义了P1.0连接74LS164的A、B脚,P1.1连接74LS164的CLK脚。67 4.74LS164的CLR脚接高电平。5.编写一段显示程序,烧录进单片机,检查好电源正负端和P1.0、P1.1连接是否正确。检查无误后上电,检查显示电路是否正确。以下是笔者编写的一段显示程序:上电后,7位数码管分别显示0~6。#include"reg51.h"#defineuintunsignedint#defineucharunsignedcharvoiddis();voidsendbyte();sbitDAT=P1^0;sbitCLK=P1^1;uchardisp_buffer[7];unsignedchartab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};voiddelay_50ms(unsignedintt)//延时子程序{unsignedintj;for(;t>0;t--)for(j=6245;j>0;j--){;}}voiddis()//显示子程序,0~6{unsignedchargsb,led,led1,jj;disp_buffer[0]=tab[0];67 disp_buffer[1]=tab[1];disp_buffer[2]=tab[2];disp_buffer[3]=tab[3];disp_buffer[4]=tab[4];disp_buffer[5]=tab[5];disp_buffer[6]=tab[6];for(gsb=0;gsb<7;gsb++){led=disp_buffer[gsb];for(jj=0;jj<8;jj++){led1=led&0x1;if(led1==0x1)DAT=1;elseDAT=0;CLK=0;CLK=1;led=led>>1;}}}voidmain()//主程序{while(1){dis();delay_50ms(10);}}67 1.1.1DS1302电路调试该电路包含DS1302芯片、主电源、备用电源、晶振等部分。在与单片机连接的过程中需要注意以下几点:1.清楚DS1302与单片机连接的管脚。本设计定义为:DS1302的SCLK连接P1.5,I/O连接P1.6,RST连接P1.7。2.注意电源正负极连接。3.DS1302接32.768KHz的晶振。该晶振体型比较小,在焊接时要小心,注意不要将晶振引脚弄断。同时也要尽量使晶振离DS1302的X1、X2引脚近距离焊接。4.编写DS1302的时钟/日历程序,只要求能够正确显示时间。烧录进单片机,检查电路电源正负极连接是否正确,检查P1.0和P1.1引脚接线是否正确。检查无误后可以上电检查。笔者编写了一段时钟/日历显示程序,设置初始时间为14:28:00,初始日期为2008年5月12日。上电后LED数码管显示“142800”,之后开始走时。观察32分钟之后,数码管显示“150000”,证明DS1302电路正确。源程序见附录A1.1.2按键电路调试按键电路比较简单,故调试起来也很容易。如果确保按键焊接正确,只需在DS1302的调试程序上加上一段日历显示子程序,并在主程序中写入:If(P_7==0){dis_calendar;}日历显示子程序原理与时钟显示子程序原理相同,源程序见附录A该程序的功能是:67 当按下K7时,第1~6位LED数码管马上由时间显示日期。当K7弹出后,数码管1~6位有显示日期转为显示实时时间[20]。1.1软件调试在硬件调试完毕的基础上,需要进一步完善程序,也就是进入软件调试阶段。在本设计中,软件调试主要分三大部分:实时时钟日历子程序调试、环境温度采集子程序调试、按键子程序调试。将这三部分调试成功,那么整个设计的软件部分也就基本完成了。在硬件调试部分,已经将实时时钟日历子程序调试完毕了,只需在主程序中调用按键子程序即可,源程序见附录A,这里不再赘述。1.1.1键盘子程序调试依据设计要求,键盘子程序需要完成对时间/日历的校对、日期/温度的显示和闹铃的开关。为了便于显示子程序和闹铃子程序的调用,除了K1、K2键以外,其余按键都定义功能标志位。例如:If(K7==0){alarm_flag=true;}在调用闹铃子程序时,闹铃标志位为“1”,则开启闹铃,否则关闭闹铃。源程序见附录A。窗体底端67 结论过去人们应用时钟仅仅是为了明确当前时间。随着生产力的发展,社会的进步,生产生活对时钟的需求越来越大,对时钟的体型、功能的要求也各有不同。所以多功能电子时钟在今后的应用也会越来越广泛。基于单片机实现电子时钟,仅仅是众多方法之一。并且市场上的实时时钟日历芯片品类繁多,IC化的传感器各种各样,显示方式也愈趋于人性化。所以多功能电子时钟有多种实现方案,能够实现的功能也很多,笔者已经通过仿真和调试,实现了时间日历显示和校对、闹铃等功能。本文采用51单片机C语言进行编程,当然也可以应用汇编语言编程。由于笔者能力有限,提供的程序还可以进一步优化,并且还可以根据需求为电子时钟增设新功能。67 参考文献1.向继文等.基于AT89C51的电子钟系统设计[J],机电产片开发与创新,2007年第2期2.黄智伟,王彦.FPGA系统设计与实践[M],北京:电子工业出版社,2005.13.刘皖等.FPGA设计与应用[M],北京:清华大学出版社,2006,64.姜煜等.基于FPGA芯片设计多功能数字钟的研究[J],应用科技,2001年12月第28卷12期5.冯育长.单片机系统设计与实例分析[M],西安:西安电子科技大学出版社,2007.56.李及,赵利民.MCS-51系列单片机原理与应用[M].长春:吉林科学技术社,1995.7.何力民.单片机应用技术选编5[M],北京:北京航空航天大学出版社1997.108.潘永雄.新编单片机原理与应用[M],西安:西安电子科技大学出版社,2003.2.9.万胜前.基于KeilC51软件的电子钟设计与制作[J],鄂州大学学报,2007年第2期10.蒋敏.单片微机万年历设计[J],职大学报,2000年第2期11.彭小军.用单片机实现电子时钟[J].新余高专学报,2004年4月第9卷第2期12.逢玉台等.集成温度传感器AD590及其应用[J],国外电子元器件,2002年第7期13.戴佳,戴卫恒.51单片机C语言应用程序设计实例精讲[M],北京:电子工业出版社,2006.414.付家才.单片机控制工程实践技术[M],北京:化学工业出版社,2004.3.15.刘军等.单片机原理与接口技术[M],上海:华东理工大学出版社,2006.2.16.何书森等.用电子线路设计速成[M],福州:福建科学技术出版社,2005.10.17.李晓静等.液晶显示控制器与单片机的接口及编程[J],电子技术,2004年第6期18.张迎新.单片微型计算机原理、应用及接口技术(第二版)[M],北京:国防工业出版社,2005.919.潘新民,王艳芳.微型计算机控制技术[M],北京:电子工业出版社,2004.67 20.沈红卫.基于单片机的智能系统设计与实现[M],北京:电子工业出版社,2005.1.67 附录一程序程序A.1主程序//主程序的功能是对子程序进行调用,并设定显示延时时间#include"reg51.h"//头文件;#include"typedef.h"#include"lcd.h"#include"key.h"#include"alarm_clock.h"#include"ds1302.h"sbitDAT=P1^0;//74LS164的A、B脚接单片机P1.0;sbitCLK=P1^1;//74LS164的CLOCK脚接单片机P1.1;sbitCalendar=P2^7;//定义日历显示按键K7接单片机P2.7;sbitWDZ=P2^6;//定义温度显示按键K6接单片机P2.6;sbitFUN=P2^5;//定义功能选择键K5接单片机P2.5;sbitUP=P2^4;//定义加1键K4接单片机P2.4;sbitDOWN=P2^3;//定义减1键K3接单片机P2.3;sbitEnte_Snooze=P2^2;//定义确认/贪睡键K2接单片机P2.2;sbitAlarm=P2^1;//定义闹铃开关键K1接单片机P2.1;sbitbeeper=P2^0;//定义闹铃接口P2.0;#defineuintunsignedint#defineucharunsignedchar67 #definetrue1//定义true=1;#definefalse0//定义false=0;#defineFUNCTION0xDF//定义FUN键值为DFH;#defineUP0xEF//定义UP键值为EFH;#defineDOWN0xF7//定义DOWN键值为F7H;#defineALARM0xFB//定义ALARM键值为FBH;#defineEnte_Snooze0xFB//定义E/S键值为BFH;voidkey_task(void);voidprocess(ucharcurrent_key);externbitflash_flag;//定义全局变量(标志位);externucharfunction_count;externbitalarm_flag;externbitkey_enable;voiddis();voidsendbyte();voidreset_3w();voidwbyte_3w(uchar);ucharrbyte_3w();voidwrite_byte(ucharClock_Add,ucharClock_Data);ucharread_byte(uchar);voidwrite_clock_burst();voidds1302_init();67 voidds1302_task();voidlcd_disp_time1();voiddis_WD();voidds18b20();voidalarm_clock(void);voiddelay(unsignedinttime)//10ms延时{unsignedchara,b,c;for(a=0;a>=1;}}ucharrbyte_3w()//读字节子程序{uchari;ucharR_Byte;ucharTmpByte;R_Byte=0x00;IO=1;for(i=0;i<8;i++){SCLK=1;SCLK=0;TmpByte=(uchar)IO;TmpByte<<=7;R_Byte>>=1;R_Byte|=TmpByte;}returnR_Byte;}voidwrite_byte(ucharClock_Add,ucharClock_Data){reset_3w();wbyte_3w(Clock_Add);67 wbyte_3w(Clock_Data);reset_3w();}voidwrite_clock_burst(){reset_3w();//复位wbyte_3w(CLOCK_BURST_ADD);//写多字节传送模式寄存器wbyte_3w(hex2bcd[sec]);//写入初始化时间wbyte_3w(hex2bcd[min]);wbyte_3w(hex2bcd[hour]);wbyte_3w(hex2bcd[date]);wbyte_3w(hex2bcd[month]);wbyte_3w(hex2bcd[day_of_week]);wbyte_3w(hex2bcd[year]);wbyte_3w(0);/*mustwritecontrolregisterinburstmode*/reset_3w();}ucharread_byte(ucharClock_Add)//从DS1302读一个字节{ucharClock_Data;reset_3w();wbyte_3w(Clock_Add);Clock_Data=rbyte_3w();reset_3w();return(Clock_Data);}67 voidds1302_init()/*---initializetime&datefordefaultvalue---*/{reset_3w();wbyte_3w(0x8e);//写保护寄存器wbyte_3w(0);//去保护reset_3w();wbyte_3w(0x90);//写涓流充电寄存器wbyte_3w(0xab);//开涓流充电,在VCC1和VCC2之间串入2个二极管,8KΩ电阻write_clock_burst();//写入初始化时间}voidds1302_task(){if(!key_enable){sec=bcd2hex[read_byte(READ_SEC_ADD)];//读DS1302secmin=bcd2hex[read_byte(READ_MIN_ADD)];//读DS1302minhour=bcd2hex[read_byte(READ_HOUR_ADD)];//读DS1302hourdate=bcd2hex[read_byte(READ_DATE_ADD)];day_of_week=bcd2hex[read_byte(READ_DOW_ADD)];month=bcd2hex[read_byte(READ_MONTH_ADD)];//读DS1302monthyear=bcd2hex[read_byte(READ_YEAR_ADD)];//读DS1302year}}程序A.3键盘子程序//主要是用于对时间的设定与调整#include"reg51.h"67 #include"typedef.h"#include"key.h"#include"ds1302.h"uintwait_time;bitkey_enable;bitflash_flag;bitalarm_flag;ucharflash_count;ucharfunction_count=0;ucharkey;ucharkey_push;ucharkey_l;voidkey_scan()//扫描键盘;{ucharl,a,PUSH;PUSH=P2&0xFF;if(PUSH!=0xFF){for(l=500;l>0;l--)//延时;for(a=50;a>0;a--);if(PUSH!=0xFF){key_push=P2&0xFF;key=key_push;//key等于键值;}}}67 voidprocess(ucharcurrent_key)//按键功能子程序;{switch(current_key){caseFUNCTION://功能选择键;{key_enable=true;function_count=function_count+1;if(function_count>=9)function_count=1;}break;caseUP://加1操作键;{if(function_count==1)//function_count=1,则秒加1操作;{sec++;if(sec>=60)//秒加到60,则被置0;sec=0;write_byte(WRITE_SEC_ADD,hex2bcd[sec]);//写入秒寄存器;}if(function_count==2)//function_count=2,则分加1操作;{min++;if(min>=60)//分加到60,则被置0;min=0;write_byte(WRITE_MIN_ADD,hex2bcd[min]);//写入分寄存器;}elseif(function_count==3)//function_count=3,则小时加1操作;67 {hour++;if(hour>=24)//小时加到24,则被置0;hour=0;write_byte(WRITE_HOUR_ADD,hex2bcd[hour]);//写入小时寄存器;}elseif(function_count==4)//function_count=4,则闹铃分钟加1操作;{clk_min++;if(clk_min>=60)//分钟加满60自动置0;clk_min=0;}elseif(function_count==5)//function_count=5,则闹铃小时加1操作;{clk_hour++;if(clk_hour>=24)//小时加满24自动置0;clk_hour=0;}elseif(function_count==6)//function_count=6,则年加1操作;{year++;if(year>99)year=0;write_byte(WRITE_YEAR_ADD,hex2bcd[year]);}}elseif(function_count==7)//function_count=7,则月加1操作;{month++;if(month>=13)67 month=1;write_byte(WRITE_MONTH_ADD,hex2bcd[month]);}elseif(function_count==8)//function_count=8,则日加1操作;{date++;if(date>=31)date=0;write_byte(WRITE_DATE_ADD,hex2bcd[date]);}break;caseDOWN://键盘减1操作功能{if(function_count==1){if(sec==0)sec=60;--sec;write_byte(WRITE_SEC_ADD,hex2bcd[sec]);}if(function_count==2){if(min==0)min=60;--min;write_byte(WRITE_MIN_ADD,hex2bcd[min]);}elseif(function_count==3){if(hour==0)hour=24;67 --hour;write_byte(WRITE_HOUR_ADD,hex2bcd[hour]);}elseif(function_count==4){if(clk_min==0)clk_min=60;--clk_min;}elseif(function_count==5){if(clk_hour==0)clk_hour=24;--clk_hour;}elseif(function_count==6){if(year==0)year=100;--year;write_byte(WRITE_YEAR_ADD,hex2bcd[year]);}elseif(function_count==7){if(month==1)month=13;--month;write_byte(WRITE_MONTH_ADD,hex2bcd[month]);}elseif(function_count==8){if(date==0)67 date=31;--date;write_byte(WRITE_DATE_ADD,hex2bcd[date]);}break;caseALARM:{alarm_flag=(~alarm_flag);}break;caseEnte_Snooze{Time=true;//确认键;if((alarm_flag==true)&(clk_hour==hour)&(clk_min==min))//贪睡功能;{clk_min=clk_min+5;}}default:break;}}voidkey_task(){key_scan();if(key==0x29){wait_time=wait_time+1;if(wait_time==3){wait_time=0;key_enable=false;}}elsewait_time=0;67 if(function_count!=0){flash_count++;if(flash_count<20)flash_flag=true;elseif((flash_count>20)&&(flash_count<40))flash_flag=false;if(flash_count>=40)flash_count=0;}process(key);if(Calendar==0)//如果K7按下,显示日期;{dis_Calendar();}elseif(WDZ==0)//如果K6按下,显示温度;{voiddis_WD();}if(Time=true)//如果按下确认键,直接显示时间;{disp_time();}key=0;}程序A.4闹铃程序主要是设定闹铃的条件#include"reg51.h"#include"typedef.h"#include"lcd.h"#include"alarm_clock.h"#include"key.h"67 ucharfreq_count;voidalarm_clock(){unsignedchara,b,c;if((alarm_flag==true)&(clk_hour==hour)&(clk_min==min)){freq_count++;if(freq_count<30){beeper=false;}for(a=0;a<2;a++)for(b=0;b<10;b++)for(c=0;c<120;c++);if(freq_count>=30){beeper=true;}if(freq_count==100)freq_count=0;}}程序A.5显示程序//当符合不同的条件时,该程序使数码管显示不同的数据;#include"reg51.h"#include"typedef.h"#include"lcd.h"#include"key.h"ucharsec=45;ucharmin=0;67 ucharhour=8;uchardate=1;ucharmonth=1;ucharyear=6;ucharday_of_week;//2006-01-01Sun00:00:00ucharclk_hour=8;ucharclk_min=1;//08:00uchardisp_buffer2[7];unsignedchardis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x08,0x40,0x01};//低中高voiddisp_time(void){unsignedchargsb,led,led1,jj;if(function_count<=1){if((flash_flag==true)&&(function_count==1))//时显示{disp_buffer[0]=dis[3];disp_buffer[2]=dis[hour%10];//正常显示disp_buffer[1]=dis[hour/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}else67 {if(alarm_flag==true)//闹钟开关显示disp_buffer[0]=dis[12];elseif(function_count==0)disp_buffer[0]=0;disp_buffer[2]=dis[hour%10];disp_buffer[1]=dis[hour/10];}if((flash_flag==true)&&(function_count==2))//分显示{disp_buffer[0]=dis[2];disp_buffer[4]=dis[min%10];//正常显示disp_buffer[3]=dis[min/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}else{disp_buffer[4]=dis[min%10];disp_buffer[3]=dis[min/10];}if((flash_flag==true)&&(function_count==3))//秒显示{disp_buffer[0]=dis[3];disp_buffer[6]=dis[sec%10];//正常显示disp_buffer[5]=dis[sec/10];if(key_enable==false)67 {function_count=0;disp_buffer[0]=dis[11];}}else{disp_buffer[6]=dis[sec%10];disp_buffer[5]=dis[sec/10];}for(gsb=0;gsb<7;gsb++){led=disp_buffer[gsb];for(jj=0;jj<8;jj++){led1=led&0x1;if(led1==0x1)data_led=1;//DATA=1elsedata_led=0;//DATA=0clk_led=0;clk_led=1;//clk=0~1led=led>>1;}}}elseif(function_count>3){if((flash_flag==true)&&(function_count==4))//约定时间设置{disp_buffer2[1]=dis[11];disp_buffer2[2]=dis[11];disp_buffer2[3]=dis[11];disp_buffer2[4]=dis[11];67 disp_buffer2[0]=dis[4];disp_buffer2[6]=dis[clk_min%10];//预约分正常显示disp_buffer2[5]=dis[clk_min/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}if((flash_flag==true)&&(function_count==5)){disp_buffer2[1]=dis[11];disp_buffer2[2]=dis[11];disp_buffer2[5]=dis[11];disp_buffer2[6]=dis[11];disp_buffer2[0]=dis[5];disp_buffer2[4]=dis[clk_hour%10];//预约时正常显示disp_buffer2[3]=dis[clk_hour/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}if((flash_flag==true)&&(function_count==8))//日设置{disp_buffer2[1]=dis[11];disp_buffer2[2]=dis[11];disp_buffer2[3]=dis[11];disp_buffer2[4]=dis[11];67 disp_buffer[0]=dis[6];disp_buffer2[6]=dis[date%10];//日正常显示disp_buffer2[5]=dis[date/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}if((flash_flag==true)&&(function_count==7))//月设置{disp_buffer2[1]=dis[11];disp_buffer2[2]=dis[11];disp_buffer2[5]=dis[11];disp_buffer2[6]=dis[11];disp_buffer2[0]=dis[7];disp_buffer2[4]=dis[month%10];//月正常显示disp_buffer2[3]=dis[month/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}if((flash_flag==true)&&(function_count==6))//年设置{disp_buffer2[5]=dis[11];disp_buffer2[6]=dis[11];disp_buffer2[3]=dis[11];disp_buffer2[4]=dis[11];67 disp_buffer2[0]=dis[8];disp_buffer2[2]=dis[year%10];//年正常显示disp_buffer2[1]=dis[year/10];if(key_enable==false){function_count=0;disp_buffer[0]=dis[11];}}for(gsb=0;gsb<7;gsb++){led=disp_buffer2[gsb];for(jj=0;jj<8;jj++){led1=led&0x1;if(led1==0x1)data_led=1;//DATA=1elsedata_led=0;//DATA=0clk_led=0;clk_led=1;//clk=0~1led=led>>1;}}}}voiddis_Calendar()//显示日历子程序{unsignedchargsb,led,led1,jj;disp_buffer[2]=tab[hour%10];67 disp_buffer[1]=tab[hour/10];disp_buffer[4]=tab[min%10];//正常显示disp_buffer[3]=tab[min/10];disp_buffer[6]=tab[sec%10];//正常显示disp_buffer[5]=tab[sec/10];for(gsb=0;gsb<7;gsb++){led=disp_buffer[gsb];for(jj=0;jj<8;jj++){led1=led&0x1;if(led1==0x1)DAT=1;//DATA=1elseDAT=0;//DATA=0CLK=0;CLK=1;//clk=0~1led=led>>1;}}}}67 附录二多功能电子时钟元器件一览表窗体顶端类别序号型号数量(单位)用途单价(¥)电源1+5V电池1个系统电源3.0元2+3V电源(纽扣式)1个时钟备用电源4.0元IC芯片3AT89S511片CPU15.0元4DS13021片实时时钟日历芯片3.0元574LS1647片8位移位寄存器1.5元LED6共阴8段数码显示7只时间和温度显示1.0元按键12自锁/自动复位8个功能键盘0.5元电容1330pF2个单片机时钟震荡电路0.1元1410μF1个复位电路0.2元晶振1511.0592MHz1支单片机时钟震荡电路0.5元1632.768KHz1支DS1302时钟震荡电路1.0元电阻17300KΩ7支限制LED亮度0.05元18100Ω1支复位电路0.05元1910KΩ2支限压保护0.05元三极管20S90121个闹铃电路0.3元蜂鸣器2174F3781个闹铃电路1.0元面薄板22焊接性2块基础电路和显示电路3.0元总计:64.2元67 附录三多功能电子时钟硬件原理图67 67 致谢在论文完成之际,我要特别感谢我的指导老师张翠侠的热情关怀和悉心指导。在我撰写论文的过程中,张老师倾注了大量的心血和汗水,无论是在论文的选题、构思和资料的收集方面,还是在论文的研究方法以及成文定稿方面,我都得到了张老师悉心细致的教诲和无私的帮助,特别是她广博的学识、深厚的学术素养、严谨的治学精神和一丝不苟的工作作风使我终生受益,在此表示真诚地感谢和深深的谢意。在论文的写作过程中,也得到了许多同学的支持和帮助,给予了我很多宝贵的意见,在此一并致以诚挚的谢意。感谢所有关心、支持、帮助过我的良师益友。最后,向在百忙中抽出时间对本文进行评审并提出宝贵意见的各位老师表示衷心地感谢!67'