首页 基于单片机的万年历设计_毕业设计

基于单片机的万年历设计_毕业设计

举报
开通vip

基于单片机的万年历设计_毕业设计 摘 要 现代电子万年历在家庭居室、学校、车站和广场使用的越来越广泛,给人们的生活、学习、工作带来了极大的方便。针对以往的电子万年历断电后的需要重新调整时间与日期,并且计时误有差现象。本系统设计采用了实时芯片(DS1302)作为计时器件,该芯片内部自带晶振荡器,这样就有效的保证了计时的精确性,并且内部自带电池使得在断电的情况下能够继续的更新时间信息。本设计采用了AT89C51作为主要控制器,为了提高电路的使用性加入了报时和闹钟功能。 电子万年历是一种非常广泛日常计时工具,对现代社会越...

基于单片机的万年历设计_毕业设计
摘 要 现代电子万年历在家庭居室、学校、车站和广场使用的越来越广泛,给人们的生活、学习、工作带来了极大的方便。针对以往的电子万年历断电后的需要重新调整时间与日期,并且计时误有差现象。本系统设计采用了实时芯片(DS1302)作为计时器件,该芯片内部自带晶振荡器,这样就有效的保证了计时的精确性,并且内部自带电池使得在断电的情况下能够继续的更新时间信息。本设计采用了AT89C51作为主要控制器,为了提高电路的使用性加入了报时和闹钟功能。 电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。该电路采用AT89C51单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。 本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。在硬件与软件设计时,没有良好的基础知识和实践经验会受到很大限制,每项功能实现时需要那种硬件,程序该如何编写,算法如何实现等,没有一定的基础就不可能很好的实现。在编写程序过程中发现以现有的相关知识要独自完成编写任务困难重重,在老师和同学的帮助下才完成了程序部分的编写。 万年历的设计过程在硬件与软件方面进行同步设计。硬件部分主要由AT89C51单片机,LCD显示电路,以及调时按键电路等组成。在单片机的选择上本人使用了AT89C51单片机,该单片机适合于许多较为复杂控制应用场合。最后总在老师同学的帮助以及自己的努力下完成了此次电子万年历的设计。 Abstract E-calendar-bedroom at home,schools,stations and more extensive use of plaza for people’s lives,study,work great convenience.Electronics calendar for the past need to re-adjust after power-off time and date,and time is a big error,Designed the system using real-time clock chip(DS1302) as a time parts,the chip comes with an internal crystal oscillator,so that effectively guarantee the accuracy of the time and hang own internal battery power makes the situation will continue to update the time information.This design uses AT89C51 as the main controller,in order to improve the practicality of the cricuit add temperature measurement circuit ,timekeeping and alarm funtinons. E-calendar day time is a very wide range of tools, increasingly popular in modern society. It can be year, month, day, Sunday, hours, minutes, seconds for time, but also has a leap year compensation to a variety of functions, and the DS1302's long life, small error. For the digital electronic calendar using an intuitive digital display can simultaneously display year, month, day, Sunday, hours, minutes, seconds, and temperature and other information, but also a time-calibration and other functions. The circuit uses AT89C51 microcontroller as the core, power consumption, low-voltage work in 3V, the voltage can choose 3 ~ 5V voltage supply. The design is based on 51 series of microcontrollers to the design of electronic calendar, you can display date information on when the minutes and seconds, and weeks, with adjustable date and time functions. At the same time in the design of the theoretical basis of the MCU and peripheral expansion of knowledge of the more comprehensive preparation. The hardware and software design, there is no good basic knowledge and practical experience will be greatly limited, each feature is required to achieve the kind of hardware, procedures, how to write, how to implement such algorithms, there is no certain foundation can not be good implementation. Found during the preparation process to the existing knowledge to complete the preparation of the task alone difficult, In the help of teachers and students to complete the program part of the preparation. Calendar of the design process in hardware and software to synchronize the design. Hardware mainly by the AT89C51 microcontroller, LED display circuit, and the tune composed of the circuit when the button. In the SCM choice I used the AT89C51 microcontroller, which is suitable for many of the more complex control applications. The final overall the teacher to help students, as well as their own efforts to complete the design of the electronic calendar. 目录 【摘要】…………………………………………………………………………………...............1 第一章、设计要求与方案论证 1.1 设计要求……………………………………………………………………………………..5 1.2 系统基本方案选择和论证…………………………………………………………………...5 1.2.1单片机芯片的选择方案和论证………………………………………………………..5 1.2.2 显示模块选择方案和论证……………………………………………………………..6 1.2.3时钟芯片的选择方案和论证…………………………………………………………...6 1.3 电路设计最终方案决定………………………………………………………………………7 第二章、系统的硬件设计与实现 2.1 电路设计框图………………………………………………………………………………...7 2.2主要单元电路的器件………………………………………………………………………….7 2.2.1单片机主控制模块…………………………………………………………………...7 2.2.2时钟电路模块………………………………………………………………………...10 2.2.3显示电路…………………………………………………………………..………….13 2.2.4按键电路…………………………………………………………………………….14 2.2.5 晶振电路………………………………………………………………………….….15 第三章、日历算法 3.1电子日历优化算法……………………………………………………………………………16 第四章、系统的软件设计 4.1程序流程框图……………………………………………………………………………..….18 第五章、软件仿真 5.1仿真过程……………………………………………………………………………………...21 5.2显示模块的设计……………………………………………………………………………...22 第六章、总结…………………………………………………………………………….……….23 参考文献 ……………………………………………………………………………..……. .24 致谢………………………………………………………………………………………………..25 附录一:系统程序清单…………………………………………………………………………..26 第一章、设计要求与方案论证 1.1 设计要求: 设计一个能够显示年、月、日、时、分、秒、星期功能的数字万年历。 采用LCD显示年、月、日、时、分、秒、星期,并具备以下功能: 1 具备年、月、日、星期、时、分、秒校准功能; 2 设置按键为选择,按键为加,按键为减,按键为确定; 3 自动将日期时间调整控制在合理范围内,星期调整会在调整年月日时自动完成; 4 星期及时间信息,调整时钟时,所选择的调整对象反白显示。 1.2 系统基本方案选择和论证 1.2.1单片机芯片的选择方案和论证: 随着国内超大规模集成电路的出现,微处理器及其外围芯片有了迅速的发展。集成技术的最新发展之一是将CPU和外围芯片,如程序存储器、数据存储器、并行、串行I/O口、定时/计数器、中断控制器及其他控制部件集成在一个芯片之中,制成单片计算机(Single-Chip Microcomputer)。而近年来推出的一些高档单片机还包括有许多特殊功能单元,如A/D、D/A转换器、调制解调器、通信控制器、锁相环、DMA、浮点运算单元等。因此,只要外加一些扩展电路及必要的通道接口就可以构成各种计算机应用系统,如工业控制系统、数据采集系统、自动测试系统、万年历电子表等。 单片机的出现,并在各个技术领域中得到如此迅猛的发展,与单片机构成计算机应用系统所形成的下述特点有关: 1、单片机构成的应用系统有较大的可靠性。这些可靠性的获得除了依靠单片机芯片本身的高可靠性以及应用有最少的联接外,还可以方便地采用软、硬件技术。 2、系统扩展、系统配置较典型、 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 ,容易构成各种规模的应用系统,应用系统有较高的软、硬件利用系数。 3、由于构成的应用系统是一个计算机系统,相当多的测、控功能由软件实现,故具有柔性特征,不须改变硬件系统就能适当地改变系统功能。 顾本次选择单片机作为核心处理器,并且做了以下比较: 片方案一: 采用89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS 8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。 方案二: 采用STC89C52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,对所下载的程序能够加密,比较安全。当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯造成损坏。 由于实验室AT89C51比较多而且比较实惠顾选择AT89C51。 1.2.2 显示模块选择方案和论证: 方案一: 采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以也不用此种作为显示。 方案二: 采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,所以也不用此种作为显示。 方案三: 采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,与普通数码管相比功耗较小,硬件连接简单。 所以显示部分采用LCD12864(不含字库)液晶。 1.2.3时钟芯片的选择方案和论证: 方案一: 直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。所以不采用此方案。 方案二: 采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA。 1.3 电路设计最终方案决定 综上各方案所述,对此次作品的方案选定: 采用STC89C51作为主控制系统; DS1302提供时钟;LCD12864(不含字库)液晶作为显示。 第二章、系统的硬件设计与实现 2.1 电路设计框图 图1 设计图 2.2主要单元电路的器件 2.2.1单片机主控制模块 单片机实质上是一个芯片,在实际应用中,必须外加各种扩展接口电路、外部设备等相关硬件和软件,才能构成一个单片机系统。尽管各类单片机很多,但无论是从世界范围或是从全国范围来看,使用最为广泛的应属MCS-51单片机。 单片微型计算机市指集成在一个芯片上的微型计算机,也就是把组成微型计算机的各种功能部件,包括CPU、随机存储器RAM、只读存储器ROM、基本输入/输出接口电路、定时器/计数器等部件都制作在一块集成芯片上,构成一个完整的微型计算机,从而实现微型计算机的基本功能。 89C51单片机是在一块芯片中集成了CPU、存储器、定时器/计数器和多种功能的I/O现等一台计算机所需的基本功能部件。主要包括1个8位CPU、1个片内振荡器及时钟电路、128B RAM、4KB ROM、2个16位定时器计数器、32条可编程的I/O线和一个可编程的全双工串行接口、5个中断源、2个中断优先级套中断结构。其内部结构示意图如图2: 图2 单片机内部结构示意图 1、中央处理器 CPU是单片机的内部核心部件,是一个8位二进制数的中央处理单元,主要由运算器,控制器和寄存器阵列构成。 2、控制器 控制器是单片机内部各部件按一定时序协调工作的控制核心,是分析和执行指令的部件。控制器主要由程序计数器、指令寄存器、指令译码器、振荡和定时控制逻辑电路等构成。 3、寄存器阵列 寄存器阵列式单片机内部的临时存储单元或固定用途单元,包括通用寄存器组和专用寄存器组。 4、存储器 程序存储器是可读不可写的,用于存放编号的程序和表格常数。 5、数据存储器是即可读也可写的,用于存放运算的中间结果,进行数据暂存及数据缓冲等。 6、定时器计数器 89C51内部有2个16位可编程定时器计数器,简称为定时器0(T0)和定时器1(T1),T0和T1在定时器控制寄存器TCON和定时器方式选择寄存器TMOD的控制下,可工作在定时器模式或计数器模式下,每种模式又有不同的工作方式。89C51有两个16位的可编程定时/计数器,以实现定时或计数产生中断用于控制程序转向。 7、并行输入输出(I/O)口 89C51共有4组8位I/O口(P0、 P1、P2或P3),用于对外部数据的传输。 89C51单片机内部总线是单总线结构,即数据总线和地址总线是公用的。 89C51有4 0条 超市营销方案100条新疆维吾尔自治区教学常规60条中医养生知识100条工伤保险条例第30条感动服务100条 引脚, 与其他51系列单片机引脚是兼容的。 这40条引脚可分为I/O接口线、电源线、控制线、外接晶体线4部分。 89C51单片机为双列直插式封装结构, 如图3所示。 图3 89C51引脚分配图 Pin40:电源脚。工作电压为+5V Pin20:接地端 P0口:P0口为一个8位漏极开路的双向I/O口,每脚可以吸收8TTL门电流。当P0口的管脚第一次写“1”时,被定义为高阻输入,P0口能够用于外部数据存储器,它可以被定义为数据/地址的第八位,在FLASH编程时,P0口作为原码输入口,当FLASH进行校验时,P0口输出原码,此时,P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流,P1口管脚写入1时,被内部上拉为高,可用作输出,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可以接收、输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。因此作为输入时,P2口的管脚被外部拉低,将输出电流,这就是内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉的优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可以接收输出4个TTL门电流。当P3口写入“1”时,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平;P3口将输处电流(ILL),这就是上拉的缘故。 P3口也可以作为AT89C51的一些特殊功能口,如下所示: P3.0: RXD (串行输入口) P3.1: TXD (串行输出口) P3.2: (外部中断0) P3.3: (外部中断1) P3.4:T0 (定时/计数器0) P3.5: T1 (定时/计数器1) P3.6: (外部数据存储器写选通线) P3.7: (外部数据存储器读选通线) P3口同时为闪烁编程和编程校验接收一些控制信号 RST复位输出:当振荡器复位时,要保持RST脚两个机器周期的高电平时间。 XTAL1:反向振荡器的输入及内部时钟工作电路的输入; XTAL2:来自反向振荡器的输出。 振荡器特性 XTAL1和XTAL2分别为反向放大器的输入和输出,该反向放大器可以配置为片内振荡器,石英振荡器和陶瓷振荡器均可采用,如果采用外部时钟源驱动器件,XTAL2应不连接,有余的输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉冲没有任何严格的要求,但必须保证脉冲的高低电平要求的宽度。 2.2.2时钟电路模块 (1) 时钟芯片DS1302的工作原理: DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图4所示。表1为DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。表6为DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。 (2) DS1302的控制字节 DS1302的控制字如表-1所示。控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出 RAM RD 1 A4 A3 A2 A1 A0 / CK /WR 表1 DS1302的控制字格式 (3) 数据输入输出(I/O) 在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。如下图-3所示: 图4 DS1302单字节读/写时序图 (4) DS1302的寄存器 DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表2。 表2 DS1302的日历、时间寄存器 此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。 图5所示出DS1302 的引脚排列,其中Vcc1 为后备电源,VCC2 为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302 由Vcc1 或Vcc2 两者中的较大者供电。当Vcc2 大于Vcc1+0.2V 时,Vcc2 给DS1302供电。当Vcc2 小于Vcc1 时,DS1302 由Vcc1 供电。X1 和X2 是振荡源,外接32.768kHz 晶振。RST 是复位/片选线,通过把RST 输入驱动置高电平来启动所有的数据传送。RST 输入有两种功能:首先,RST 接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST 提供终止单字节或多字节数据的传送手段。当RST 为高电平时,所有的数据传送被初始化,允许对DS1302 进行操作。如果在传送过程中RST 置为低电平,则会终止此次数据传送,I/O 引脚变为高阻态。上电运行时,在Vcc≥2.5V 之前,RST 必须保持低电平。只有在SCLK 为低电平时,才能将RST 置为高电平。I/O 为串行数据输入输出端(双向),后面有详细说明。SCLK 始终是输入端。 图5 DS1302引脚排列 2.2.3显示电路 就时钟而言,通常可采用液晶显示或数码管显示。由于一般的段式液晶屏,需要专门的驱动电路,而且液晶显示作为一种被动显示,可视性相对较差;对于具有驱动电路和微处理器接口的液晶显示模块(字符或点阵),一般多采用并行接口,对微处理器的接口要求较高,占用资源多。另外,89C51本身无专门的液晶驱动接口,因此,本设计采用点阵式数码管显示,在写程序需要用带自己编写的代码才能来显示汉字,对于显示文字比较适合。初始化时,由软件编写的指令就集中在显示功能的设置上。LGM12641BS1R的指令可带一个、两个参数,或无参数。若指令中含有参数,则每条指令执行时均须先送入参数,再送入指令代码。由于状态位作用不一样,因此执行不同指令必须检测不同状态位。液晶显示模块LGM12641BS1R如图6所示: 图 6 显示电路LGM12641BS1R 在本万年历当中12864液晶显示当前的实时时间重要的阴阳历等功能。 12864(不带字库)液晶具有如下的特性: 1 提供8 位,4 位并行接口及串行接口可选 2 并行接口适配M6800 时序 3 自动电源启动复位功能 4 内部自建振荡源 64×16 位字符显示RAM(DDRAM 最多16 字符×4 行,LCD 显示范围16×2 行)(改为半角输入) 64×16 位字符产生RAM(CGRAM) 2.2.4按键电路 由于我设计的是电子万年历,需要实现多种功能的显示,并要能够切换显示和调节年月日,因此,在设计过程中按键的设计就显得尤为重要。 在设计过程中我一共采用了4个按键,尽量在小的空间里实现最多的功能。其中MODE键是年月日与时间显示切换键,按下一次就能够更换一次显示位。在调整显示环境下加和减键是显示调整位的的加1减1键,确定是选定你修改的时间,并提高万年历显示的精确性。按键电路如图7所示: 图 7 按键电路 2.2.5 晶振电路 1.晶体振荡器的作用:石英晶体振荡器也称石英晶体谐振器,它用来稳定频率和选择频率,是一种可以取代LC谐振回路的晶体谐振元件。 2.本次设计所用的晶体振荡电路如图8所示: 图 8 晶体振荡电路 此晶振电路所选用的石英晶振频率为12MHZ。 时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12us),是计算机中最基本的、最小的时间单位。 在一个时钟周期内,CPU仅完成一个最基本的动作。对于某种单片机,若采用了1MHZ的时钟频率,则时钟周期为1us;若采用4MHZ的时钟频率,则时钟周期为250us。由于时钟脉冲是计算机的基本工作脉冲,它控制着计算机的工作节奏(使计算机的每一步都统一到它的步调上来)。显然,对同一种机型的计算机,时钟频率越高,计算机的工作速度就越快。但是,由于不同的计算机硬件电路和器件的不完全相同,所以其所需要的时钟周频率范围也不一定相同。我们学习的51系列单片机的时钟范围是1.2MHz-12MHz。 第三章、日历算法 3.1电子日历优化算法 1.阳历算法 阳历的算法比较简单,每十月的总的天数相对来说是固定的。只有2月份,在闰年是29天,在非闰年是28天。每个月的日历排法.主要是确定每个月第一天是星期几。我们知道1901年1月1日是星期二,星期的变化是7天一个周期,比如说要计算1901年2月1日是星期几,可以这样推算:从1901年1月1日到1901年2月1日总共经过了31天(从表3可 看出),31对7取模是3:1901年1月1日是星期二,加三后,是星期五。因此1901年2月1日是星期五。同理,可以推算出从1901—2100年任何一天是星期几。 月份 1 2 3 4 5 6 7 8 9 10 11 12 闰年 31 29 31 30 31 30 31 31 30 31 30 31 非闰年 31 28 31 30 31 30 31 31 30 31 30 31 表3 2.阴历算法 阴历程序的设计采用推算阳历来实现: 根据阳历当前日期在一年中的天数来计算阴历日期。阳历每月为30 天或31天(2 月除外,闰年2 月为29 天,平年为28 天),阴历一年有12 个月或13 个月(含闰月),一个月为30 天或29 天。把一个只有29 天的月称为小月,用1 为标志,把30 天的月称为大月,用0 为标志。如有闰月,则把闰月的年份作为高四位,低四位表示闰月的大小,大月为0,小月为1。春节和元旦相差的天数用一个字节表示。总共用4 字节存储一年中任一天阳历和阴历的对应关系的有关数据: 表4 比特数 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 数据 ! ! ! ! ! 1 ! ! ! 1 ! 1 x x x x 表5 我们先要做一个数据表,这个数据表里面每2个字节,表示T一个阴所年彝个月份的天教 2个字节(共16bit)的具体意义如表2。 其中“!(0/1)中“0”表示30天,“1”表示29天。“x x x x(4个比特可表示数值范围0~15)”表示该年中是否有闰月,数值“0”表示无闰月,“ 1~12” 表示某一个闰月。闰月一般是29天;在200年中(1901~2100年),闰月是30天的,可用一个特殊语句来解决。这里2OO年需要200 x 2=400个字节,构成阴历压缩数据表。 有了阴历的数据表后,主要是要确定阳历日和胡历日的对应关系。我们知道阳历年1901年1月1日,对应的阴历年是对应的阴历日,可用以下算法: (1)从阳历年1901年1月1日到1901年2月1日,计算出经过了31天; (2)根据阴历数据表知道阴历年1900年11月有29天,因此31—29=2天。原来阳历年1901年1月1日对应的阴历日是11日,则有11+1=12; (3)因为阴历1901年12月份有30天,而12<=30,所以阳历年1901年2月1日对应的阴历年是1900年12月13日。如果上一步相加得出的散大于当前阴历月的总的天敢,别应该继续减去当前阴历月的总的天数,直到符合条件。 对于月份增加时,还要通过数据表查看是否要经过闰月。 对于其他任何一个阳历日和阴历日的对应关系,都可以通过以上算法求得结果。 第四章、系统的软件设计 4.1程序流程框图 图9主程序流程图 Y N Y N 图10 计算阳历流程图 图11时间调整程序流程图 第五章、软件仿真 5.1仿真过程 1、仿真:打开WAVE6000,输入所编写的源程序并对程序进行编译,在软件的帮助下检查其中的错误并进行反复修改,知道编译正确后运行,确保没有错误以后对正确的源程序进行保存,保存时给其命名,以便将来载入程序时容易找到。 2、打开PROTEUS软件,并出画单片机电子万年历具体运行电路图。 3、检查所画电路运行图,确保没有错误以后,在PROTEUS下对原理图进行加载WAVE6000下的源程序。 4、加载完成后,单击电路图框下的开始按钮,进行仿真,观察LED数码管现实情况,此时LED数码管开始显示数字。调节开关进行时间的调节。当秒的显示间隔快与或慢与实际间隔时,调节石英晶体震荡器的频率参数,从而使秒的间隔达到标准。然后检查电路其它问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 ,并对其的各参数进行调整,使之正确。 4.2仿真结果 通过在WAVE6000下对源程序的编译,改正了其中的很多错误,然后运行,保证源程序的正确性。然后按原理图选择正确合理的电器元件,画出正确的电路图,加载源程序运行,顺利实现了单片机数字电子钟的“小时”、“分钟”、“秒”的显示。该电子万年历的显示效果及电子万年历时间和日期的调节效果分别如图12和图13所示: 图12 电子万年历的运行效果 图13 电子万年历时间和日期的调节效果 5.2显示模块的设计 该电子万年历使用11.0592MHZ晶振与单片机8051相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能,其电路图如下所示: 图14 LCD液晶驱动电路 第六章、总结 通过这一次的毕业设计,我学到了不少的知识,并且加深了以前所学知识的印象。虽然以前做过相类似的课设,但是今天再做的时候,把以前没有学好的模拟电路的知识进行了补充和加强。这使我受益很大。加深了我对于单片机和数字电路的认识,相信在以后的学习和工作中碰到这些基础的元器件我会更加得心应手。通过查阅大量的资料,我获得了以前在课堂上学不到的东西,加深的我对一起学到的东西的巩固,相信在以后工作中,会有很有帮助的。我很认真地对待这个过程中的每一个细节,希望自己能做得更好。希望今后还有这样的机会,能够让我学到更多的知识。在此次的数字钟设计过程中,更进一步地熟悉了芯片的结构及掌握了各芯片的工作原理和其具体的使用方法。 在连接六进制,十进制,六十进制的进位及十二进制的接法中,要求熟悉逻辑电路及其芯片各引脚的功能,那么在电路出错时便能准确地找出错误所在并及时纠正了。 在本次的设计中遇到的问题也有不少,如在使用LCD12864时,写程序的时候开始根本没有注意到用LCD12864是否含有数据库,想我用的就是没有数据库的,写程序时如果不自己加数据库很容易会在最后不能显示,因此开始时一定要了解你所使用的芯片的功能,以免造成不必要的麻烦。 参考文献 [1] 康华光主编,电子技术基础(模拟部分),北京:高等教育出版社,1999.6 [2] 康华光主编,电子技术基础(数字部分),北京:高等教育出版社,2000.6 [3] 楼然苗 51 系列单片机设计实例 北京:北京航空航天大学出版社2003 [4] 楼然苗 单片机课程设计指导 北京:北京航空航天大学出版社 2007 [5] 张毅刚 单片机原理与应用 北京:高等教育出版社 2006 [6]求实科技 单片机典型模块设计实例导航北京:北京航空航天大学出版社 2004 [7] 黄智伟 全国大学生电子设计竞赛制作实训 北京航空航天大学出版社 2007 [8]马忠梅 籍顺心 单片机的C语言应用程序设计(第4版)北京航空航天大学出版社 2007 [9] 高等学校毕业设计指导手册(电子信息卷).北京:高等教育出版社,1998年 [10] 李建忠.《单片机原理及应用》.西安电子科技大学出版, 2006.02 [11] 张俊谟.《单片机中级教程》.北京航空航天大学出版, 2006.03 [12] 余发山.《单片机原理及及应用技术》.中国矿业大学出版社, 2003.12 [13] 杨凌霄.《微型计算机原理及应用》.中国矿业大学出版社, 2004.08 [14] 李飞光.《单片机课程设计实例指导》.北京航空航天大学出版社, 2004 [15] 李振声.《实验电子技术》(P182~193).国防工业大学出版社,2001 [16] 何立民.《单片机应用技术选编》.北京航空航天大学出版社, 2000.08 [17] 万光毅.《单片机实验与实践教程》.北京航空航天大学出版社, 2005.01 [18] 周航慈.《单片机程序设计基础》.北京航空航天大学出版社, 1991.11 [19] 黄遵熹.《单片机原理接口与应用》.西北工业大学出版社, 1997.05 [19]刘勇 编 数字电路 电子工业出版社 2004 [20]陈正振 编 电子电路设计与制作 广西交通职业技术学院信息工程系 2007 [21]杨子文 编 单片机原理及应用 西安电子科技大学出版社 2006 [22]王法能 编 单片机原理及应用 科学出版社 2004 [23]曹琳琳.单片机原理及接口技术【M】.北京:国防科技大学出版社,2000年. [24]许惠民.单片微型计算机原理、接口及应用fM】. 北京:北京邮电大学出版社,2000 致谢 首先感谢我尊敬的导师薛俊老师,薛老师严谨的治学态度、渊博的专业知识以及忘我的工作热情对我的一生都有着非常深远的影响,激励我不断努力学习和工作,向着更高的人生目标奋斗! 薛老师在学术上给予我很多指导和帮助,为我们创造良好的学习氛围,正是在这种环境下我才能够顺利完成学位 论文 政研论文下载论文大学下载论文大学下载关于长拳的论文浙大论文封面下载 。此外,读书期间,使我们受益的不仅仅是佘老师广博的知识,丰富的经验,更为重要的是佘老师在为人为师,以及科研中的态度。在为人方面,我懂得了做人要积极乐观,正直,乐于助人;为师方面,要不遗余力、无私奉献;科研中,要严谨认真、脚踏实地、勤于动脑、勤于动手。这些在我以后的工作和生活中将是我所要努力做到的。 在论文撰写期间,我要感谢许多让我分享他们宝贵经验和知识的老师及朋友。他们为我论文的完成提出了许多宝贵建议及真知灼见,在此表示最深的谢意。 毕业设计的完成,为我的大学学习生活画下了最后一笔。 应该感谢的人很多,要感谢学院给我们提供了一个展现自己的舞台,给我们一次难得煅炼的机会,使得我们的动手能力和专业技能都有了很大的提高。 在做论文设计的日子里得到了指导教师的悉心指导,在此向我们的指导教师致以诚挚的谢意。感谢提供相关技术帮助的老师和同学,你们的支持和鼓励使我们对这次的作品完成有了信心和动力,也给了我们很多无私的帮助和支持,我们在此深表谢意。 在做论文设计的日子里得到了指导教师的悉心指导,在此向我们的指导教师致以诚挚的谢意。感谢提供相关技术帮助的老师和同学,你们的支持和鼓励使我们对这次的作品完成有了信心和动力,也给了我们很多无私的帮助和支持,我们在此深表谢意。 余登红 2012年6月于长江大学工程技术学院 附录一:系统程序清单 //-------------------------------LCD_12864.C------------------------- //名称:12864LCD显示驱动程序(不带字库) //------------------------------------------------------------------- #include #include #define uchar unsigned char #define uint unsigned int #define LCD_DB_PORT P0 // 液晶DB0~DB7 #define LCD_START_ROW 0xC0 // 起始行 #define LCD_PAGE 0xB8 // 页指令 #define LCD_COL 0x40 // 列指令 sbit DI=P2^0; sbit RW=P2^1; sbit E=P2^2; sbit CS1=P2^3; sbit CS2=P2^4; sbit RST=P2^5; bit Reverse_Display=0; //-------------------------------------------------------------------//检查LCD是否忙 //-------------------------------------------------------------------bit LCD_Cheak_Busy() { LCD_DB_PORT=0xFF; RW=1;_nop_(); DI=0; E=1; _nop_(); E=0; return (bit)(P0&0x80); } //------------------------------------------------------------------- //向LCD发送命令 //------------------------------------------------------------------- void LCD_Write_Command (uchar c) { while(LCD_Cheak_Busy()); LCD_DB_PORT=0xFF ; RW=0; _nop_(); DI=0; LCD_DB_PORT=c ; E=1; _nop_(); E=0; } //------------------------------------------------------------------- //向LCD发送数据 //------------------------------------------------------------------- void LCD_Write_Data(uchar d) { while(LCD_Cheak_Busy()); LCD_DB_PORT=0xFF ; RW=0; _nop_(); DI=1; //根据Reverse_Display决定是否反相显示 if(!Reverse_Display) LCD_DB_PORT=d; else LCD_DB_PORT=~d; E=1; _nop_(); E=0; } //------------------------------------------------------------------- //初始化LCD //------------------------------------------------------------------- void LCD_Initialize() { CS1=1;CS2=1; LCD_Write_Command(0x38); //8位形式,2行字符 LCD_Write_Command(0x0F); //开显示 LCD_Write_Command(0x01); //清屏 LCD_Write_Command(0x06); //画面不动光标右移 LCD_Write_Command(LCD_START_ROW); //设置起始行 } //------------------------------------------------------------------- // 通用显示函数 //从第P页第L列开始显示W字节数据,数据在r所指向的缓冲 //每字节8位是垂直显示的,高位在下,地位在上 //每个8X128的矩阵区域为一页(每页分左半页与右半页) //整个LCD又由64X64的左半屏和64X64的右半屏构成 //------------------------------------------------------------------- void Common_Show(uchar P,uchar L,uchar W,uchar *r) { uchar i; if(L<64) // 显示在左半屏或左右半屏 { CS1=1; CS2=0; LCD_Write_Command(LCD_PAGE+P); LCD_Write_Command(LCD_COL+L); if(L+W<64) //全部显示在左半屏 { for(i=0;i #include #include #define uchar unsigned char #define uint unsigned int extern void LCD_Initialize(); extern void Display_A_Char_8X16(uchar P,uchar L,uchar *M) reentrant; extern void Display_A_WORD(uchar P,uchar L,uchar *M) reentrant; //在调整日期时间时,用该位决定是否反白显示 extern bit Reverse_Display; sbit IO=P1^0; //DS1302数据线 sbit CLK=P1^1; //DS1302时钟线 sbit RST=P1^2; //DS1302复位线 sbit K1=P3^4; //选择 sbit K2=P3^5; //加 sbit K3=P3^6; //减 sbit K4=P3^7; //确定 uchar tCount=0; //一年中每个月的天数,2月的天数由年份决定 uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 所读取的日期时间 uchar DateTime[7]; //当前调整的时间对象:秒 分 时 日 月 年(0 1 2 3 4 6) //5对应星期,星期调整由年月日调整自动完成 char Adjust_Index=-1; //水平与垂直偏移 uchar H_Offset=10,V_Page_Offset=0; //年月日 星期 时分秒汉字点阵(16X16) uchar code DATE_TIME_WORDS[]= {0x40,0x20,0x10,0x0C,0xE3,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x02,0x00,0x00, //年 0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x11,0x11,0x11,0x11,0x11,0xFF,0x00,0x00,0x00,0x00, //月 0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x01,0x21,0x41,0x3F,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,//日 0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,//星 0x00,0x48,0x46,0x41,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00, 0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,//期 0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00, 0x00,0xFC,0x44,0x44,0x44,0xFC,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00,//时 0x00,0x07,0x04,0x04,0x04,0x07,0x00,0x00,0x03,0x40,0x80,0x7F,0x00,0x00,0x00,0x00, 0x80,0x40,0x20,0x98,0x87,0x82,0x80,0x80,0x83,0x84,0x98,0x30,0x60,0xC0,0x40,0x00,//分 0x00,0x80,0x40,0x20,0x10,0x0F,0x00,0x00,0x20,0x40,0x3F,0x00,0x00,0x00,0x00,0x00, 0x12,0x12,0xD2,0xFE,0x91,0x11,0xC0,0x38,0x10,0x00,0xFF,0x00,0x08,0x10,0x60,0x00,//秒 0x04,0x03,0x00,0xFF,0x00,0x83,0x80,0x40,0x40,0x20,0x23,0x10,0x08,0x04,0x03,0x00} ; //星期几的汉字点阵 uchar code WEEKDAY_WORDS[]= {0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,//日 0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,//一 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,0x00,//二 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00, 0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,//三 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 0x00,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,//四 0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x22,0x7F,0x00,0x00, 0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00,0x00,//五 0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00, 0x10,0x10,0x10,0x10,0x10,0x91,0x12,0x1E,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x00,//六 0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x00,0x00,0x01,0x02,0x0C,0x78,0x30,0x00,0x00}; //半角数字点阵 uchar code DIGITS[]= {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9}; //------------------------------------------------------------------- //向DS1302写入一字节 //------------------------------------------------------------------- void Write_A_Byte_TO_DS1302(uchar x) { uchar i; for(i=0;i<8;i++) { IO=x&0x01; CLK=1;CLK=0;x>>=1; } } //------------------------------------------------------------------- //从DS1302读取一字节 //------------------------------------------------------------------- uchar Get_A_Byte_FROM_DS1302() { uchar i,b=0x00; for(i=0;i<8;i++) { b |= _crol_((uchar)IO,i); CLK=1;CLK=0; } return b/16*10+b%16; } //------------------------------------------------------------------- //从DS1302指定位置读数据 //------------------------------------------------------------------- uchar Read_Data(uchar addr) { uchar dat; RST = 0;CLK=0;RST=1; Write_A_Byte_TO_DS1302(addr); dat = Get_A_Byte_FROM_DS1302(); CLK=1;RST=0; return dat; } //------------------------------------------------------------------- //向DS1302某地址写入数据 //------------------------------------------------------------------- void Write_DS1302(uchar addr,uchar dat) { CLK=0; RST=0; Write_A_Byte_TO_DS1302(addr); Write_A_Byte_TO_DS1302(dat); CLK=0;RST=0; } //------------------------------------------------------------------- //设置时间 //------------------------------------------------------------------- void SET_DS1302() { uchar i; Write_DS1302(0x8e,0x00); //写控制字,取消写保护 //秒分时日月年依次写入 for(i=0;i<7;i++) { //秒的起始地址 10000000(0x80) //后续依次是分,时,日,月,周,年,写入地址依次递增2 Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10)) ; } Write_DS1302(0x8e,0x80); //加保护 } //------------------------------------------------------------------- //读取当前日期时间 //------------------------------------------------------------------- void GetTime() { uchar i; for(i=0;i<7;i++) { DateTime[i]=Read_Data(0x81+2*i); } } //------------------------------------------------------------------- //判断是否是闰年 //------------------------------------------------------------------- uchar isLeapYear(uint Y) { uint y; return (y%4==0&&y%100!=0)||(y%400==0) ; } //------------------------------------------------------------------- // 求自2000 1 1开始的任何一天时星期几 //函数没通过,求出总数再求星期几 //因为求总天数可能会越出uint的范围 //------------------------------------------------------------------- void RefreshWeekDay() { uint i,d, w=5 ;//已知1999 12 31是周五 for(i=2000;i<2000+DateTime[6];i++) { d=isLeapYear(i) ? 366:365 ; w=(w+d)%7; //取出当年元旦的星期数 } d=0; for(i=1;i 0) DateTime[6]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6]) ? 29:28; //如果年份变化后当前的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay(); //涮新星期 break; case 4: //月01-12 if(x==1&&DateTime[4]<12) DateTime[4]++; if(x==-1&&DateTime[4]>1) DateTime[4]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6]) ? 29:28; //如果月份变化后当前的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay(); //刷新星期 break; case 3: //日00-28/29/30/31 MonthsDays[2]=isLeapYear(2000+DateTime[6]) ? 29:28; // if(x==1&&DateTime[3]0) DateTime[3]--; RefreshWeekDay(); //刷新星期 break; case 2: //时 if(x==1&&DateTime[2]<23) DateTime[2]++; if(x==-1&&DateTime[2]>0) DateTime[2]--; break; case 1: //分 if(x==1&&DateTime[1]<59) DateTime[1]++; if(x==-1&&DateTime[1]>0) DateTime[1]--; break; case 0: //秒 if(x==1&&DateTime[0]<59) DateTime[0]++; if(x==-1&&DateTime[0]>0) DateTime[0]--; break; } } //------------------------------------------------------------------- //定时器0每秒刷新LCD显示 //------------------------------------------------------------------- void T0_INT() interrupt 1 { TH0=-50000/256; TL0=-50000%256; if(++tCount!=2) return; tCount=0; //年 Reverse_Display=Adjust_Index==6; Display_A_Char_8X16(V_Page_Offset,16+H_Offset,DIGITS+DateTime[6]/10*16); Display_A_Char_8X16(V_Page_Offset,24+H_Offset,DIGITS+DateTime[6]%10*16); //月 Reverse_Display=Adjust_Index==4; Display_A_Char_8X16(V_Page_Offset,48+H_Offset,DIGITS+DateTime[4]/10*16); Display_A_Char_8X16(V_Page_Offset,56+H_Offset,DIGITS+DateTime[4]%10*16); //日 Reverse_Display=Adjust_Index==3; Display_A_Char_8X16(V_Page_Offset,80+H_Offset,DIGITS+DateTime[3]/10*16); Display_A_Char_8X16(V_Page_Offset,88+H_Offset,DIGITS+DateTime[3]%10*16); //星期 //Reverse_Display==5; Display_A_WORD(V_Page_Offset+2,96+H_Offset,WEEKDAY_WORDS+(DateTime[5]-1)*32); //Display_A_WORD(V_Page_Offset+2,96+H_Offset,WEEKDAY_WORDS+2*32); //时 Reverse_Display=Adjust_Index==2; Display_A_Char_8X16(V_Page_Offset+5,16+H_Offset,DIGITS+DateTime[2]/10*16); Display_A_Char_8X16(V_Page_Offset+5,24+H_Offset,DIGITS+DateTime[2]%10*16); //分 Reverse_Display=Adjust_Index==1; Display_A_Char_8X16(V_Page_Offset+5,48+H_Offset,DIGITS+DateTime[1]/10*16); Display_A_Char_8X16(V_Page_Offset+5,56+H_Offset,DIGITS+DateTime[1]%10*16); //秒 Reverse_Display=Adjust_Index==0; Display_A_Char_8X16(V_Page_Offset+5,76+H_Offset,DIGITS+DateTime[0]/10*16); Display_A_Char_8X16(V_Page_Offset+5,84+H_Offset,DIGITS+DateTime[0]%10*16); } //------------------------------------------------------------------- //键盘中断(INT0) //------------------------------------------------------------------- void EX_INT0() interrupt 0 { if(K1==0) { if(Adjust_Index==-1||Adjust_Index==0) Adjust_Index=7; Adjust_Index--; if(Adjust_Index==5) Adjust_Index=4;//跳过对星期的调整 } else if(K2==0) DateTime_Adjust(1); //加 else if(K3==0) DateTime_Adjust(-1); //减 else if(K4==0) { SET_DS1302(); //将调整后的时间写入DS1302 Adjust_Index=-1; //操作索引重设为-1,时间继续正常显示 } } //------------------------------------------------------------------- //主程序 //------------------------------------------------------------------- void main() { // LCD_Initialize(); // Display_A_Char_8X16(V_Page_Offset,0+H_Offset,DIGITS+2*16); Display_A_Char_8X16(V_Page_Offset,8+H_Offset,DIGITS); //--------------------------------------------------------------- //显示固定汉字:年月日 ,星期,时分秒 //--------------------------------------------------------------- Display_A_WORD(V_Page_Offset,32+H_Offset,DATE_TIME_WORDS+0*32); //年 Display_A_WORD(V_Page_Offset,64+H_Offset,DATE_TIME_WORDS+1*32); //月 Display_A_WORD(V_Page_Offset,96+H_Offset,DATE_TIME_WORDS+2*32); //日 Display_A_WORD(V_Page_Offset+2,64+H_Offset,DATE_TIME_WORDS+3*32); //星 Display_A_WORD(V_Page_Offset+2,80+H_Offset,DATE_TIME_WORDS+4*32); //期 Display_A_WORD(V_Page_Offset+5,32+H_Offset,DATE_TIME_WORDS+5*32); //时 Display_A_WORD(V_Page_Offset+5,64+H_Offset,DATE_TIME_WORDS+6*32); //分 Display_A_WORD(V_Page_Offset+5,92+H_Offset,DATE_TIME_WORDS+7*32); //秒 //允许INTO,T0中断 IE=0x83; IP=0x01; IT0=0x01; //TMOD=0x01; TH0=-50000/256; TL0=-50000%256; TR0=1; while(1) {//如果未执行调整操作则正常读取当前时间 if(Adjust_Index==-1) GetTime(); } } 开始 初始化 读、写日期、时间 分离日期\时间值 显示子程序 确认返回 日期、时间修改子程序 闰月子程序 返回 确认返回 开始 置阳历总天数 当前月加1 当前号数是总天数 总天数加入该月天数 月加 总天数中加入号 与当前月相同? 计算阳历天数结束,总天数中的数据为当前日期在阳历中的第几天 按键有效,跳出时间调整程序,进入主循环程序 分钟减1 分钟加1 减键有效 加键有效 等待按键程序 控制键有效,进入分钟调整程序 小时减1 小时加1 减键有效 加键有效 等待按键程序 控制键有效,进入小时调整程序 星期减1 星期加1 减键有效 加键有效 等待按键程序 控制键有效,进入星期调整程序 日减1 日加1 减键有效 加键有效 等待按键程序 控制键有效,进入日调整程序 月减1 月加1 减键有效 加键有效 等待按键程序 控制键有效,进入月调整程序 年减1 年加1 减键有效 加键有效 等待按键程序 控制键有效,进入年调整程序 开始 PAGE 20 _1399650867.doc 主控模块 (89C51) 时钟电路 (DS1302) LCD显示电路 键扫描电路
本文档为【基于单片机的万年历设计_毕业设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
北溟愚鱼
暂无简介~
格式:doc
大小:837KB
软件:Word
页数:46
分类:工学
上传时间:2018-09-23
浏览量:16