基于51单片机的键盘盘可调万年历.docx
《基于51单片机的键盘盘可调万年历.docx》由会员分享,可在线阅读,更多相关《基于51单片机的键盘盘可调万年历.docx(33页珍藏版)》请在冰豆网上搜索。
基于51单片机的键盘盘可调万年历
开放性实验报告
题目:
基于80C51的万年历设计_
院系:
专业班级:
学号:
姓名:
指导老师:
________________________
时间:
2014年9月8号
摘要
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。
它可以对年、月、日、周、时、分、秒进行计时,还具有闰年补偿等多种功能。
本系统选用DALLAS公司生产的日历时钟芯片DS1302来作为实时时数字万年历采用直观数字显示,可以同时显示年、月、日、周、时、分、秒等信息,还具有键盘时间校准等功能。
该电路采用AT89C52单片机作为核心,用以5V电压供电。
本系统硬件部分由AT89C52单片机、DS1302时钟芯片、LCD1602液晶显示环境下以C51语言编写,包括时间设置、时间显示、时间修正等功能。
在仿真的时候,以Proteus与KeiluVision4软件为基础,编写了MCS-51单片机对LCD1602显示控制的软件,绘制其原理图,并使用Proteus软件与KeiluVision4软件建立联合仿真。
本设计主要论述了原理图各个模块的作用,以及控制软件的各个模块的编程。
关键词:
时钟芯片DS1302;单片机AT89C52;液晶显示1602;独立键盘等
目录
第1章绪论1
1.1实时万年历的简介1
1.2系统所实现的功能3
第2章开发工具软件简介4
2.1KeiluVision4软件简介4
2.2Proteus软件简介4
2.3KeiluVision4与Proteus软件联合仿真5
第3章LCD1602显示控制技术6
3.11602字符型LCD简介6
3.2LCD1602功能7
3.3LCD1602的指令说明及时序8
3.4LCD1602的RAM地址映射及标准字库表7
3.5LCD1602的一般初始化(复位)过程8
第4章系统硬件概况13
4.1系统概况13
4.2MCS-51单片机最小系统模块14
4.3DS1302时钟芯片控制与键盘设置时间模块15
4.4LCD1602显示模块16
第5章软件控制系统概况18
5.1程序流程概况18
5.2流程图18
5.3源程序代码19
参考文献25
第1章绪论
1.1实时万年历的简介
随着电子技术的发展,人类在不断研究的过程中也在不停创造新的纪录。
万年历目前已经不再局限于以纸张的形式出现。
以电脑软件或者电子产品形式出现的万年历被称为电子万年历。
与传统万年历相比,电子万年历得到了越来越得到大众的青睐,采用电子时钟作为时间显示早已成为一种时尚。
目前市场上各式各样的电子时钟数不胜数,但多数是只针对时间显示,功能单一不能满足人们多样化的需求。
本文提出了一种基于AT89C51单片机的万年历设计方案,本方案以AT89C51单片机作为主控核心,与时钟芯片DS1302、按键、LED1602显示等模块组成硬件系统。
在硬件系统中设有独立按键和LED显示器,能显示丰富的信息,根据使用者的需要可以随时对时间进行校准、选择时间等,综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点。
1.2系统所实现的功能
现在所使用的万年历,实际上就是记录一定时间范围内(比如100年或更多)的具体阳历或阴历日期的年历,方便有需要的人查询使用,与原始历法并无直接联系。
而随着微电子技术的高速发展,人们发明了更加准确更加便捷的电子万年历。
因为这种万年历在日常生活中运用得越来越广泛,在现代社会也越来越流行。
它可以对年、月、日、周、时、分、秒进行计时,还具有闰年补偿等多种功能,而且其使用寿命更长,误差更小,有的电子万年历还具有时间以及星期的校准功能。
本文主要包括以下内容:
1.单片机为核心,建立以LCD1602为显示控制系统,编制各控制子程序模块,为操作人员提供灵活、准确的控制信息,实现对LCD1602液晶显示当前时间。
2.绘制整个控制系统原理图。
3.配合控制程序软件,完成对整个硬件系统的控制。
4.使用KeiluVision4进行C语言代码的编写。
5.使用Proteus进行仿真。
第2章开发工具软件简介
2.1KeiluVision4软件简介
Keil是美国KeilSoftware公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。
用过汇编语言后再使用C来开发,体会更加深刻。
在开发大型软件时更能体现高级语言的优势。
Keil软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。
Keil生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。
其次,该软件不但可以进行软件仿真,而且还可以通过其内嵌模块Keil-Monitor-51,实现在不需要连接硬件仿真器的条件下,通过下载线连接硬件系统对项目进行实时仿真。
另外,可以与Proteus单片机仿真软件联合实现虚拟硬件仿真。
2.2Proteus软件简介
目前电子设计手段日新月异,由手工设计阶段到EDA阶段,再到虚拟设计阶段,人们不断提高设计水平与效率。
Proteus软件是英国Labcenterelectronics公司出版的EDA工具软件。
Proteus嵌入式系统仿真与开发平台是一款可以实现数字电路、模拟电路、微控制器系统仿真及PCB设计等功能的EDA软件。
从元件的选取到连线,直至电路的调试、分析和软件的编译,都是在计算机中完成,所有的工作先在虚拟环境下进行。
基于这一设计思想开发的Proteus软件,可在原理图设计阶段对所设计的电路进行评估、验证,看是否达到设计要求的技术指标,并可以通过改变元件的参数使整个电路性能达到最优化。
这样就避免了传统电子电路设计中方案更换带来的多次重复购买元器件及制板,在节省设计时间与经费的同时,提高了设计效率与质量。
Proteus软件不仅具有其它EDA工具软件的模拟电子和数字电子的仿真功能,而且还具有其他EDA软件所没有的单片机系统硬件仿真功能。
它可以仿真MCS-51系列单片机、AVR单片机、PIC单片机和ARM7微处理器,可以直接在电路原理图上实现硬件的虚拟仿真,实现程序的调试,并提供进行测试与分析的虚拟示波器、逻辑分析仪等虚拟仪器及仿真图表。
它是目前最好的仿真单片机及外围器件的工具。
Proteus软件主要由实现原理图编辑及仿真的ISIS模块和实现PCB板设计及自动布线的ARES模块组成。
Proteus软件提供了三十多个元器件库,数千元器件。
元件涉及电阻、电容、二极管、MOS管、变压器、继电器、各种放大器、各种激励源、300多种微处理器、各种门电路和各种终端等。
提供的仪表有交直流电压表、电流表、逻辑分析仪、定时/计数器和信号发生器等虚拟仪器,Proteus作为可视化仿真软件,提供数码管、液晶屏、LED、按钮、键盘等外设。
2.3KeiluVision4与Proteus软件联合仿真
Proteus软件与KeiluVision4软件之间的联合虚拟仿真,指KeiluVision4软件将Proteus软件打开的单片机系统看成一个虚拟的硬件电路,使用KeiluVision4软件对程序进行编译、调试时自动连接Proteus软件中的虚拟单片机系统,虚拟单片机系统的状态随KeiluVision4软件对程序调试实时变化。
这样,可实现用Proteus软件与KeiluVision4软件联合虚拟硬件仿真。
第3章LCD1602液晶显示屏
3.11602字符型LCD简介
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,本设计采用16列*2行的字符型LCD1602带背光的液晶显示屏。
1602LCD主要技术参数:
显示容量:
16×2个字符
芯片工作电压:
4.5—5.5V
工作电流:
2.0mA(5.0V)
模块最佳工作电压:
5.0V
字符尺寸:
2.95×4.35(W×H)mm
3.21602引脚功能
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
数据
3
VL
液晶显示偏压
11
D4
数据
4
RS
数据/命令选择
12
D5
数据
5
R/W
读/写选择
13
D6
数据
6
E
使能信号
14
D7
数据
7
D0
数据
15
BLA
背光源正极
8
D1
数据
16
BLK
背光源负极
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位
第4脚:
RS为寄存器选择,高电平时选数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
3.31602LCD的指令说明及时序
芯片时序表如下:
读状态
输入
RS=L,R/W=H,E=H
输出
D0—D7=状态字
写指令
输入
RS=L,R/W=L,D0—D7=指令码,E=高脉冲
输出
无
读数据
输入
RS=H,R/W=H,E=H
输出
D0—D7=数据
写数据
输入
RS=H,R/W=L,D0—D7=数据,E=高脉冲
输出
无
基本操作时序表
读写操作时序如图2-7和2-8所示:
图2-7读操作时序
图2-8写操作时序
3.41602LCD的RAM地址映射及标准字库表
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认入显示字符地址,也就是告诉模块在哪里显示字符,图2-9是1602的内部显示地址。
图2-9液晶内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?
这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
是自动右移的,无需人工干预。
每次输入指令前都要判断液晶模块是否处于忙的状态。
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
3.51602LCD的一般初始化(复位)过程
延时15mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)以后每次写指令、读/写数据操作均要检测忙信号
写指令38H:
显示模式设置
写指令08H:
显示关闭
写指令01H:
显示清屏
写指令06H:
显示光标移动设置
写指令0CH:
显示开及光标设置
第4章系统硬件概况
4.1系统概况
单片机控制模块是整个设计方案的核心。
AT59C51芯片作为该系统的控制部件,它通过DS1302将时间实时通过硬件电路转送入单片机内部,单片机内部将时间转换成字符串然后送入LCD1602模块显示。
键盘通过AT59C51还控制LCD1602模块对万年历的显示与调节。
其系统原理图如下:
4.2MCS-51单片机最小系统模块
(1)晶振电路:
在XTALI与XTAL2外接石英晶体和微调电容等构成时钟电路。
其中,晶体的选择至少必须考虑:
谐振频点,负载电容,激励功率,温度特性,长期稳定性。
选择电容C1,C2:
在许可范围内,C1,C2值越低越好。
C值偏大虽有利于振荡器的稳定,但将会增加起振时间。
应使C2值大于C1值,这样可使上电时,加快晶振起振。
4.3DS1302时钟芯片控制模块
(1)时钟芯片DS1302的工作原理:
DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图所示。
为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表示进行读操作,控制字节总是从最低位开始输出
表-1DS1302的控制字格式
RAMRD
1A4A3A2A1A0
/CK/WR
(3)数据输入输出(I/O)
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
如下图1所示
图1DS1302读/写时序图
(4)DS1302的寄存器
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表-2。
表-2DS1302的日历、时间寄存器
写寄存器
读寄存器
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
80H
81H
CH
10秒
秒
82H
83H
10分
分
84H
85H
12/
0
10
时
时
/PM
86H
87H
0
0
10日
日
88H
89H
0
0
0
10月
月
8AH
8BH
0
0
0
0
0
星期
8CH
8DH
10年
年
8EH
8FH
WP
0
0
0
0
0
0
0
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:
一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
本设计总的用了三个按扭开关作为调整设置按键,三个中的其中两个是调整时间增加、减少的键,第三个是切换年、月、日及时、分、秒的显示状态并在所切换的显示状态下配合加减两个键调整时间。
4.4LCM1602显示模块
单片机P0.0~P0.7分别于lcd模块的D0~D7数据线连接,P2.0~P2.2接到lcd模块控制信号引脚RS、RW和E,lcd模块的VDD引脚接电源+5v,VSS和VEE引脚接地。
结合LCM1602控制指令,通过AT89C51单片机来控制LCM1602显示相应的时间。
第5章软件控制系统概况
5.1程序流程概况
该控制系统主要包括单片机对LCM1602液晶温度显示与万年历显示控制两部分。
软件控制程序主要有主控程序、电子时钟的时间控制程序和温度显示程序组成。
主控程序负责对整个程序进行调用与控制,进行了初始化程序还有键盘功能程序;显示程序和时间控制程序是电子时钟中比较重要的部分,时间控制程序体现了年、月、日、时、分、秒的计算方法。
软件的设计采用模块化设计与混合编程的设计思想实现,编程软件为KeiluVision4软件。
5.2流程图
时间控制程序主要是定时器0计时中断程序每隔10ms中断一次当作一个计数,每中断一次则计数加1,当计数100次时,则表示1秒到了,秒变量加1,同理再判断是否1分钟到了,再判断是否1小时到了,再判断是否1天到了,再判断是否1月到了,再判断是否1年到了,若计数到了则相关变量清除0。
先给出一般年份的每月天数。
如果是闰年,第二个月天数不为28天,而是29天。
闰年的判断规则为,如果该年份是4或100的整数倍或者是400的整数倍,则为闰年;否则为非闰年。
在我们的这个设计中由于只涉及100年范围内,所以判断是否闰年就只需要用该年份除4来判断就行了。
温度的显示主要是靠DS18B20采集现在的温度数据,CPU读取数据进行显示,当各自的条件得不到满足时,对应的显示器状态就不发生改变,只是在满足条件的情况下,显示器的状态才变化。
程序流程图如图所示:
5.3源程序代码
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitsclk=P3^6;
sbitio=P3^4;
sbitce=P3^5;
sbitlcdrs=P2^6;
sbitlcdrw=P2^5;
sbitlcden=P2^7;
sbitK0=P3^0;
sbitK1=P3^1;
sbitK2=P3^2;
sbitK3=P3^3;
ucharflag;
ucharnyr[]="2014-01-01";
ucharsfm[]="23:
59:
50Mon";
ucharweek1[]="Mon";
ucharweek2[]="Tue";
ucharweek3[]="Wed";
ucharweek4[]="Thur";
ucharweek5[]="Fri";
ucharweek6[]="Sat";
ucharweek7[]="Sun";
voidwrite_week();
voiddelay1(ucharm)
{
ucharx,y;
for(x=m;x>0;x--)
for(y=110;y>0;y--);
}
//以下为DS1302驱动程序
uchartime_data[7]={0x14,0x01,0x01,0x01,0x23,0x59,0x50};//年,周,月,日,时,分,秒
ucharyear,week,month,day,hour,minute,second;
ucharwrite_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//写地址
ucharread_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//读地址
voiddelay()
{;}
voidwrite_1302_byte(ucharadd)
{
uchari;
for(i=0;i<8;i++)
{
sclk=0;
io=add&0x01;
add=add>>1;
sclk=1;
}
}
voidwrite_1302(ucharadd1,uchardat1)
{
ce=0;
delay();
sclk=0;
delay();
delay();
ce=1;
write_1302_byte(add1);
write_1302_byte(dat1);
delay();
delay();
ce=0;
}
ucharread_1302(ucharaddr)
{
ucharj,temp=0x00;
ce=0;
delay();
sclk=0;
delay();
delay();
ce=1;
write_1302_byte(addr);
for(j=0;j<8;j++)
{
if(io)
temp=temp|0x80;
sclk=0;
temp=temp>>1;
delay();
sclk=1;
}
return(temp);
}
voidset_rtc()
{
uchari;
write_1302(0x8E,0x00);
for(i=0;i<7;i++)
{
write_1302(write_add[i],time_data[i]);
}
write_1302(0x8E,0x80);
}
voidread_rtc()
{
uchari;
for(i=0;i<7;i++)
{
time_data[i]=read_1302(read_add[i]);
}
}
///以上为DS1302的驱动程序
//以下为1602液晶显示驱动
voidwrite_1602com(ucharcom)
{
lcdrs=0;
lcdrw=0;
P0=com;
delay1(5);
lcden=1;
delay1(5);
lcden=0;
}
voidwrite_1602dat(uchardat)
{
lcdrs=1;
lcdrw=0;
P0=dat;
delay1(5);
lcden=1;
delay1(5);
lcden=0;
}
voidinit_1602()
{
uchari;
lcden=0;
write_1602com(0x38);
write_1602com(0x0c);
write_1602com(0x06);
write_1602com(0x01);
write_1602com(0x80+3);
for(i=0;i<10;i++)
{
write_1602dat(nyr[i]);
delay1(5);
}
write_1602com(0x80+0x40+1);
for(i=0;i<13;i++)
{
write_1602dat(sfm[i]);
delay1(5);
}
}
voidwrite_sfm(ucharadd,uchardat)
{
ucharshi,ge;
shi=dat/16;
ge=dat%16;
write_1602com(0x80+0x40+add);
write_1602dat(0x30+shi);
write_1602dat(0x30+ge);
}
voidwri