电子时钟万年历设计
基于单片机的电子万年历设计

基于单片机的电子万年历设计一、概述随着科技的快速发展和人们对生活品质的追求,电子设备在日常生活中扮演着越来越重要的角色。
电子万年历作为一种集日期、时间显示于一体的实用电子产品,已经深入到人们的日常生活和工作中。
传统的机械式日历已经无法满足现代人对时间精确性和功能多样性的需求,基于单片机的电子万年历设计应运而生,成为了当前研究的热点之一。
基于单片机的电子万年历设计,旨在利用单片机(如STC89CAT89C51等)的强大计算和控制能力,结合液晶显示屏(LCD)、按键输入等外设,实现时间的准确显示、日期的自动更新、闹钟提醒、温度显示等多样化功能。
该设计不仅具有高度的集成性和可靠性,而且能够通过编程实现各种定制化的功能,满足不同用户的需求。
本文将对基于单片机的电子万年历设计进行详细的介绍和分析,包括设计思路、硬件组成、软件编程等方面。
通过本文的阅读,读者可以了解电子万年历的基本原理和设计方法,掌握单片机在电子万年历设计中的应用技巧,为实际的开发工作提供有益的参考和借鉴。
1.1 研究背景与意义随着科技的不断进步,人们日常生活和工作中对于时间的精度和便捷性的要求日益提高。
传统的机械式日历和简单的电子时钟已经无法满足现代生活的需求。
电子万年历作为一种集时间显示、日历查询、定时提醒等多功能于一体的电子装置,在日常生活、工作乃至科研领域都具有广泛的应用价值。
基于单片机的电子万年历设计,不仅可以提供准确的时间显示,还能实现复杂的日期计算、农历显示、节假日提示等功能,极大地提高了时间管理的效率和便捷性。
单片机作为一种集成度高、功耗低、价格适中的微型计算机,非常适合用于小型化、智能化的电子产品设计,如电子万年历。
本研究的意义在于,通过对基于单片机的电子万年历的设计研究,可以推动微型计算机技术和电子时钟技术的融合发展,提升电子产品的智能化水平,满足人们日益增长的生活和工作需求。
同时,该研究还可以为相关领域的技术人员提供参考和借鉴,推动电子万年历产品的不断创新和优化。
单片机万年历电子钟设计报告含电路图和源程序

万年历设计报告学院:武夷学院班级:09电信1班组员:林巧文一、设计要求与方案论证21.1 设计要求:21.1.1根本要求21.1.2发挥局部21.2 系统根本方案选择和论证21.2.1单片机芯片的选择方案和论证:21.2.2 显示模块选择方案和论证:21.2.3时钟芯片的选择方案和论证:31.3 电路设计最终方案决定3二、理论分析与计算32.1,秒数的产生由定时器T0产生:3三.系统的硬件设计与实现43.1 电路设计框图:43.2 系统硬件概述:43.3 主要单元电路的设计53.3.1单片机主控制模块的设计53.3.2显示模块的设计53.3.3闹钟模块的设计73.3.4电源稳压模块7四、系统的软件设计74.1程序流程框图74.2闹钟模块流程图:74.3按键调整模块流程图:7五、测试方案与测试结果分析75.1 测试仪器 (7)5.2软件测试平台 Keil C5185.3 模块测试85.3.1显示模块测试85.4测试结果分析与结论85.4.1测试结果分析85.4.2 测试结论 (8)六、作品总结9参考文献9附录一:系统电路图9附录三:系统C程序10一、设计要求与方案论证1.1 设计要求:根本要求〔1〕准确显示:时、分、秒〔24小时制〕〔2〕显示星期〔3〕显示公历〔4〕时间、日期、星期可调节〔5〕断电记忆功能发挥局部〔1〕闹钟功能〔2〕显示阴历〔3〕显示24节气〔4〕其他1.2 系统根本方案选择和论证单片机芯片的选择方案和论证:方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术, 当在对电路进展调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的屡次拔插会对芯片造成一定的损坏。
方案二:采用AT89S52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进展调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片屡次拔插,所以不会对芯片造成损坏。
电子万年历的设计

三、硬件设计
LED数码管动态 数码管动态 扫描显示模块 AT89S52 主控制 模块 温度采集模块 键盘模块
DS1302时钟模块 时钟模块
主控制系统图
键盘模块
日期和时间的修改由3 个按键构成。 键1为向右移; 键2为加1; 键3为减1。
DS1302的引脚图
返回
ds1302内部结构
温度采集模块
谢谢大家 欣赏
数字式温度传感器DS18B20, 它是数字式温度传感器, 具有测量精度高,电路连 接简单特点,此类传感器 仅需要一条数据线进行数 据传输,使用P0.7与 DS18B20的I/O口连接加一 个上拉电阻,Vcc接电源 ,Vss接地
I/O
vss
vcc
返回
LED动态扫描显示模块 动态扫描显示模块
系统电路图
一.设计要求
具有年、 具有年、月、日、星期、时、分、秒等功 星期、 能; 时间与阴、阳历能够自动关联; 时间与阴、阳历能够自动关联; 具备年、 星期、 具备年、月、日、星期、时、分、秒校准 功能; 功能; 具有温度计功能; 具有温度计功能;
二、基本方案
采用AT89S52作为主控制系统 作为主控制系统 采用 采用DS1302提供时钟 提供时钟 采用 采用数字式温度传感器DS18B20 采用数字式温度传感器 采用LED数码管动态扫描作为显示 数码管动态扫描作为显示 采用
1.
六、总结
通过此次毕业设计, 通过此次毕业设计,我 不仅把知识融会贯通, 不仅把知识融会贯通,而且 丰富了大脑, 丰富了大脑,同时在查找资 料的过程中也了解了许多课 外知识,开拓了视野, 外知识,开拓了视野,认识 了将来电子的发展方向, 了将来电子的发展方向,使 自己在专业知识方面和动手 能力方面有了质的飞跃。 能力方面有了质的飞跃。
多功能时钟(万年历)设计

多功能时钟(万年历)设计报告专业电子信息科学与技术班级13级电子专升本姓名韩科峰学号130522012考勤成绩设计成绩调试成绩报告成绩总成绩一、课题名称多功能时钟(万年历)设计二、内容摘要美国DALLAS公司推出的具有涓细电流充电能的低功耗实时时钟电路DS1302。
它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
本设计是基于单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。
在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。
关键词:三、设计指标(要求);1、显示时间、日期由按键选择显示(日期时间可调整)。
2、可设置闹钟功能;3、制作PC机设置界面软件,由PC机可完成对时钟的各项设置四、系统框图;STC12C5A08S2单片机DS1302时钟模块五、各单元电路设计、参数计算和元器件选择4位共阴极数码管按键六、工作原理DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲;DS1302的控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。
对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0,位1至位5指操作单元的地址。
位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。
控制字节总是从最低位开始输入/输出的。
“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。
万年历电子钟设计论文

目录摘要万年历电子钟是一种非常广泛的日常计时工具,在现代社会生活中越来越流行。
它可以对年、月、日、周、时、分、秒进行计时,还具有闰年补偿等多种功能。
万年历电子钟设计是基于单片机进行的,可以显示年、月、日、时、分、秒、周及温度信息,具有可调整日期和时间功能。
设计包含STC89C52单片机模块、LED数码管模块、键盘模块、DS1302时钟模块、闹钟控制模块。
STC89C52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
LED数码管动态扫描,对于显示数字最合适,价格适中,而且采用动态扫描法与单片机连接时,占用的单片机口线少。
DS1302的使用寿命长,误差小。
对于万年历电子钟采用直观的数字显示,可以同时显示年、月、日,周日,时、分、秒等信息,还具有时间校准,闹钟,闹钟状态校准等功能。
关键词:STC89C52,DS1302,74HC164,LED数码管一.设计要求与方案论证1.1 设计要求1.1.1基本要求(1)具有年、月、日、星期、时、分、秒等功能;(2)时间与阴、阳历能够自动关联;(3)具备年、月、日、星期、时、分、秒校准功能;2. 发挥部分:(1)增加闹钟二.电子万年历硬件设计与实现2.1 电子万年历系统设计2.1.1系统设计框图2.1.2 系统硬件概述本电路是由STC89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;本源程序采用DS1302做专用的走时,停电后也可以正常走时90天以上;本源程序充分利用了STC89C51的新功能,设定的定时控制数据可以停电10年不丢失;本程序设计了误差自动校正,如果因为晶振的误差导致一天走时快1秒或者慢1秒的话,本程序每天都会在深夜自动校正后再在正确时间基础上计时;本程序还设计了快速走时摸拟运行状态(是正常走时的100倍以上);本程序还有6位数的阳历年月日显示,既可以当日历还可以当电子钟,也有6位数字显示时间。
2.2系统硬件各模块作用2.2.1单片机主控制模块功能特性描述STC89C52是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。
多功能电子钟及万年历毕业设计

3........................................................... 16
3.7.3 DS18B20 接口电路设计............................................................................ 17
2.1 设计任务分析.................................................................................................... 5
2.2 方案论证与选择................................................................................................ 5
2.2.1 电路择方案................................................................................................. 5
2.2.2 单片机主芯片选择方案............................................................................. 5
1.1 设计概述............................................................................................................ 3
1.2 设计目标与意义................................................................................................ 3
基于单片机的电子时钟万年历设计

(2)31 8 位暂存数据存储RAM(3)串行 I/O 口方式使得管脚数量最少(4)宽范围工作电压2.0 5.5V(5)工作电流 2.0V 时,小于300nA(6)读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式(7)8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配(8)简单 3 线接口(9)与 TTL 兼容Vcc=5V(10)可选工业级温度范围-40~+85优点:串行接口的日历时钟芯片,使用简单,接口容易,与微型计算机连线较少等特点,在单片机系统尤其是手持式信息设备中己得到了广泛的应用。
所以,最终选择串行时钟芯片DS1302,DS1302的管脚图如图2所示。
图2 DS1302管脚图1.2显示模块选择方案一:LED数码管显示数码管显示比较常用的是采用CD4511和74LS138实现数码转换,数码显示分动态显示和静态显示,静态显示具有锁存功能,可以使数据显示得很清楚,但浪费了一些资源。
目前单片机数码管普通采用动态显示。
编程简单,但只能显示数字,不能显示中文。
方案二:LCD1602能够显示英文和数字。
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
所以最终选择LCD1602。
2.项目功能模块2.1 89C51模块Mcs-51单片机管脚图图如图3所示:单片机管脚图2.2 1602液晶显示模块1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
毕业设计万年历功能电子时钟的设计

摘要单片机应用技术飞速发展,纵观我们现在生活的各个领域,从导弹的导航装置,到飞机上各种仪表的控制,从计算机的网络通讯与数据传输,到工业自动化过程的实时控制和数据处理,以及我们生活中广泛使用的各种智能IC卡等,这些都离不开单片机。
单片机是集CPU ,RAM ,ROM ,定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。
而51系列单片机是各单片机中最为典型和最有代表性的一种。
这次毕业设计通过对它的学习,应用,从而达到学习、设计、开发软、硬的能力。
本文以单片机为核心,采用串行时钟芯片DS1302。
过去多用并行接口的时钟芯片,如MC146818、DS12887 等。
它们已能完全满足单片机系统对实时时钟的要求,但是这些芯片与单片机接口复杂、占用地址, 数据总线接线多、芯片体积大占用空间多。
显示电路采用LED动态扫描方式,动态扫描方式节省外部接口资源。
本文通过对一个基于单片机的能实现万年历功能电子时钟的设计,从而达到学习、了解单片机相关指令在各方面的应用。
系统由主控制器A T89C52、时钟电路DS1302、显示电路、按键电路、和复位电路等部分构成,能实现时钟日历显示的功能,能进行年、月、日、时、分及星期的显示。
关键词:AT89C52芯片DS1302芯片C语言Keil软件LED动态显示;AbstractSCM rapid development of applied technology, we now live Looking at the various fields, from the missile's navigation devices, to the various instruments on the aircraft control, computer network communications and data transmission, industrial automation to the process of real-time control and data Processing, and we live in the extensive use of the smart IC cards, these are inseparable from the SCM. S CM is set CPU, RAM, ROM, timing, counting on one interface and a variety of microcontrollers. Its small size, low cost, feature strong, smart widely used in industry and industrial automation. And 51 of the SCM SCM is the most typical and most representative one. The graduation project through its study, and thereby to study, design, develop software and hardware capabilities.Based on SCM as the core, a serial clock chip DS1302. Past the use of parallel interface chip's clock, such as the MC146818, DS12887, and so on. They have been able to fully meet the SCM system to the requirements of real-time clock, but these chips and microcontroller interface complex, occupied address, data bus wiring, chip size of the space and more. LED display circuit using dynamic scan mode, dynamic scan mode external interface save resources.Based on a microcontroller based on the calendar function to achieve the design of electronic clock, so as to achieve learning and understanding of SCM related instructions in all aspect s of the application. System by the main controller AT89C52, clock circuit DS1302, show circuit, the circuit keys, and reset circuit, and other components, to achieve the clock showed that the calendar function, capable of year, month, day, hour, minute an d weeks of shows.Key W ords:AT89C52 Chip DS1302 Chip Keil C language software LED dynamic display;目录摘要 (I)Abstract (II)目录........................................................................................................... 错误!未定义书签。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学与技术学院硬件课程设计报告在日常生活中,手表,闹钟是不可或缺的。
在实际生活生产活动中,也要考虑时间的因素,如工时的计算,霓虹灯的亮灭。
因为集成电路制造技术的不断提高,出现了高性能、高可靠的集成芯片。
电子时钟在工业领域,日常生活中得到了广泛的应用。
电子时钟在性能方面具有精度高,实时性好,易于调整等优点。
这些使得温度控制系统的研究和开发得到的各方面的广泛关注和支持。
本次课程设计,我利用8254计数芯片,8255芯片,4*4小键盘,12864LCD 液晶显示器,蜂鸣器制作了一个带有闹钟功能的电子时钟万年历。
它可以实现由4*4小键盘输入初始时间(包括年月日时分秒星期),利用8254计数,通过程序处理进位,判断闰年,在液晶显示屏上实时显示时间。
还可以由小键盘选择不同的闹钟模式,设定闹钟时间。
关键词:电子时钟; 8255A芯片; 8254芯片; 12864LCD液晶显示器;键盘输入;蜂鸣器;闹钟功能;万年历1.设计任务与要求...........................................................................6- 1.1实验目的 (6)1.2具体要求 (6)2.总体方案与说明...........................................................................6- 2.1使用硬件 (6)2.1流程设计 (6)2.1.1系统程序模块 (6)2.1.1系统流程图 (7)3.硬件方案 (7)3.1硬件说明 (7)3.1.1计数芯片8254 (7)3.1.2可编程外围接口芯片8255A (8)3.1.2 128×64字符液晶显示器 (11)3.2电路原理图与说明 (12)3.2.1键盘电路 (13)3.2.2 8254计数电路 (13)3.2.3 液晶显示电路 (14)3.3电路连接图 (14)3.3.1 8254计数芯片 (14)3.3.2 整体电路 (15)4.软件方案 (15)4.1软件主要模块流程图 (15)4.1.1输入子程序模块流程图 (16)4.1.2显示子程序模块流程图 (18)4.1.2闰年子程序模块流程图 (18)4.1.2蜂鸣器子程序模块流程图 (18)4.1.2时间进位程序模块流程图 (19)4.1.2主程序模块流程图 (20)4.2源程序清单与注释 (21)5.分析与测试 (38)6.运行结果 (38)6.1试验线路图 (39)6.2实验结果 (39)6.2.1欢迎界面 (39)6.2.2闹钟设定界面 (40)6.2.3闹钟功能实现 (41)6.2.4闰年功能实现 (41)7.结论与体会 (43)7.1结论 (43)7.2体会 (44)参考文献 (45)-1 设计任务与要求1.1实验目的1.复习8255芯片,8254芯片工作原理及使用方法2.学会使用12864字符液晶显示屏,蜂鸣器3.锻炼小规模逻辑电路设计4.提高分析、解决问题的能力1.2具体要求本系统要求能通过4*4键盘输入预设时间,实时反映当前时间的变化并能对闰年进行准确判断。
另外,当时间与预先设置的闹钟时间相同时,能够蜂鸣,并在电脑屏幕上显示。
2 总体方案与说明2.1使用硬件8255芯片、8254芯片、12864字符液晶显示器、蜂鸣器、4*4键盘2.1流程设计2.1.1系统程序模块2.1.2 系统流程图3硬件方案3.1硬件说明3.1.1计数芯片82548254 芯片是一款使用十分广泛的可编程定时,计数芯片,其主要功能是定时和计数的功能。
我们的微机内的动态存储器刷新电路,系统日时钟的技术以及发声系统的声源都是由8254芯片来完成的。
结构8254 芯片的外部引脚和内部结构如下图工作原理8254芯片共有六种工作方式,分别对应与六种不同的用途。
(1)方式0:计数到0结束输出正跃变信号方式。
(2)方式1:硬件可重触发单稳方式。
(3)方式2:频率发生器方式。
(4)方式3:方波发生器。
(5)方式4:软件触发选通方式。
(6)方式5:硬件触发选通方式。
3.1.2可编程外围接口芯片8255A8255A 是一种通用的可编程并行I/O 接口芯片,它是为Intel 系列微处理器设计配套电路,也可用于其他微处理器系统中。
通过对它编程,芯片可工作于不同的工作方式。
在微型计算机系统中,用8255A 做接口时,通常不需要附加外部逻辑电路就可直接为CPU 与外设之间提供数据通道,因此得到了极为广泛的应用。
结构和功能8255A的外部引脚和内部结构如下图图3-3 8255外部引脚图图3-4 8255内部功能图由图可见,8255A由数据端口A、B、C(期中,C口被分为C口上半部分和C 口下半部分),A组和B组控制逻辑,数据总线缓冲器和读写控制逻辑。
8255A内部包含3个8位输入输出端口,通过外部的24根输入输出线与外设进行通信联络。
A口和B口可以用作8位输入口或8位输出口。
C口既可以用作8位输入输出口用,也可作为两个4位的输入输出口。
还常常用来配合A口和B口工作,分别用来产生A口和B口的输出控制信号和输入A口和B口的端口状态端口信号。
8255A的控制字方式选择控制字8255A具有3种基本工作方式。
方式0:基本输入输出方式;方式1:选通输入输出方式;方式2:双向总线I/O方式。
端口A可以工作于3种方式中的任一种;端口B只能工作于方式0和方式1,而不能工作于方式2;端口C常被分成2个4位端口,除了用做输入输出端口外,还能用来配合A口和B口工作,为这两个端口的输入输出操作提供联络信号。
图3-5 8255方式选择控制字格式工作方式A.方式0基本输入输出方式,它适用于不需要应答信号的简单输入输出场合。
在这种方式下,A口和B口可作为8位端口,C口的高4和低4为可作为两个4为端口。
CPU与这些端口交换数据时,可以直接输入指令从端口读取数据,或用输出指令将数据写入指定端口,不需要任何其他联络信号。
B.方式1选通输入/输出方式。
在这种方式下,A口和B口作为数据口,均可用于输入或输出方式。
而且这两个8位数据口的输入、输出数据都能锁存,但它们必须在联络信号的控制下才能完成I/O操作。
端口C的6根线用来产生或接受这些联络信号。
C.方式2双向总线方式。
只有A口可以工作于这种方式。
在这种方式下,CPU与外设交换数据时,可在单一的8位端口数据线PA7-PA9上进行,既可以通过A口把数据传送到外设,又可以从A口接收从外设送来的数据,而且输入和输出的数据均能锁存,但输入和输出不能同时进行3.1.3 128×64字符液晶显示器ST7920是台湾矽创电子公司生产的中文图形控制芯片,它是一种内置128×64-12汉字图形点阵的液晶显示控制模块,用于显示汉字及图形。12864A-1汉字图形点阵液晶显示模块集成ST7920驱动器,可显示汉字及图形,内置8192个中文汉字(16×16点阵)、128个字符(8×16点阵)及64×256点阵显示RAM (GDRAM)。
结构图3-6 LCD液晶字符显示器外形尺寸图3-7 LCD液晶字符坐标工作原理12864液晶显示器工作于并行模式。
8位数据线与8255A芯片8位数据口连接,控制口(E、R/W、D/I)与8255A芯片C口四位相连。
通过8255A的8位数据空向12864液晶显示器传送数据,通过C口低四位传送控制信号。
控制口E为使能端,高电位有效。
R/W为读写控制,低点位为写数据、高电位为读数据。
D/I为数据与命令口,低电位为命令、高电位为数据。
将需要显示的地址通过数据口以命令的形式送入显示器,再将需要显示的数据通过数据口以数据的形式送入显示器,即可显示内容。
图3-8 LCD中文字库截图3.2电路原理图与说明3.2.1 键盘输入电路图3-9 键盘输入电路原理图3.2.2 8254计数电路图3-10 计数电路原理图3.2.3 液晶显示电路图3-11 液晶显示电路原理图3.3电路连接图3.3.1 8254计数芯片3.3.2 整体电路4 软件方案4.1软件主要模块流程图4.1.1输入子程序模块流程图图4-1 输入子程序模块流程图4.1.4蜂鸣器子程序模块流程图4.1.6主程序模块流程图4.2源程序清单与注释#include<stdio.h>;/*头文件*/#include<iostream.h>#include<conio.h>#include "ApiExusb.h"#pragma comment(lib,"ApiExusb.lib")char lcd1[10]={0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3};char lcd2[10]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9};char l1[8]={0,0xd2,0xb6,0xc8,0xcb,0xce,0xc1,0xc8};/*字符机内码数组*/char l2[8]={0,0xbb,0xfe,0xfd,0xc4,0xe5,0xf9,0xd5};charlhy1[32]={0xb5,0xe7,0xd7,0xd3,0xca,0xb1,0xd6,0xd3,0xcd,0xf2,0xc4,0xea,0xc0,0xfa ,0xa1,0xef,0xa1,0xf1,0xbb,0xb6,0xd3,0xad,0xc4,0xfa,0xca,0xb9,0xd3,0xc3,0xa1,0xc 3,0xa3,0xa9};charlhy2[32]={0xc7,0xeb,0xca,0xb9,0xd3,0xc3,0xd0,0xa1,0xbc,0xfc,0xc5,0xcc,0xca,0xe4 ,0xc8,0xeb,0xa1,0xf9,0xd6,0xc6,0xd7,0xf7,0xa1,0xaa,0xcb,0xce,0xca,0xc0,0xbb,0xd b,0xa1,0xf9};charsd1[64]={0xc7,0xeb,0xc9,0xe8,0xb6,0xa8,0xc4,0xd6,0xd6,0xd3,0xc4,0xa3,0xca,0xbd, 0xa2,0xa0,0xa2,0xd9,0xca,0xb1,0xb7,0xd6,0xc3,0xeb,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0 ,0xa2,0xa0,0xa2,0xda,0xd0,0xc7,0xc6,0xda,0xca,0xb1,0xb7,0xd6,0xc3,0xeb,0xa2,0xa 0,0xa2,0xa0,0xa2,0xdb,0xc4,0xea,0xd4,0xc2,0xc8,0xd5,0xca,0xb1,0xb7,0xd6,0xc3,0x eb,0xa2,0xa0};charsd2[16]={0xc7,0xeb,0xc9,0xe8,0xb6,0xa8,0xc4,0xd6,0xd6,0xd3,0xca,0xb1,0xbc,0xe4, 0xa2,0xa0};void clear();void cmdsetup();void datasetup();void input();/*数字输入*/void show(int,int); /*数字显示*/void show1(int,int,int);/*单位显示*/void show2(int);/*星期显示*/void showhy();/*欢迎界面显示*/void showclr();/*界面清屏*/void showsd1();/*设定界面1显示*/void showsd2();int days(int,int);void clock();/*蜂鸣器闹铃*/byte i,k;int j;void main(){int year,month,day,week,hour,minute,second;intflag,scheduledyear,scheduledmonth,scheduledday,scheduledweek,scheduledhour,sche duledminute,scheduledsecond;byte data;;showhy();/*欢迎界面显示*/showclr();showsd1();/*闹钟模式界面显示*/input();flag=j;showclr();showsd2();/*闹钟设定模式界面显示*/if (flag==1) /*闹钟模式1 输入,显示预设时分秒*/{show1(0x92,0xca,0xb1);show1(0x8a,0xb7,0xd6);show1(0x9a,0xc3,0xeb);k=0x90;input();scheduledhour=10*j;k=0x91;input();scheduledhour=scheduledhour+j;k=0x88;input();scheduledminute=10*j;k=0x89;input();scheduledminute=scheduledminute+j;k=0x98;input();scheduledsecond=10*j;k=0x99;input();scheduledsecond=scheduledsecond+j;showclr();}if (flag==2)/*闹钟模式2 输入,显示预设星期时分秒*/ {show1(0x90,0xd0,0xc7);show1(0x91,0xc6,0xda);show1(0x96,0xca,0xb1);show1(0x8a,0xb7,0xd6);show1(0x8e,0xc3,0xeb);k=0x92;input();scheduledweek=j;k=0x94;input();scheduledhour=10*j;k=0x95;input();scheduledhour=scheduledhour+j;k=0x88;input();scheduledminute=10*j;k=0x89;input();scheduledminute=scheduledminute+j;k=0x8c;input();scheduledsecond=10*j;k=0x8d;input();scheduledsecond=scheduledsecond+j;showclr();}if (flag==3)/*闹钟模式3 输入,显示预设年月日时分秒*/ {show1(0x94,0xc4,0xea);show1(0x97,0xd4,0xc2);show1(0x8a,0xc8,0xd5);show1(0x8e,0xca,0xb1);show1(0x9a,0xb7,0xd6);show1(0x9e,0xc3,0xeb);k=0x90;input();scheduledyear=1000*j;k=0x91;input();scheduledyear=scheduledyear+100*j;k=0x92;input();scheduledyear=scheduledyear+10*j;k=0x93;input();scheduledyear=scheduledyear+j;k=0x95;input();scheduledmonth=10*j;k=0x96;input();scheduledmonth=scheduledmonth+j;k=0x88;input();scheduledday=10*j;k=0x89;input();scheduledday=scheduledday+j;k=0x8c;input();scheduledhour=10*j;k=0x8d;input();scheduledhour=scheduledhour+j;k=0x98;input();scheduledminute=10*j;k=0x99;input();scheduledminute=scheduledminute+j;k=0x9c;input();scheduledsecond=10*j;k=0x9d;input();scheduledsecond=scheduledsecond+j;showclr();}k=0x80; /*输入,显示预设的年月日时分秒星期*/input();year=j*1000;k++; /*K储存字符显示在液晶屏的地址*/ input();year=year+j*100;k++;input();year=year+j*10;k++;input();year=year+j;k++; /*显示单位汉字*/show1(k,0xc4,0xea);k=0x90;input();month=j*10;k++;input();month=month+j;k++;show1(k,0xd4,0xc2);k=0x94;input();day=j*10;k++;input();day=day+j;k++;show1(k,0xc8,0xd5);k=0x88;show1(k,0xd0,0xc7); k++;show1(k,0xc6,0xda); k++;input();week=j;k=0x8c;input();hour=j*10;k++;input();hour=hour+j;k++;show1(k,0xca,0xb1);k=0x98;input();minute=j*10;k++;input();minute=minute+j;k++;show1(k,0xb7,0xd6);k=0x9b;input();second=j*10;k++;input();second=second+j;k++;show1(k,0xc3,0xeb)printf("Press any key to begin!\n\n"); getch();cout<<year<<"年"<<endl; /*在电脑上显示预设的年月日时分秒星期*/cout<<month<<"月"<<endl;cout<<day<<"日"<<endl;cout<<"星期"<<week<<endl;cout<<hour<<"时"<<endl;cout<<minute<<"分"<<endl;cout<<second<<"秒"<<endl;while (j>=0) /*计数累加进位显示*/{PortWriteByte(0x28b,0x82); /*10000010 ,8255B口输入*/PortWriteByte(0x283,0x77); /*01110111,通道1,方式3,bcd计数*/PortWriteByte(0x280,0x00); /*写入初值1000*/PortWriteByte(0x280,0x10);PortWriteByte(0x283,0xb1); /*10110001,通道2,方式0,bcd计数*/PortWriteByte(0x281,0x00); /*写入初值2000*/PortWriteByte(0x281,0x20);while(!(data&&0x10)) /* B4检出高电平,证明1秒过去*/{PortReadByte(0x289,&data);}second++; /* 时间更新进位*/if (second>=60){minute++;if (minute>=60){hour++;if (hour>=24){week++;if (week>=7) {week=1;} /* 星期数归1,而不是归0*/day++;if (day>days(month,year)) /* 调用闰年子程序,计算当月应有天数*/ {month++;if (month>=12){year++;month=1; /* 月份数归1,而不是归0*/}day=1; /* 天数数归1,而不是归0*/}hour=0;}minute=0;}second=0;}cout<<year<<"年"<<endl; /* 在电脑屏幕上显示更新后的时间日期*/cout<<month<<"月"<<endl;cout<<day<<"日"<<endl;cout<<"星期"<<week<<endl;cout<<hour<<"时"<<endl;cout<<minute<<"分"<<endl;cout<<second<<"秒"<<endl;/* 分不同模式,进行当前时间与闹钟设定时间比较*/if((flag==1)&&(hour==scheduledhour)&&(minute==scheduledminute)&&(second==schedule dsecond))clock(); /* 调用蜂鸣器子程序*/if((flag==2)&&(week==scheduledweek)&&(hour==scheduledhour)&&(minute==scheduledmin ute)&&(second==scheduledsecond))clock();if((flag==3)&&(year==scheduledyear)&&(month==scheduledmonth)&&(day=scheduledday)& &(hour=scheduledhour)&&(minute==scheduledminute)&&(second==scheduledsecond)) clock();k=0x80; /* 调用显示子程序*/show(year/1000,k); /* 液晶屏上显示更新后的时间日期*/k++;show(year/100%10,k); /* 逐位分离*/k++;show(year/10%10,k);k++;show(year%10,k);k=0x90;show(month/10,k);k++;show(month%10,k);k=0x94;show(day/10,k);k++;show(day%10,k);k=0x8a;show2(week);k=0x8c;show(hour/10,k);k++;show(hour%10,k);k=0x98;show(minute/10,k);k++;show(minute%10,k);k=0x9b;show(second/10,k);k++;show(second%10,k);}}/************************//* 数字输入 *//************************/void input(){byte data;printf("Press any key to begin!\n\n");getch();if(!Startup()) /* 检查设备是否正确打开*/ {printf("ERROR: Open Device Error!\n");return;}printf("请输入数字\n");while(!kbhit()){PortWriteByte(0x28b,0x81); /* 初始化8255*/PortWriteByte(0x28a,0x0f); /* 向C口低4位送1111*/PortReadByte(0x28a,&data); /* 读取C口低4位*/i=data;if (i!=0x0f){i=data;Sleep(50); /* 延时*/PortWriteByte(0x28b,0x88); /* 防抖动,再次读入,初始化8255*/ PortWriteByte(0x28a,0xf0); /* 向C口高4位送1111*/PortReadByte(0x28a,&data); /* 读取C口高4位*/i=i|data;if (i==0x77) j=0; /* 将按键值转化为数字*/else if(i==0x7b) j=1;else if(i==0x7d) j=2;else if(i==0x7e) j=3;else if(i==0xb7) j=4;else if(i==0xbb) j=5;else if(i==0xbd) j=6;else if(i==0xbe) j=7;else if(i==0xd7) j=8;else if(i==0xdb) j=9;else;printf("%d\n",j); /* 电脑屏幕显示*/if (k==0x8a){show2(j); /* 显示星期数,使用汉字*/Cleanup();return;}show(j,k);}}Cleanup();return;}/************************//* LCD显示 *//************************/void show(int j,int k){if(!Startup()) /* 检查设备是否正确打开*/{printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80); /*设8255为方式0,C口输出,A口输出*/clear();PortWriteByte(0x288,k); /*向A口送入字符在液晶屏上显示的地址*/ cmdsetup();Sleep(10); /*延时*/PortWriteByte(0x288,lcd1[j]);datasetup(); /*向A口送入字符机内码高位*/PortWriteByte(0x288,lcd2[j]);datasetup(); /*向A口送入字符机内码低位*/return;}void show1(int k,int j1,int j2) /*在液晶屏上显示单位 */ {printf("请进行下一位\n");getch();cout<<"aaaaaaaa"<<endl;if(!Startup()){printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80); /*设8255为方式0,C口输出,A口输出*/clear();PortWriteByte(0x288,k);cmdsetup();Sleep(10);PortWriteByte(0x288,j1);datasetup();PortWriteByte(0x288,j2);datasetup();Cleanup();return;}void show2(int j) /*显示星期数,一至日 */ {PortWriteByte(0x28b,0x80);clear();PortWriteByte(0x288,k);cmdsetup();Sleep(10);PortWriteByte(0x288,l1[j]);datasetup();PortWriteByte(0x288,l2[j]);datasetup();return;}void showhy() /*显示欢迎界面 */{printf("Press any key to begin!\n\n");getch();cout<<"aaaaaaaa"<<endl;if(!Startup()){printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80);clear();PortWriteByte(0x288,0x80);cmdsetup();Sleep(10);for (i=0;i<16;i++){PortWriteByte(0x288,lhy1[i]);datasetup();};PortWriteByte(0x288,0x90);cmdsetup();Sleep(10);for (i=16;i<32;i++){PortWriteByte(0x288,lhy1[i]);datasetup();};PortWriteByte(0x288,0x88);cmdsetup();Sleep(10);for (i=0;i<16;i++){PortWriteByte(0x288,lhy2[i]);datasetup();};PortWriteByte(0x288,0x98);cmdsetup();Sleep(10);for (i=16;i<32;i++){PortWriteByte(0x288,lhy2[i]);datasetup();};Cleanup();return;}void showsd1() /*显示闹钟模式选择界面 */ {printf("Press any key to begin!\n\n");getch();cout<<"aaaaaaaa"<<endl;if(!Startup()){printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80); /*设8255为方式0,C口输出,A口输出*/clear();PortWriteByte(0x288,0x80);cmdsetup();Sleep(10);for (i=0;i<16;i++){PortWriteByte(0x288,sd1[i]);datasetup();};PortWriteByte(0x288,0x90);cmdsetup();Sleep(10);for (i=16;i<32;i++){PortWriteByte(0x288,sd1[i]);datasetup();};PortWriteByte(0x288,0x88);cmdsetup();Sleep(10);for (i=32;i<48;i++){PortWriteByte(0x288,sd1[i]);datasetup();};PortWriteByte(0x288,0x98);cmdsetup();Sleep(10);for (i=48;i<64;i++){PortWriteByte(0x288,sd1[i]);datasetup();};Cleanup();return;}void showsd2() /*显示闹钟预设时间设定界面 */ {printf("Press any key to begin!\n\n");getch();cout<<"aaaaaaaa"<<endl;if(!Startup()){printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80); /*设8255为方式0,C口输出,A口输出*/clear();PortWriteByte(0x288,0x80);cmdsetup();Sleep(10);for (i=0;i<16;i++){PortWriteByte(0x288,sd2[i]);datasetup();};Cleanup();return;}void showclr() /*以显示满屏空格的方法来进行清屏 */ {printf("Press any key to begin!\n\n");getch();cout<<"aaaaaaaa"<<endl;if(!Startup()){printf("ERROR: Open Device Error!\n");return;}PortWriteByte(0x28b,0x80);clear();PortWriteByte(0x288,0x80);cmdsetup();Sleep(10);for (i=0;i<8;i++){PortWriteByte(0x288,0xa2); datasetup();PortWriteByte(0x288,0xa0); datasetup();};PortWriteByte(0x288,0x90);cmdsetup();Sleep(10);for (i=0;i<8;i++){PortWriteByte(0x288,0xa2); datasetup();PortWriteByte(0x288,0xa0); datasetup();};PortWriteByte(0x288,0x88);cmdsetup();Sleep(10);for (i=0;i<8;i++){PortWriteByte(0x288,0xa2); datasetup();PortWriteByte(0x288,0xa0); datasetup();};PortWriteByte(0x288,0x98);cmdsetup();Sleep(10);for (i=0;i<8;i++){PortWriteByte(0x288,0xa2); datasetup();PortWriteByte(0x288,0xa0); datasetup();};Cleanup();return;}void clear(){PortWriteByte(0x288,0x0c);cmdsetup();}void cmdsetup(){PortWriteByte(0x289,0x00);Sleep(1);PortWriteByte(0x289,0x04);Sleep(1);PortWriteByte(0x289,0x00);Sleep(1);}void datasetup(){PortWriteByte(0x289,0x01);Sleep(1);PortWriteByte(0x289,0x05);Sleep(1);PortWriteByte(0x289,0x01);Sleep(1);}/************************//* 闰年计算 *//************************/int days(int month,int year){int rn; /*闰年标记,=1代表是闰年 */if((year%4==0&&year%100!=0)||year%400==0){ rn=1;}else{rn=0;}switch(month) /*返回每月应有天数 */{case 1: return 31;case 2: if(rn==1){return 29;} /*考虑闰年情况,返回2月份应有天数 */ else {return 28;}case 3: return 31;case 4: return 30;case 5: return 31;case 6: return 30;case 7: return 31;case 8: return 31;case 9: return 30;case 10: return 31;case 11: return 30;case 12: return 31;}}/************************//* 蜂鸣器闹铃*//************************/void clock(){PortWriteByte(0x28b,0x80); /*初始化8255,B口输出*/PortWriteByte(0x289,0x80); /*由B7向蜂鸣器送高电平,启动蜂鸣器*/ cout<<"到时间啦!!!"<<endl; /*在电脑屏幕上显示提醒*/Sleep(500); /*延时*/PortWriteByte(0x289,0x00); /*由B7向蜂鸣器送低电平,关闭蜂鸣器*/return;}5分析与测试首先,在连接键盘和显示程序后,总是无法达到设想中的效果,后来发现是遗漏了检查设备是否正常启动的Startup(),Cleanup()之类的部分。