单片机电子万年历含程序Word文件下载.docx
《单片机电子万年历含程序Word文件下载.docx》由会员分享,可在线阅读,更多相关《单片机电子万年历含程序Word文件下载.docx(30页珍藏版)》请在冰豆网上搜索。
年、月、日、时、分、秒、星期,并具有可调整日期和时间功能。
该电子万年历使用12MHZ晶振与单片机AT89C52相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。
利用单片机定时器与计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机部处理的数据。
同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。
若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。
若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性,从而使得其成本降低,更适合我们大学生自主研发。
AT89C52是一个低电压,高性能CMOS8位单片机,片含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
关键词:
单片机数字显示动态扫描时间日期可调
第一章设计论证与要求
1.1设计应用意义
二十一世纪是数字化技术高速发展的时代,而单片机在数字化高速发展的时代扮演着极为重要的角色。
电子万年历的开发与研究在信息化时代的今天亦是当务之急,因为它应用在学校、机关、企业、部队等单位礼堂、训练场地、教学室、公共场地等场合,可以说遍与人们生活的每一个角落。
所以说单片机的开发是国家之所需,社会之所需,人民之所需。
由于社会对信息交换不断提高的要求与高新技术的逐步发展,促使电子万年历发展并且投入市场得到广泛应用。
1.2设计方案论证
1.2.1单片机芯片选择
方案一:
采用89C51芯片作为硬件核心,采用FlashROM,部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
方案二:
采用AT89C52,片ROM全都采用FlashROM;
能以3V的超底压工作;
同时也与MCS-51系列单片机完全该芯片部存储器为8KBROM存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
但由于课程学习是主要以AT89C51为主,因此选择AT89C52。
1.2.2显示模块选择
方案一:
采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以也不用此种作为显示.
方案二:
采用LED数码管动态扫描,LED数码管价格适中,对于显示数字最合适,而且采用动态扫描法与单片机连接时,占用的单片机口线少。
所以采用了LED数码管作为显示。
1.2.3时钟芯片选择
采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以与闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V围,2.5V时耗电小于300nA。
此方案虽然时间精度高,但电路复杂,设计成本高,所以不采用。
直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
采用此种方案减少芯片的使用,节约成本。
本次设计采用单片机提供秒信号,用定时器T0的模式二(8位自动重装计数初值的计数值)。
1.3设计流程
熟悉硬件了解各引脚功能
分块设计各部分电路
将分块的电路组合
认真学习单片机汇编语言
完成整体电路图
确定变成结构和思路
综合各程序完成整体程序
编辑各个程序模块
用Proteus画出电路图
调试程序,进行修改
对仿真问题进行改正
画出仿真图进行仿真
准备器件、搭接电路
仿真成功
软硬件结合,完成任务书要求
验证硬件电路
成功
进行扩展
第二章系统硬件电路设计
2.1单片机时钟信号
单片机由外部电路提供时钟信号。
本实验使用11.0592MHz的晶振、30pF的电容组成单片机的时钟电路。
如图2-1所示:
图2-1时钟电路
2.2主控芯片AT89C52模块
AT89C52是一个低电压,高性能CMOS8位单片机,片含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS—51指令系统,片置通用8位中央处理器和Flash存储单元,功能强大的AT89C52单片机可为您提供许多较复杂系统控制应用场合。
图2-2AT89C52管脚图
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时含2个外中断口。
3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
2.3显示电路的设计与原理
就时钟而言,通常可采用液晶显示或数码管显示。
由于一般的段式液晶屏,需要专门的驱动电路,而且液晶显示作为一种被动显示,可视性相对较差;
对于具有驱动电路和微处理器接口的液晶显示模块(字符或点阵),一般多采用并行接口,对微处理器的接口要求较高,占用资源多。
另外,89C52本身无专门的液晶驱动接口,因此,本设计采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合。
初始化时,由软件编写的指令就集中在显示功能的设置上。
数码管引脚如图2-3所示。
图2-3数码管引脚定义
本设计采用动态扫描法,单片机P1.7控制第一只数码管,P1.6控制第二位,P1.5控制第三位,P1.4控制第四位,P1.3控制第五位,P1.2控制第六位,P0口控制八位数据,轮流选题六只数码管,先开通一只数码管,其余关闭,让P0显示数据,延秒一定时间后关闭数码管。
设计如图2-4所示。
图2-4显示电路设计
实物选用六位八段数码管LG3661AH,其管脚排列如图2-5所示。
图2-56位共阴数码管管脚图
2.4按键电路设计
由于我设计的是电子万年历,需要实现多种功能的显示,并要能够切换显示和调节年月日,因此,在设计过程中按键的设计就显得尤为重要。
在设计过程中,按键选择P2口的前4位,一共采用了4个按键,尽量在小的空间里实现最多的功能。
其中MODE键是年月日与时间显示切换键,按下一次就能够更换一次显示位。
在调整显示环境下年/时、月/分、日/秒键是显示调整位的的加1键,每按一次显示数字加1。
设计如图2-5所示。
图2-5按键电路
其中P2.0为年/时键,P2.1为月/分键,P2.2为日/秒/星期键,P2.3为模式键。
第三章软件设计
3.1软件主流程
开始
时=24?
秒=0;
分+1
月份=13?
秒+1
分=0;
时+1
分=60?
秒=60?
时=0;
日+1
日>
本月天数?
日=1,;
月份+1
有T0中断?
年=9999?
月份=1;
年+1
年=00
根据平润年与大小月查出本月天数
Y
N
初始化
启动定时器T0,设置工作模式,装入计数初值
允许T0中断
调键盘扫描
调用显示子程序
返回
调用延时子程序
3.2初始化程序与宏定义
#include<
reg52.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitP1_2=P1^2;
sbitP1_3=P1^3;
sbitP1_4=P1^4;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
sbitkey_y_h=P2^0;
sbitkey_m_m=P2^1;
sbitkey_d_s=P2^2;
sbitkey_set=P2^3;
uinttcnt;
uintyearh=20;
ucharflag,flag1,sec;
uintweek=1;
uintmin=30;
uinthour=15;
uintday=16;
uintmonth=12;
unintflag2==0;
uintyear=13;
ucharsec_l,sec_h,min_l,min_h,hour_l,hour_h;
ucharday_l,day_h,month_l,month_h,year_l,year_h;
ucharcodetab[]={
0x3F,/*0*/
0x06,/*1*/
0x5B,/*2*/
0x4F,/*3*/
0x66,/*4*/
0x6D,/*5*/
0x7D,/*6*/
0x07,/*7*/
0x7F,/*8*/
0x6F,/*9*/
};
3.3主程序
voidmain()
{
TMOD=0x02;
//设置模式为定时器T0的模式2(8位自动重装计数初值的计数值)
TH0=0x06;
//设置计数器初值,靠TH0存储重装的计数值X0=256-250=6
TL0=0x06;
TR0=1;
//启动T0
ET0=1;
//开启定时器T0中断允许
EA=1;
while
(1)
keyscan();
}
voidt0(void)interrupt1using0//t0的中断程序
tcnt++;
if(tcnt==4000)//定时器的定时计数,4000次250us为1秒
{
tcnt=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
min=0;
hour++;
if(hour==24)
hour=0;
day++;
week++;
if(month==2&
&
((year==0&
yearh%4==0)||(year!
=0&
year%4==0))&
day==30)day=1;
elseif(month==2&
day==29)day=1;
elseif((month==4||month==6||month==9||month==11)&
day==31)day=1;
elseif(day==32)day=1;
if(day==1)
month++;
if(month==13)