利用单片机制作简单万年历

国家职业资格全国统一鉴定(国家职业资格二级)家用电子产品维修工论文题目:利用单片机制作简单万年历编号:13利用单片机制作简单万年历摘要:随着时代科技的发展,从摆钟到电子时钟,时代在进步,科技在不断地创新,本文设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。

在硬件设计方面,该电路采用AT89C52单片机作为核心,功耗小,计时模块采用DS1302d时钟电路,它的特点是寿命长,误差小,在显示方面,采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见;在软件设计方面,应用c语言编写程序,它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能。

在设计同时对单片机的理论基础和外围扩展知识进行了很好的实现。

关键词:AT89C52 DS1302 LCD1602目录1、前言 (4)2、方案设计 (4)2.21 主控模块设计 (5)2.22 时钟电路模块设计 (6)2.23 按键电路模块设计 (6)2.24 显示模块设计 (7)2.31 主程序设计 (7)2.32 LCD1602显示软件设计 (8)2.33 按键程序设计 (9)2.34 DS1302时钟程序模块设计 (9)3、测试与结果分析 (10)4、软件仿真 (10)5、结束语 (11)参考文献 (13)1、前言据了解,目前市场上的电子万年历并不是采用51单片机作为主控制器的,基于单片机的万年历一般是学生和单片机爱好者在进行设计,谈不上占有市场。

也许就是这样,研究单片机万年历的人不在少数,并且都在努力。

努力不是单方面的,单片机的功能也应该要提高,STC89C52单片机就是这样的例子,其功能虽然没有大幅度提高,但使用起来更方便了。

我相信,在不久的将来肯定会有功能更强大成本更低的单片机出现,给我们的设计带来更多的便利。

本设计采用的是AT89S52单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序,最突出特点是具有ISP 在系统烧写功能,使得烧写程序更加方便。

计时芯片采用DALLAS公司的涓细充电时钟芯片DS1302,该芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时分、秒信息,采用双电源供电,当外部电源掉电时能够利用后备电池准确计时。

总体来说,本设计成本消耗不高,功能设计也比较简单实现。

2、方案设计2.1 总体设计思路本设计包括硬件和软件设计两个部分。

模块划分为主控模块、时钟电路模块、显示模块等子模块。

软件方面可划分为:液晶显示程序、时钟调节程序、按键控制程序等管理软件组成。

用户终端对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能。

它们之间的构成框图系统设计框图如图1所示。

图1 系统设计框图2.2 系统的硬件模块设计2.21 主控模块设计AT89S52单片机为40引脚双列直插芯片,有四个I/O 口P0,P1,P2,P3, MCS-51单片机共有4个8位的I/O 口(P0、P1、P2、P3),每一条I/O 线都能独立地作输出或输入。

单片机的最小系统如图2所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。

图2 单片机最小系统89c51主控模块 按键模块显示模块 时钟模块2.22 时钟电路模块设计DS1302的引脚排列如图3所示,其中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进行操作。

如果在传送过程中RSTS 置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电动行时,在Vcc 大于等于2.5V之前,RST必须保持低电平。

中有在SCLK 为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。

SCLK始终是输入端。

图3 时钟电路2.23按键电路模块设计键盘是一种最常用的输入设备,它是一组按键的集合,从功能上可分为数字键和功能键两种,作用是输入数据与命令,查询和控制系统的工作状态,实现简单的人机对话。

本文用到键盘的软件方法:是指编制一段时间大于100ms的延时程序,在第一次检测到有键按下时,执行这段延时子程序使键的前沿抖动消失后再检测该键状态,如果该键仍保持闭合状态电平,则确认为该键已稳定按下,否则无键按下,从而消除了抖动的影响。

同理,在检测到按键释放后,也同样要延迟一段时间,以消除后沿抖动,然后转入对该按键的处理。

如图4所示。

图4 按键电路2.24显示模块设计液晶显示原理是将液晶置于两片导电玻璃之间,靠两个电极间电场的驱动,引起液晶分子扭曲向列的电场效应,以控制光源透射或遮蔽功能,在电源关开之间产生明暗而将影像显示出来,若加上彩色滤光片,则可显示彩色影像。

LCD1602电路如下图5所示。

图5 液晶电路图2.3 系统的软件模块设计2.31主程序设计本程序设计与平时编写程序步骤相同,不过需要添加DS1302、LCD1602的头文件,之后在设定延迟函数的延迟时间,再设置外部中断初始化、显示函数初始化,最后在程序最后加入中断请求服务函数。

程序流程图如图6所示。

图6 程序流程图2.32 LCD1602显示软件设计经过ADC0804模数转换得到的电压值数字量,在单片机的P1口输入,单片机处理后在P0口由LCD1602显示出来该被测电压的值,在设置LCD1602时,定义数组以显示屏里的字母以及输出电源的数值,以下为LCD1602的部分伪代码,如图7所示。

图7 液晶1602部分伪代码2.33按键程序设计采用查询法时,必须保证CPU每隔一定时间主动地去扫描按键一次,该扫描时间间隔应小于两次按键的时间间隔,否则会有按键不响应的情形查询检测是否有键按下,如有键闭合,则消除抖动,再判断键号,然后转入相应的键处理。

为了避免抖动干扰需要对程序进行以下的编排,其原理流程图如图8所示。

图8 按键流程图2.34 DS1302时钟程序模块设计DS1302和单片机的连接很简单。

只需一根复位线,一根时钟线,一根数据线即可。

同时它本身还需要接一个32.768KHz的晶振来提供时钟源。

对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。

同时可以在第8脚接上一个3.6V的可充电的电池。

对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。

部分程序如图9所示。

图9 DS1302程序3、测试与结果分析首先熟悉各个元器件的性能和引脚排列情况,并认真检查各个元器件是否好的,然后依据原理图在板上把硬件电路连接起来,接着开始调试。

首先用电压表对整个模拟电路分块测试,看是否有短接和断接起来,如果没有则分模块进行电压值测试并与理论值相比,如果相差不大就表示这个模块连接正确,接着继续下一个模块的检测,直到整个电路检测完毕。

如果测试值与理论值相比相差较大,则说明这个模块的电路有问题,这时候就要一步步检查,直到测试值与理论值基本相符,即电路连接正确。

4、软件仿真包括:标题栏、主菜单、标准工具栏、绘图工具栏、状态栏、对象选择按钮、预览对象方位控制按钮、仿真进程控制按钮、预览窗口、对象选择器窗口、图形编辑窗口。

运行Proteus程序后,进入软件的主界面。

通过左侧工具栏中的P(从库中选择元件命令)命令,在Pick Devices 左侧窗口中选择所需元件的关键字,然后放置元件并调整方向和位置以及参数设置,最后进行连线。

整体仿真电路图如图10所示。

图10 整体电路图Proteus ISIS的工作界面,如图11所示。

图11 液晶显示5、结束语制作这次课程设计一切都是从零开始,从最简单的画流程图起步,这次课程设计可以圆满完成,跟单片机课程里面的课外作业是离不开的。

这次课程设计从开始到制作成功前后超过了一个星期。

当电子万年历可以成功实现时,那种激动和喜悦只有自己可以体会。

在整个设计过程中,充分发挥人的主观能动性,自主学习,学到了许多没学到的知识。

较好的完成了设计,达到了预期的目的,完了最初的设想。

对电路的设计、布局要先有一个好的构思,才显得电路板美观、大方。

程序编写中,由于思路不清晰,开始时遇到了很多的问题,经过静下心来思考,和同学讨论,理清了思路,反而得心应手。

在此次设计中,我要感谢本专业的老师们精心教导,才能学到了这么多东西,这是最重要的。

总之,此次课设使我的能力得到了全方位的提高,使得我的操作能力和专业技能都有了很大的提高。

参考文献1. ATMEL公司AT89S52单片机中文PDF资料.2. 祝诗平. Proteus和Keil软件在单片机教学中的应用[J] .西南农业大学学报(社会科学版),2011(2).3. 王庆利.单片机设计案例实践教程[M].北京邮电大学出版社,200.4. 刘松,曹金玲.《单片机技术与应用》[J].机械工业出版社, 2000.。

合集下载

基于单片机的万年历设计

基于单片机的万年历设计

基于单片机的万年历设计一、系统总体设计基于单片机的万年历系统主要由单片机控制模块、时钟模块、显示模块、按键模块和电源模块等组成。

单片机控制模块是整个系统的核心,负责处理和协调各个模块之间的数据传输和控制信号。

通常选用具有较高性能和稳定性的单片机,如 STC89C52 等。

时钟模块用于提供准确的时间信息,常见的有 DS1302 等芯片,能够实现年、月、日、时、分、秒的精确计时。

显示模块用于将时间等信息直观地展示给用户,可采用液晶显示屏(LCD)或数码管。

LCD 显示效果清晰、美观,但成本相对较高;数码管则价格低廉,显示简单明了。

按键模块用于用户对万年历进行设置和操作,如调整时间、设置闹钟等。

电源模块为整个系统提供稳定的电源供应,保证系统的正常运行。

二、硬件设计1、单片机最小系统单片机最小系统包括单片机芯片、晶振电路和复位电路。

晶振电路为单片机提供时钟信号,保证其正常工作;复位电路则用于在系统出现异常时将单片机恢复到初始状态。

2、时钟模块电路DS1302 时钟芯片通过串行方式与单片机进行通信,其引脚连接到单片机的相应 I/O 口。

通过对 DS1302 进行读写操作,可以获取和设置时间信息。

3、显示模块电路若采用 LCD1602 液晶显示屏,其数据线和控制线与单片机的 I/O 口相连。

通过编程控制单片机向 LCD 发送指令和数据,实现时间等信息的显示。

4、按键模块电路通常使用独立按键,将按键的一端接地,另一端连接到单片机的I/O 口,并通过上拉电阻保证在按键未按下时引脚处于高电平。

当按键按下时,引脚电平被拉低,单片机通过检测引脚电平的变化来判断按键的操作。

三、软件设计软件设计主要包括主程序、时钟模块驱动程序、显示模块驱动程序和按键处理程序等。

主程序负责初始化各个模块,并进行循环检测和处理。

在循环中,不断读取时钟模块的时间数据,然后通过显示模块进行显示,并检测按键是否有操作。

时钟模块驱动程序根据 DS1302 的通信协议,实现对时钟芯片的读写操作,从而获取和设置时间。

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

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

基于单片机的电子万年历设计一、概述随着科技的快速发展和人们对生活品质的追求,电子设备在日常生活中扮演着越来越重要的角色。

电子万年历作为一种集日期、时间显示于一体的实用电子产品,已经深入到人们的日常生活和工作中。

传统的机械式日历已经无法满足现代人对时间精确性和功能多样性的需求,基于单片机的电子万年历设计应运而生,成为了当前研究的热点之一。

基于单片机的电子万年历设计,旨在利用单片机(如STC89CAT89C51等)的强大计算和控制能力,结合液晶显示屏(LCD)、按键输入等外设,实现时间的准确显示、日期的自动更新、闹钟提醒、温度显示等多样化功能。

该设计不仅具有高度的集成性和可靠性,而且能够通过编程实现各种定制化的功能,满足不同用户的需求。

本文将对基于单片机的电子万年历设计进行详细的介绍和分析,包括设计思路、硬件组成、软件编程等方面。

通过本文的阅读,读者可以了解电子万年历的基本原理和设计方法,掌握单片机在电子万年历设计中的应用技巧,为实际的开发工作提供有益的参考和借鉴。

1.1 研究背景与意义随着科技的不断进步,人们日常生活和工作中对于时间的精度和便捷性的要求日益提高。

传统的机械式日历和简单的电子时钟已经无法满足现代生活的需求。

电子万年历作为一种集时间显示、日历查询、定时提醒等多功能于一体的电子装置,在日常生活、工作乃至科研领域都具有广泛的应用价值。

基于单片机的电子万年历设计,不仅可以提供准确的时间显示,还能实现复杂的日期计算、农历显示、节假日提示等功能,极大地提高了时间管理的效率和便捷性。

单片机作为一种集成度高、功耗低、价格适中的微型计算机,非常适合用于小型化、智能化的电子产品设计,如电子万年历。

本研究的意义在于,通过对基于单片机的电子万年历的设计研究,可以推动微型计算机技术和电子时钟技术的融合发展,提升电子产品的智能化水平,满足人们日益增长的生活和工作需求。

同时,该研究还可以为相关领域的技术人员提供参考和借鉴,推动电子万年历产品的不断创新和优化。

基于单片机的万年历设计

基于单片机的万年历设计

一、引言万年历是一种显示当前日期和时间的器件或软件。

随着科技的发展,电子产品普及率愈来愈高,基于单片机的万年历设计成为了一种非常受欢迎的设计方案。

本文将介绍一种基于单片机的万年历设计。

二、设计原理1.显示模块:采用液晶显示屏作为显示模块,可以显示日期、时间等信息。

2.时钟模块:基于RTC(实时时钟)模块,用于获取当前日期和时间。

3.按键模块:采用按键模块作为输入模块,用于设置日期和时间、切换显示模式等。

4.控制模块:基于单片机,用于控制各个模块的工作,并进行相关的计算和显示。

三、硬件设计1.单片机选择在本设计中,选择了一款常用的单片机,STM32F103C8T6、它具有低功耗、高性能的特点,并且具备丰富的外设接口,非常适合用来设计万年历。

2.RTC模块选择在本设计中,选择了一款常用的RTC模块,DS1302、它具有低功耗、稳定性好的特点,并且具备SPI接口,非常适合用来获取当前日期和时间。

3.液晶显示屏选择在本设计中,选择了一款常用的液晶显示屏,1602液晶显示屏。

它具有较大的屏幕尺寸、低功耗的特点,并且可以显示多行字符,非常适合用来显示日期、时间等信息。

4.按键模块选择在本设计中,选择了一款常用的按键模块,4x4按键模块。

它具备4行4列的按键布局,可以满足设置日期和时间、切换显示模式等功能的需求。

五、软件设计1.初始化设置在软件设计中,首先需要对各个硬件模块进行初始化设置。

2.获取当前日期和时间使用RTC模块获取当前日期和时间,并将其存储在相应的变量中。

3.显示日期和时间使用液晶显示屏将当前日期和时间显示出来。

4.设置日期和时间通过按键模块获取用户的输入,并将对应的日期和时间设置到RTC模块中。

5.切换显示模式通过按键模块获取用户的输入,并根据用户的选择切换不同的显示模式,例如切换到年模式、月模式、日模式等等。

六、总结通过以上的设计,基于单片机的万年历完成了日期和时间的获取、显示和设置等功能。

基于单片机万年历设计

基于单片机万年历设计

引言:单片机是集成电路上的一种微处理器。

它具有微处理器的核心功能,如运算逻辑单元,控制单元和寄存器,同时还包含其他外设和接口,如存储器,计数器/定时器等。

在现代科技的不断发展下,单片机已经在许多不同的领域得到广泛应用。

其中之一就是在万年历方面的设计。

万年历在生活中扮演着重要的角色,因此基于单片机设计一个功能强大的万年历具有很大的实用价值。

概述:本文将介绍基于单片机的万年历设计,该设计旨在实现更精确的日期和时间显示,同时提供基本的日历功能和其他实用功能。

文中将详细介绍设计的硬件和软件部分,并讨论其中的各种功能和特点。

正文:1.硬件设计1.1主控芯片选择1.2外设接口设计1.3屏幕选择和显示控制1.4时钟电路设计2.软件设计2.1系统架构设计2.2日期和时间计算算法2.3用户界面设计2.4日历功能实现2.5其他实用功能的实现3.功能和特点3.1准确的日期和时间显示3.2自动切换夏令时3.3多种日期和时间格式支持3.4节假日提醒功能3.5闹钟功能4.应用领域4.1家用4.2办公场所4.3学校4.4研究机构4.5工业领域5.前景和挑战5.1市场需求5.2技术挑战5.3发展趋势5.4可持续发展总结:基于单片机的万年历设计是一项非常有实用价值的技术,它能够提供准确的日期和时间显示,并具备多种实用功能。

本文详细介绍了硬件和软件的设计过程,以及功能和特点,并探讨了该设计在不同领域的应用前景和挑战。

未来,随着科技的进一步发展,基于单片机的万年历设计将继续得到改进和拓展,为人们的生活和工作带来更多的便利和效益。

自己制作的单片机万年历程序+原理图

自己制作的单片机万年历程序+原理图

自己制作的单片机万年历程序+原理图单片机万年历仿真原理图如下仿真Altium Designer画的万年历原理图和PCB图如下:PCB原理图基于51单片机,可以完成时钟显示、公历显示、农历显示、温度显示、闹钟报警定时的LCD时钟PPT内容预览:本设计使用AT89C51来做主控芯片,其强大的功能足够实现我们设计的所有功能。

使用LCD1602的液晶显示器来进行显示。

使用Keil uVision5进行编程。

通过Proteus8.6来进行仿真。

点击一次K1进入时钟设置页面,通过点击K2切换时、秒、分、星期、年、月、日,通过K3与K4实现加减来完成时钟的设置点击两次K1进入闹钟设置页面,通过点击K2切换开关、时、秒、分,通过K3与K4实现加减完成闹钟的设置。

单片机源程序如下注释是很全的#include //调用单片机头文件#define uchar unsigned char //无符号字符型宏定义变量范围0~255#define uint unsigned int //无符号整型宏定义变量范围0~65535#include "eeprom52.h"#include "nongli.h"#include "intrins.h"bit flag_200ms ;bit flag_100ms ;sbit beep = P3^7; //蜂鸣器定义bit flag_beep_en;uint clock_value; //用作闹钟用的sbit dq = P3^1; //18b20 IO口的定义uint temperature ; //温度变量uchar flag_nl; //农历阳历显示标志位uchar menu_1,menu_2;uchar key_time,flag_value; //用做连加的中间变量bit key_500ms ;uchar n_nian,n_yue,n_ri; //农历显示的函数#include "ds1302.h"#include "lcd1602.h"/******************把数据保存到单片机内部eeprom中******************/void write_eeprom(){SectorErase(0x2000);byte_write(0x2000, fen1);byte_write(0x2001, shi1);byte_write(0x2002, open1);byte_write(0x2058, a_a);}/******************把数据从单片机内部eeprom中读出来*****************/void read_eeprom(){fen1 = byte_read(0x2000);shi1 = byte_read(0x2001);open1 = byte_read(0x2002);a_a = byte_read(0x2058);}/**************开机自检eeprom初始化*****************/void init_eeprom(){read_eeprom(); //先读if(a_a != 1) //新的单片机初始单片机内问eeprom{fen1 = 3;shi1 = 8;a_a = 1;write_eeprom(); //保存数据}}/***********************18b20初始化函数*****************************/void init_18b20(){bit q;dq = 1; //把总线拿高delay_uint(1); //15usdq = 0; //给复位脉冲delay_uint(80); //750usdq = 1; //把总线拿高等待delay_uint(10); //110usq = dq; //读取18b20初始化信号delay_uint(20); //200usdq = 1; //把总线拿高释放总线}/*************写18b20内的数据***************/void write_18b20(uchar dat){uchar i;for(i=0;i<8;i++){ //写数据是低位开始dq = 0; //把总线拿低写时间隙开始dq = dat & 0x01; //向18b20总线写数据了delay_uint(5); // 60usdq = 1; //释放总线}}/*************读取18b20内的数据***************/uchar read_18b20(){uchar i,value;for(i=0;i<8;i++){dq = 0; //把总线拿低读时间隙开始value >>= 1; //读数据是低位开始dq = 1; //释放总线if(dq == 1) //开始读写数据value |= 0x80;delay_uint(5); //60us 读一个时间隙最少要保持60us 的时间}return value; //返回数据}/*************读取温度的值读出来的是小数***************/uint read_temp(){uint value;uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序init_18b20(); //初始化18b20write_18b20(0xcc); //跳过64位ROMwrite_18b20(0x44); //启动一次温度转换命令delay_uint(50); //500usinit_18b20(); //初始化18b20write_18b20(0xcc); //跳过64位ROMwrite_18b20(0xbe); //发出读取暂存器命令EA = 0;low = read_18b20(); //读温度低字节value = read_18b20(); //读温度高字节EA = 1;value <<= 8; //把温度的高位左移8位value |= low; //把读出的温度低位放到value的低八位中value *= 0.625; //转换到温度值小数return value; //返回读出的温度带小数}/******************1ms 延时函数*******************/void delay_1ms(uint q){uint i,j;for(i=0;i<>< p=""><>for(j=0;j<120;j++);}/******************写星期函数*******************/void write_week(uchar hang,uchar add,uchar week)//写星期函数{if(hang==1)write_com(0x80+add);elsewrite_com(0x80+0x40+add);。

基于51单片机的万年历设计

基于51单片机的万年历设计

基于51单片机的万年历设计一、系统设计方案本万年历系统主要由 51 单片机、时钟芯片、液晶显示屏、按键等部分组成。

51 单片机作为核心控制器,负责整个系统的运行和数据处理。

时钟芯片用于提供精确的时间信息,液晶显示屏用于显示万年历的相关内容,按键则用于设置时间和功能切换。

二、硬件设计1、单片机选型选用常见的 51 单片机,如 STC89C52 单片机,它具有性能稳定、价格低廉、易于编程等优点。

2、时钟芯片选择 DS1302 时钟芯片,该芯片能够提供高精度的实时时钟,具有闰年补偿功能,并且可以通过串行接口与单片机进行通信。

3、液晶显示屏采用 1602 液晶显示屏,能够清晰地显示字符和数字,满足万年历的显示需求。

4、按键电路设计四个按键,分别用于时间设置、功能切换、加和减操作。

三、软件设计1、主程序流程系统上电后,首先进行初始化操作,包括单片机端口初始化、时钟芯片初始化、液晶显示屏初始化等。

然后读取时钟芯片中的时间数据,并在液晶显示屏上显示出来。

接着进入循环,不断检测按键状态,根据按键操作执行相应的功能,如时间设置、功能切换等。

2、时钟芯片驱动程序通过单片机的串行接口向 DS1302 发送命令和数据,实现对时钟芯片的读写操作,获取准确的时间信息。

3、液晶显示屏驱动程序编写相应的函数,实现对1602 液晶显示屏的字符和数字显示控制。

4、按键处理程序采用扫描方式检测按键状态,当检测到按键按下时,执行相应的按键处理函数,实现时间设置和功能切换等操作。

四、时间设置功能通过按键操作进入时间设置模式,可以分别设置年、月、日、时、分、秒等信息。

在设置过程中,液晶显示屏会显示当前设置的项目和数值,并通过加、减按键进行调整。

设置完成后,将新的时间数据保存到时钟芯片中。

五、显示功能万年历的显示内容包括年、月、日、星期、时、分、秒等信息。

通过合理的排版和显示控制,使这些信息在液晶显示屏上清晰、直观地呈现给用户。

六、系统调试在完成硬件和软件设计后,需要对系统进行调试。

51单片机实现万年历程序

51单片机实现万年历利用AT89S52单片机的P0口来和另外几个口来控制1602液晶的显示和P1口还有其它口来控制ds12887时钟芯片。

设置四个按键,1个定义为时间设置功能键,一个定义为闹钟设置功能键,另外两个用来调节时间的增减。

原理图:pcb图:源程序:#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit beep=P2^0;//蜂鸣器控制口sbit timeadd=P2^1;//调节时间加sbit timesub=P2^2;//调节时间减sbit timeclk=P2^3;//闹钟设定键sbit timefun=P2^4;//时间设定键sbit lcdrs=P2^5;//液晶的命令和数据控制口sbit ledrw=P2^6;//液晶的写数据口sbit lcden=P2^7;//液晶显示模块的使能端sbit timeds=P3^3;//时钟芯片地址闸sbit timerw=P3^4;//时钟芯片读写sbit timeas=P3^5;//时钟芯片地址闸sbit timeen=P3^6;//时钟芯片片选uchar code table[]="20 - - week ";uchar code table1[]=" : : ";//要显示的字符串char num,shi,fen,miao,nian=2000,yue,ri,week,numfun,anumfun,flag,flag1; uchar leap;void delay(uint x){uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void didi(){beep=0;delay(1000);beep=1;delay(1000);}void write_com(uchar com){lcdrs=0;P0=com;delay(5);lcden=1;delay(20);lcden=0;}void write_date(uchar date){lcdrs=1;P0=date;delay(5);lcden=1;delay(20);lcden=0;}void write_sfm(uchar add,uchar date){ uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(uchar add,uchar date){ uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void write_zhou(uchar add,uchar date) {write_com(0x80+add);write_date(0x30+date);}void write_ds(uchar add,uchar date){ timeen=0;timeas=1;timeds=1;timerw=1;P1=add;timeas=0;timerw=0;P1=date;timerw=1;timeas=1;timeen=1;}uchar read_ds(uchar add){uchar ds_date;timeas=1;timeds=1;timerw=1;timeen=0;P1=add;timeas=0;timeds=0;P1=0xff;ds_date=P1;timeds=1;timeas=1;timeen=1;return ds_date;}void keyscan(){if(flag1==1)//用来关闭闹钟铃声{if(timeadd==0){delay(5);if(timeadd==0){while(!timeadd==0);flag1=0;}}if(timesub==0){delay(5);if(timesub==0){while(!timesub==0);flag1=0;}}}if(timefun==0){delay(5);if(timefun==0){while(!timefun);flag=1;numfun++;if(numfun==1){write_com(0x80+0x40+0x0a);write_com(0x0f);}if(numfun==2){write_com(0x80+0x40+0x07);write_com(0x0f);}if(numfun==3){write_com(0x80+0x40+0x04);write_com(0x0f);}if(numfun==4){write_com(0x80+0x0f);write_com(0x0f);}if(numfun==5){write_com(0x80+0x09);write_com(0x0f);}if(numfun==6){write_com(0x80+0x06);write_com(0x0f);}if(numfun==7){write_com(0x80+0x03);write_com(0x0f);}if(numfun==8){numfun=0;flag=0;}}}if(numfun!=0){if(timeadd==0){delay(5);while(!timeadd);if(numfun==1){miao++;if(miao==60)miao=0;write_sfm(9,miao);write_com(0x80+0x40+9);write_ds(0,miao);}if(numfun==2){fen++;if(fen==60)fen=0;write_sfm(6,fen);write_com(0x80+0x40+6);write_ds(2,fen);}if(numfun==3){shi++;if(shi==24)shi=0;write_sfm(3,shi);write_com(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week++;if(week==8)week=1;write_zhou(0x0f,week);write_com(0x80+0x0f);write_ds(6,week);}if(numfun==5){if(nian==0){switch(yue){case 1:ri++;if(ri==32) ri=1;break;case 2:ri++;if(ri==30) ri=1;break;case 3:ri++;if(ri==32) ri=1;break;case 4:ri++;if(ri==31) ri=1;break;case 5:ri++;if(ri==32) ri=1;break;case 6:ri++;if(ri==31) ri=1;break;case 7:ri++;if(ri==32) ri=1;break;case 8:ri++;if(ri==32) ri=1;break;case 9:ri++;if(ri==31)ri=1;break;case 10:ri++;if(ri==32)ri=1;break;case 11:ri++;if(ri==31)ri=1;break;case 12:ri++;if(ri==32)ri=1;break;}}else if(leap&&yue==2){ri++;if(ri==30)ri=1;}else if(yue==2&&leap==0){ri++;if(ri==29)ri=1;}elseswitch(yue){case 1:ri++;if(ri==32) ri=1;break;case 3:ri++;if(ri==32) ri=1;break;case 4:ri++;if(ri==31) ri=1;break;case 5:ri++;if(ri==32) ri=1;break;case 6:ri++;if(ri==31) ri=1;break;case 7:ri++;if(ri==32) ri=1;break;case 8:ri++;if(ri==32) ri=1;break;case 9:ri++;if(ri==31) ri=1;break;case 10:ri++;if(ri==32) ri=1;break;case 11:ri++;if(ri==31) ri=1;break;case 12:ri++;if(ri==32) ri=1;break;}write_nyr(8,ri);write_com(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue++;if(yue==13)yue=0;write_nyr(5,yue);write_com(0x80+0x05);write_ds(8,yue);}if(numfun==7){nian++;if(nian==100)nian=0;leap=nian%4==0&&nian%100!=0;write_nyr(2,nian);write_com(0x80+2);write_ds(9,nian);}}if(timesub==0){delay(5);while(!timesub);if(numfun==1){miao--;if(miao==-1)miao=59;write_sfm(9,miao);write_com(0x80+0x40+9);write_ds(0,miao);}if(numfun==2){fen--;if(fen==-1)fen=59;write_sfm(6,fen);write_com(0x80+0x40+6);write_ds(2,fen);}if(numfun==3){shi--;if(shi==-1)shi=23;write_sfm(3,shi);write_com(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week--;if(week==0)week=7;write_zhou(0x0f,week);write_com(0x80+0x0f);write_ds(6,week);}if(numfun==5){if(nian==0){switch(yue){case 1:ri--;if(ri==0) ri=31;break;case 2:ri--;if(ri==0) ri=29;break;case 3:ri--;if(ri==0) ri=31;break;case 4:ri--;if(ri==0) ri=30;break;case 5:ri--;if(ri==0) ri=31;break;case 6:ri--;if(ri==0) ri=30;break;case 7:ri--;if(ri==0) ri=31;break;case 8:ri--;if(ri==0) ri=31;break;case 9:ri--;if(ri==0) ri=30;break;case 10:ri--;if(ri==0) ri=31;break;case 11:ri--;if(ri==0) ri=30;break;case 12:ri--;if(ri==0) ri=31;break;}}else if(leap&&yue==2){ri--;if(ri==0)ri=29;}else if(yue==2&&leap==0){ri--;if(ri==0)ri=28;}elseswitch(yue){case 1:ri--;if(ri==0) ri=31;break;case 3:ri--;if(ri==0) ri=31;break;case 4:ri--;if(ri==0) ri=30;break;case 5:ri--;if(ri==0) ri=31;break;case 6:ri--;if(ri==0) ri=30;break;case 7:ri--;if(ri==0) ri=31;break;case 8:ri--;if(ri==0) ri=31;break;case 9:ri--;if(ri==0) ri=30;break;case 10:ri--;if(ri==0) ri=31;break;case 11:ri--;if(ri==0) ri=30;break;case 12:ri--;if(ri==0) ri=31;break;}write_nyr(8,ri);write_com(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue--;if(yue==-1)yue=12;write_nyr(5,yue);write_com(0x80+0x05);write_ds(8,yue);}if(numfun==7){nian--;if(nian==-1)nian=99;leap=nian%4==0&&nian%100!=0;write_nyr(2,nian);write_com(0x80+2);write_ds(9,nian);}}}}void set_alarm(){uchar ashi,afen,amiao;if(timeclk==0)//判断是否按下闹钟设定键{delay(5);//延时消抖if(timeclk==0){while(!timeclk);anumfun++;//按键次数加1if(anumfun==1){flag=1;write_com(0x80+0x40+0x0a);write_com(0x0f);}if(anumfun==2){flag=1;write_com(0x80+0x40+0x07);write_com(0x0f);}if(anumfun==3){flag=1;write_com(0x80+0x40+0x04);write_com(0x0f);}if(anumfun==4){flag=0;anumfun=0;}}}if(anumfun!=0){if(timeadd==0)//如果加功能键按下{delay(5);while(!timeadd);if(anumfun==1) //设定秒{amiao++;if(amiao==60)amiao=0;write_sfm(9,amiao);write_com(0x80+0x40+9);write_ds(1,amiao);}if(anumfun==2){afen++;if(afen==60)afen=0;write_sfm(6,afen);write_com(0x80+0x40+6);write_ds(3,afen);}if(anumfun==3){ashi++;if(ashi==24)ashi=0;write_sfm(3,ashi);write_com(0x80+0x40+3);write_ds(5,ashi);}}}if(anumfun!=0){if(timesub==0){delay(5);while(!timesub);if(anumfun==1){amiao--;if(amiao==-1)amiao=59;write_sfm(9,amiao);write_com(0x80+0x40+9);write_ds(1,amiao);}if(anumfun==2){afen--;if(afen==-1)afen=59;write_sfm(6,afen);write_com(0x80+0x40+6);write_ds(3,afen);}if(anumfun==3){ashi--;if(ashi==-1)ashi=23;write_sfm(3,ashi);write_com(0x80+0x40+3);write_ds(5,ashi);}}}}void init(){EA=1;//开总中断EX0=1;//开外部中断0IT0=1;//设定触发方式为负跳变沿有效lcden=0;//选通液晶显示屏ledrw=0;//设定液晶显示屏的读写方式为读write_com(0x38);//设置液晶显示模式为16*2显示,5*7点阵,8位数据接口 write_com(0x0c);//打开显示,并使光标不显示也不闪烁write_com(0x06);//光标指针每次自动加1write_com(1);//清屏write_com(0x80);//送地址指针for(num=0;num<16;num++){write_date(table[num]);delay(5);}write_com(0x80+0x40);//写到第二行for(num=0;num<11;num++){write_date(table1[num]);delay(5);}write_ds(0x0a,0x20);//开启时钟芯片振荡器write_ds(0x0b,0x26);//开启闹钟read_ds(0x0c);//读取时钟芯片c寄存器}void main(){init();while(1){keyscan();set_alarm();if(flag1==1)didi();if(flag==0){//读取时间miao=read_ds(0x00);fen=read_ds(0x02);shi=read_ds(0x04);yue=read_ds(0x08);ri=read_ds(0x07);nian=read_ds(0x09);week=read_ds(0x06);//写入液晶显示屏write_sfm(9,miao);write_sfm(6,fen);write_sfm(3,shi);write_nyr(2,nian);write_nyr(5,yue);write_nyr(8,ri);write_zhou(0x0f,week);}}}void exter() interrupt 0{flag1=1;read_ds(0x0c);//读时钟芯片c寄存器。

用单片机做数字万年历

文章后附有电路原理图、程序清单,以供读者参考。因水平有限,难免有疏落不足之 处,敬请老师和同学能给与批评指正。
关键词:时钟芯片DS12C887;温度采集DS18B20;单片机AT89S52;液晶显示1602
PDF 文件使用 "pdfFactHale Waihona Puke ry Pro" 试用版本创建
摘要
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。它可以对年、月、 日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能。本系统选用DALLAS公司 生产的日历时钟芯片DS12C887来作为实时时钟芯片,为本系统提供详细的年、月、日、 星期和小时、分钟等时间信息。数字万年历采用直观数字显示,可以同时显示年、月、日、 周日、时、分、秒和温度等信息,还具有定时和时间校准等功能。该电路采用AT89S52 单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
结束语 ................................................................................................................ 25 致谢词 ................................................................................................................ 26 参考文献 ............................................................................................................ 27 附件 1 ................................................................................................................. 28

万年历的单片机实现

实验题目:万年历的单片机实现一、实验内容用单片机实现万年历二、实验要求(1)平时显示实时时钟与日历(2)输入任意日子可显示对应的星期和阴历(3)可设置的闹钟功能三、实验器件综合实验箱微机一台(Keil软件)四、设计任务分析本实验是基于51单片机的电子万年历的设计,其中包括当前时间与日期的显示,当前时间与日期的调整,闹铃的设置,任意日期的阴历查询以及星期查询的功能。

可以依据功能,将显示分为三个界面,分别为当前时间与日期显示界面,闹铃设置界面,综合查询界面,可通过三个按键进行切换,按键时需要软件“去抖”。

显示器件为型号为LCM12864的LCD液晶显示屏。

具体实现过程如下:五、具体实现过程可以依据功能,将显示分为三个界面,分别为当前时间与日期显示与设置界面,闹铃设置界面,综合查询界面。

由于LCM12864的配置文件中自带一个函数LCM_DispStr,可以直接将指定字符串显示于指定行列,故为了方便起见,也为了减少变量,将本实验中所需的时间与日期全部定义为字符串形式。

事实证明,这样反而加大了程序代码的冗余。

(一)、当前时间与日期显示与设置本界面中包含当前的时间与日期显示及设置功能,为主界面,即初始界面。

1、当前时间与日期显示由于时间具有同步性,故时间应该是可以动态刷新的,又为了不被其它功能影响计时的准确性,可以用一个定时器中断予以实现。

采用定时方式1,由于定时器无法计时1S,故可以设置一个变量从而使其为2ms*500,不太清楚具体晶振频率,取TH=-2000/256,TL=-2000%256,即作12MHz处理,经测试平均约每分钟2s的误差。

之所以设置值不大,也是为了后期的闹铃部分的闹钟能稍微响亮一些。

同时每次更新完时间后,若秒钟达到了60秒,则会引起相应的时间甚至日期的进位。

同时在日期的进位中,需要注意的是平闰年的2月只有28/29天,以及大月31天与小月30天。

2、当前时间与日期修改在此过程中,需要有按键可以进入修改界面,以及退出界面,同时,在修改时需要移位以及数字的加减功能,为了方便表明修改的哪位,设置了一个周期约为0.2s的闪烁功能。

51单片机万年历实验原理

51单片机万年历实验原理1. 概述51单片机万年历实验是一项基于51单片机的实验项目,用于模拟和显示日期和时间信息,使其具备一定的时钟和日历功能。

本文将详细介绍该实验的原理和实现方法。

2. 实验所需材料完成51单片机万年历实验需要以下材料: - 51单片机开发板 - LCD显示屏 - 时钟芯片(如DS1302) - 电容 - 电阻 - 键盘模块 - 连接线等3. 实验原理本实验的原理主要包括三个方面:51单片机的控制逻辑、时钟芯片的数据存储和显示屏的信息展示。

3.1 51单片机的控制逻辑在51单片机中,首先需要定义和初始化各个引脚和功能模块。

通过引脚的输入输出控制、时钟和定时器的设置,实现对时钟芯片和LCD显示屏的控制和数据传输。

3.2 时钟芯片的数据存储时钟芯片一般具有独立的电源供应和存储空间,用于储存日期和时间等信息。

通过与51单片机的通讯接口,读取和写入时钟芯片中的数据,实现对日期和时间信息的读取和更新。

3.3 显示屏的信息展示LCD显示屏作为用户界面,用于展示日期和时间等信息。

通过51单片机的输出控制,将读取到的日期和时间信息通过LCD显示屏进行展示。

具体的显示方式可以根据需求设计,如以年、月、日的格式显示,或者以星期和时间的格式显示等。

4. 实验步骤基于以上原理,可以按照以下步骤进行51单片机万年历实验:4.1 硬件连接按照实验所需材料,将51单片机开发板、LCD显示屏和时钟芯片等进行正确的连接。

根据引脚功能和电平要求,通过连接线将它们连接在一起。

4.2 编写程序使用合适的集成开发环境(如Keil)编写51单片机的程序。

程序主要包括引脚和功能模块的初始化设置、时钟芯片数据的读写和LCD显示屏信息的输出等。

4.3 载入程序将编写好的程序通过USB下载线或其他方式,将程序载入到开发板中。

确保程序可以正确地运行在51单片机上。

4.4 测试实验接通电源,观察LCD显示屏是否正常显示日期和时间信息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档