基于单片机的万年历设计.docx

上传人:b****6 文档编号:5737405 上传时间:2022-12-31 格式:DOCX 页数:35 大小:565.78KB
下载 相关 举报
基于单片机的万年历设计.docx_第1页
第1页 / 共35页
基于单片机的万年历设计.docx_第2页
第2页 / 共35页
基于单片机的万年历设计.docx_第3页
第3页 / 共35页
基于单片机的万年历设计.docx_第4页
第4页 / 共35页
基于单片机的万年历设计.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

基于单片机的万年历设计.docx

《基于单片机的万年历设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的万年历设计.docx(35页珍藏版)》请在冰豆网上搜索。

基于单片机的万年历设计.docx

基于单片机的万年历设计

 

1绪论

1.1设计目的与意义

随着电子技术的高速发展,对电子方面人才的要求越来越高,不仅要求其具备相关的专业理论知识,还要求其具有较强的设计、制作等实践动手能力.此次学校举行的电子设计无疑是对从事电子相关专业的人的一次很好的锻炼和考验,是培养信息人才的一次良好的机会,为其提供了一个理论知识与实践相结合的平台。

通过本次课程设计,引导学生结合所学的电路理论和程序设计的知识,思考设计方案,以小组合作方式,分工完成各个部分,从而掌握相关的硬件结合软件显示电路的设计和调试技术,一方面提高了学生的实践动手和协作能力,另一方面培养了学生综合运用所学理论知识进行工程设计的能力。

1.2方案选择与DIY电子万年历的研究情况

1.2.1时钟芯片选择

方案一:

不使用芯片,采用单片机的定时计数器

这种方法原理是利用单片机芯片的定时器来产生固定的时间,模拟时钟的时,分,秒。

如:

利用AT80C52芯片,定时器用工作方式1,每50ms产生一个中断,循环20次,即1s周期。

每一个周期加1,那么1min为60个周期,1h就是60*60=3600个周期,一天就是3600*24=86400个周期。

此方法优点是可以省去一些外围的芯片,但这种方法只能适用于一些要求不是十分精确,不做长期保留的场合。

方案二:

并行接口时钟芯片DS12887

特点:

采用单片机应用系统并行总线(三总线)扩展的接口电路,采用这种接口电路具有操作速度快,编程方便的优点。

但是对于80C52单片机来说,低位地址线要通过锁存器输出,还要地址译码器,而且并行口芯片的体积相对较大,DS12887管脚图如图1所示。

 

 

图1DS12887管脚图

方案三:

串行接口时钟芯片DS1302

芯片主特性:

(1)实时时钟具有能计算2100年之前的秒分时日日期星期月年的能力,还有闰年调整的能力

(2)318位暂存数据存储RAM

(3)串行I/O口方式使得管脚数量最少

(4)宽范围工作电压2.05.5V

(5)工作电流2.0V时,小于300nA

(5)读/写时钟或RAM数据时有两种传送方式单字节传送和多字节传送字符组方式

(6)8脚DIP封装或可选的8脚SOIC封装根据表面装配

(7)简单3线接口

(8)与TTL兼容Vcc=5V

(9)可选工业级温度范围-40+85

优点:

串行接口的日历时钟芯片,使用简单,接口容易,与微型计算机连线较少等特点,在单片机系统尤其是手持式信息设备中己得到了广泛的应用。

所以,最终选择串行时钟芯片DS1302,DS1302的管脚图如图2所示。

图2DS1302管脚图

1.2.2键盘选择

方案一:

矩阵式键盘

矩阵式键盘电路图如图3所示。

图3矩阵式键盘

行列式键盘的原理就是每一行线与每一列线的交叉地方不相通,而是接上一个按键,通过按键来接通。

特点:

以省出不少的I/O口资源,程序编写相对复杂点,适用于键数比较多的情况。

方案二:

独立式键盘

独立式键盘电路图如图4所示。

图4独立式键盘

独立式键盘是指各个按键相互独立地连接到各自的单片机的I/O口,I/O口只需要做输入口就能读到所有的按键。

特点:

电路简单,程序容易写,适用于按键数较少的情况。

所以我们选择独立式键盘。

1.2.3显示模块选择

方案一:

LED数码管显示

数码管显示比较常用的是采用CD4511和74LS138实现数码转换,数码显示分动态显示和静态显示,静态显示具有锁存功能,可以使数据显示得很清楚,但浪费了一些资源。

目前单片机数码管普通采用动态显示。

编程简单,但只能显示数字,不能显示中文。

方案二:

LCD1602

能够显示英文和数字。

1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:

阿拉伯数字、英文字母的大小写、常用的符号。

方案三:

LCD12864

作为一种输出方式,液晶显示最大的特点就是能够实现友好的人机界面,它己经广泛应用于现代工业控制和智能化仪器仪表等领域,它己经成为单片机就用开发领域典型模块之一。

能够方便的显示文字和数字。

所以最终选择LCD12864。

1.2.4DIY万年历的研究情况

目前电子爱好者,所设计的万年历大部分都采用LCD1602或数码管显示,只能显示阳历,不能带显示阴历,而且没有阴历相对应的的天干地支,和生肖年,没有达到多功能的效果。

我们采用LCD12864显示,通过算法实现,能正确显示阴历,具有友好的界面,为了追求时间的准确,我们采用芯片DS1302,通过单片机控制,读出时间显示在LCD上。

我们除了用芯片DS18B20,通过程序控制,把温度也显示出来外还通过算法控制,把阴历相对应的天干地支,和生肖年也显示出来,达到多功能效果。

 

2主要硬件描述

2.189C52模块

Mcs-51单片机管脚图图如图5所示。

图5单片机管脚图

(1)一个8位的微处理器(CPU)

(2)片内数据存储器RAM(128B/256B)

(3)片内程序存储器ROM/EPROM(4kB/8kB)

(4)4个8位并行I/O拉口P0-P3,每个口既可以作输入,也可以作输出

(5)2个16位定时器/计数器

(6)5个中断源的中断控制系统

(7)1个全双工的串行I/O接口

(8)片内时钟振荡器

2.2显示模块LCM12864

2.2.1液晶模块概述

我们采用FG12864J显示模块,如图6所示,它是一种图形点阵液晶显示器。

它主要采用动态驱动原理由行驱动—控制器和列驱动器两部分组成了128(列)×64(行)的全点阵液晶显示。

2.2.2液晶模块特点

(1)工作电压为+5V±10%,可自带驱动LCD所需的负电压

(2)全屏幕点阵,点阵数为128(列)×64(行),可显示8(/行)×4(行)个(16×16点阵)汉字,也可完成图形,字符的显示

(3)与CPU接口采用5条位控制总线和8位并行数据总线输入输出,适配M6800系列时序

(4)内部有显示数据锁存器

(5)简单的操作指令显示开关设置,显示起始行设置,地址指针设置和数据读/写等指令

图6FG12864J显示模块

2.3芯片DS1302简介

DS1302是DALLAS公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作可通过AM/PM指示决定采用24或12小时格式。

DS1302与单片机之间能简单地采用同步串行的方式进行通信仅需用到三个口线1RES复位2I/O数据线3SCLK串行时钟时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。

DS1302的管脚描述如表1所示。

表1DS1302管脚

X1X2

32.758KHz晶振管脚

GND

RST

复位

I/O

数据输入/输出引脚

SCLK

串行时钟

Vcc1Vcc2

电源供电管脚

2.4芯片DS18B20简介

DS18B20温度传感器当仁不让。

超小的体积,超低的硬件开消,抗干扰能力强,精度高,附加功能强。

对电子爱好者来说,DS18B20是我们开发温度相关的首选小产品。

DS18B20引脚功能如表2所示。

表2DS18B20引脚功能

GND

DQ

单数据总线

VDD

电源电压

NC

空引脚

 

3硬件设计与实现

该万年历以89S52作为控制核心,外接DS18B20温度传感器,DS1302时钟芯片,显示采用LCM12864,调表采用矩阵式键盘,整体硬件电路的框图如图7所示。

图7硬件电路框图

3.1单片机最小系统的设计

AT89S52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。

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

第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端。

 

图8单片机最小系统

3.2时钟电路的设计

本系统采用有DS1302串行时钟芯片作为主时钟电路,该电路使用单独的32.768M的晶振和单独的电源供电,减小主控的负担。

电路图如图9所示。

图9时钟电路

3.3温度采集模块的设计

采用数字式温度传感器DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,使用P0.7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,Vss接地。

电路图如图10所示。

图10温度采集电路

3.4人机交互模块设计

该系统输入模块采用独立式式键盘输入,显示模块采用LCM12864,很好的实现了人机交互,液晶与主控制器的接口如图11所示。

图11液晶接口电路

 

4系统软件设计与实现

4.1主要算法流程图描述

以80C52为核心,处理外转电路传进来的信号,实现时钟数据的读取,保存,显示其及键盘操作。

流程图如图12所示。

图12主程序流程图

阳历和时分秒都是通过DS1302读出来的,经过主控的转换和处理最终显示在LCM12864上,该程序流程图如图13所示。

图13计算阳历和时分秒流程图

阴历是通过一种算法转换过来,首先得到阳历值,然后根据这种算法把阳历转换成阴历,最终显示在LCM12864模块上,该程序流程图如图14所示。

图14计算阴历程序流程图

时间调整是通过四个独立按键来调整时间值,时间调整流程图如图15所示。

图15时间调整程序流程图

星期的计算方法如下:

星期=(日期年份+所过闰年数+月校正数)%7,如果是在闰年又不到3月份上述之和要减一天再除7,其1到12月的校正数据为[622503514624],该程序中采用1个字节表示年份闰年数也只计算1900年以后的闰年数。

该程序的流程图如图16所示。

图16计算星期算法

4.2LCM16824子程序的实现

LCM12864的读写时序如图17所示。

图17LCM12864读写时序

主要函数模块:

函数:

voidlcd_init(void)

显示初始化程序

函数:

VoidGUI_init()

该函数用于初始化显示界面,把一些固定不需要刷新的文字固定下来

函数:

voidlw(ucharx,uchary,uchardd)

用来写数据的子程序

函数:

voiddisplay(ucharxx,ucharyy,ucharn,ucharfb,ucharhz[])

用于显示汉字,每个汉字为16*16的点阵

函数:

voidshownum(ucharxx,ucharyy,ucharn,ucharfb,ucharnum[])

用于显示数字,每个数字为8*16的点阵

4.3DS1302子程序的实现

DS1302的读写时序如图18所示。

图18DS1302读写时序

定义结构体数组SYSTEMTIME的时间类型,结构体数组如下:

typedefstruct__SYSTEMTIME__

{

unsignedcharSecond;

unsignedcharMinute;

unsignedcharHour;

unsignedcharWeek;

unsignedcharDay;

unsignedcharMonth;

unsignedcharYear;

}SYSTEMTIME

主要函数模块:

函数:

voidInitial_DS1302(void)

描述:

时钟芯片初始化

函数:

voidWrite1302(unsignedcharucAddr,unsignedcharucDa)

描述:

把某个数据写进某个地址

函数:

unsignedcharRead1302(unsignedcharucAddr)

描述:

从芯片内某地址读取数据

函数:

voidDS1302_GetTime(SYSTEMTIME*Time)

描述:

获取时钟芯片的时钟数据到自定义的结构型数组

函数:

voidDS1302InputByte(unsignedchard)

描述:

往时钟写入一字节

函数:

unsignedcharDS1302OutputByte(void)

描述:

从时间内读取一个字节

4.4DS18B20子程序的实现

DS18B20的读写时序如图19所示。

图19DS18B20读写时序

简易的程序流程图如图20所示。

图20DS18B20读写程序流程图

主要函数描述:

函数:

voidInit_DS18B20(void)

描述:

单总线传输初始化函数.

函数:

voidWriteOneChar(uchardat)

描述:

往芯片内部地址写入一个字节,有写数据和写指令之分.

函数:

voidReadTemp(void)

描述:

读取芯片的温度.

函数:

voiddelay_18B20(unsignedinti)

描述:

延时函数

4.5键盘子程序的实现

键盘示意图如图21所示。

图21按键示意图

主要函数模块:

函数名:

voidkey_count()

功能描述:

设置状态转换函数,根据变量count的不同值,对应不同的设置状态按下设置键,自动切换设置位

函数名:

voidkey_out()

功能描述:

跳出设置模式

函数名:

ucharkey_up(inttemp,intmax,intmin)

功能描述:

按键加函数,在最大值与最小值之间变化

函数名:

ucharkey_down(inttemp,intmax,intmin)

功能描述:

按键减函数,在最大值与最小值之间变化

函数名:

voidset_year();voidset_month();voidset_day();voidset_hour();

voidset_minute();

功能描述:

分别是用来设置年月日时分秒

函数名:

voidkey_al01()

功能描述:

设置定时报警功能

4.6主程序的实现

主要函数模块:

函数名:

Init_GUI()

功能描述:

进行界面初始化,例如固定的年、星期、农历

函数名:

voidShow_NL()

功能描述:

根据算法,得出阴历,包括天干地支月日

 

函数名:

voidShow_YL()

功能描述:

根据算法,从时钟芯片读出阳历数据,显示出来

 

函数名:

LCD_ShowWNL()

功能描述:

根据算法,显示电子万年历,其中时钟的”秒”位为每次循环刷新一次,”分”为在普通模式时每分钟刷新一次,在设置模式时每次循环刷新一次,”时”为在普通模式时每小时刷新一次,在设置模式时每次循环刷新一次,公历农历的年、月、日、星期、温度,设置模式每次循环刷新一次

函数名:

voidLCD_showalarm()

功能描述:

显示定时报警的时间

函数名:

voidmian()

功能描述:

.显示万年历,循环读取时间,并通过程序进行键盘检测

 

5测试结果分析与结果

5.1测试结果分析

(1)在测试中遇到LEDLCD16824不显示

分析:

首先使用试测仪对电路进行测试,观察是否存在漏焊,虚焊,或者元件损坏。

再接着研究程序的时序图是否正确。

最后发现程序时序方面出了点小错。

修改后就把问题解决了

(2)测试中遇到调时间调到2079年后跳到2000年

分析:

认真研究时钟芯片的Datasheet发现,对年的读取,读出后是BCD码转换成十制显示时算法不正确

(3)按键调整时,不是按单位递增和递减

分析:

在键盘程序中,按键一次,向芯片写入一个新的数字,在写入数字后必须有一定延时才再写入另一个数字

(4)烧写程序进单片机里面时,有时会在显示屏上显示烂码.

分析:

用电压表检查.最后检测出USB下载线的端口电压不够换条新线就可以把问题解决

5.2测试总结

经过多次的反复测试与分析,掌握了硬件的设计与分析的能力,学会看英文版的Datasheet,同时在软件的编程方面得到更到的提高,对编程能力得到加强。

对所学的知识得到很大的提高与巩固。

最终实现功能:

(1)能显示阳历年、月、日、星期、小时、分、秒

(2)显示模块采用LCD液晶显示,要求能用按键调整时间。

(3)能显示阴历月、日,在显示阴历时间时能标明是否为闰年。

(4)具有定时报警功能,能够进行整点和半点语音报时。

(5)能够准确在LCD上显示室。

(6)在显示农历时通过算法能够把天干地去也显示出来。

 

结束语

通过对基于单片机的万年历的研究和设计,完成了一种能够显示阳历、阴历、星期、时间、实时温度、天干地支的多功能万年历,该万年历还可以定时报警和进行进行整点和半点报时。

本系统设计从开始到完成包括文档的编写总共花了一个月左右的时间,设计的难点在于星期和天干地支的计算方法,还有单片机和各个芯片之间的通信协议,液晶的读写时序,按键的防抖。

本系统基本完成了设计指标的所有要求,所有的程序分块编写,通过main函数来调用,增加了程序的易修改性和易读性,方便他人的使用和改进。

但是由于时间的局限性以及本人能力的有限性,本系统还有许多需要改进和完善的地方。

其中主要的问题就是功耗和电源供电的问题,该处采用5V供电,最好采用3V供电。

整个电路的功耗太大,没让单片机工作在空闲模式,这都是作品不实用,不能够大批量生产,这都有待改进,希望以后有机会对该系统做进一步的完善。

 

致谢

在本次设计中,我想首先感谢赵老师,从设计的开始到完成,给了我很多指导性的意见,不断帮助我完善系统设计。

从大一开始,赵老师作为我的导师,一直很注重我们动手能力的培养。

她丰富的教学及实际操作经验、严谨的治学态度,以及和蔼的态度,使得我投入了大量时间在创新基地的实验室中,做了许多实验。

而这,对我的帮助和影响是非常巨大的。

正是因为有了这些锻炼的机会,我才能非常顺利地完成我的毕业设计。

最后非常感谢郑州铁路职业技术学院信息工程系的老师和同学,是他们让我学会了如何学习,更学会了如何做人,这将是我终身受益的宝贵财富

 

参考文献

[1]周兴华编著.手把手教你学单片机C程序设计.北京:

北京航空航天大学出版社,2007

[2]侯玉宝编著.基于Proteus的51系列单片机设计与仿真.北京:

电子工业出版社,2008

[3]张义和编著.例说51单片机(C语言).北京:

人民邮电出版社.2008

[4]李朝青编著.单片机原理及接口技术.北京:

北京航空航天大学出版社,2005

[5]周慈航编著.单片机应用程序设计基础.北京:

北京航空航天大学出版社,1991

[6]马忠梅编著.单片机的C语言应用程序设计.北京:

北京航空航天大学出版社,2003

[7]李广弟编著.单片机基础.北京:

北京航空航天大学出版社,1994

[8]曾巧媛编著.单片机原理及应用.北京:

电子工业出版社,1997

[9]邱丽芳编著.单片机原理与应用.人民邮电出版社,2007

[10]何立民编著.MCS-51系列单片机应用系统设计.北京航空航天大学出版社,2003

 

附录一作品实物图

附录二原理图

 

附录三部分程序

主程序

#include

#include//更改管脚

#include

#include

#include

#include

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

SYSTEMTIMEsys;

ucharc_sun,year_sun,month_sun,day_sun;

ucharyear_moon,month_moon,day_moon,week;

ucharalarm=0,al_hour=0,al_min=0;

Init_GUI()

{

lcd_init();

Init_DS18B20();

Initial_DS1302();

delay(10);

jiemian();//显示初始化界面,例如固定的年、星期、农历……放在12864.c里

}

voidShow_NL()

{

DS1302_GetTime(&sys);

year_sun=Read1302(DS1302_YEAR);

month_sun=Read1302(DS1302_MONTH);

day_sun=Read1302(DS1302_DAY);

Conversion(0,year_sun,month_sun,day_sun);

/*day_moon=((day_moon&0x70)>>4)*10+(day_moon&0x0F);

month_moon=((month_moon&0x70)>>4)*10+(month_moon&0x0F);

year_moon=((year_moon&0xF0)>>4)*10+(year_moon&0x0F);*/

if(month_moon==1)display(8,4,12,0,ch1616);//显示“正”

elsedisplay(8,4,month_moon-1,0,ch1616);//显示当前农历的月

if(day_moon<11)display(12,4,13,0,ch1616);//显示“初”

if(day_moon<20&&day_moon>10)display(12,4,9,0,ch1616);//显示“十”

if(day_moon<30&&day_moon>19)display(12,4,14,0,ch1616);//显示“廿”

if(day_moon>29)display(12,4,2,0,ch1616);//显示“三”

display(14,4,(day_moon-1)%10,0,ch1616);//显示农历个位

display(14,2,year_moon%12,0,shengxiao);//显示生肖

display(9,2,year_moon%10,0,tiangan);//显示天干

display(11,2,year_moon%12

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1