基于51单片机的万年历Word文档下载推荐.docx
《基于51单片机的万年历Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于51单片机的万年历Word文档下载推荐.docx(46页珍藏版)》请在冰豆网上搜索。
万年历的设计过程在硬件与软件方面进行同步设计。
硬件部分主要由AT89C52单片机,LCD1602显示电路,以及调时按键电路等组成。
在单片机的选择上本人使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合,显示器使用1片LCD1602。
软件方面主要包括日历程序、时间调整程序,显示程序等。
本设计直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
程序采用C语言编写,所有程序编写完成后,在KeiluVision3软件中进行调试,确定没有问题后,用STC_ISP_V4.80下载到单片机进行检验。
最后在老师同学网络的帮助以及自己的努力下完成了此次电子万年历的设计。
二、系统的硬件设计与实现
洞洞板/万能板成品
图片左下角有地址-有录像
2.1电路设计框图
2.2系统硬件概述
本电路是由AT89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;
本设计直接采用单片机定时计数器提供秒信号,它可以对年、月、日、星期、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
显示部份由LCD1602完成。
2.3主要单元电路的设计
2.3.1单片机主控制模块的设计
AT89C52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。
单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,X1接外部晶振和微调电容的一端,在片它是振荡器倒相放大器的输入,X2接外部晶振和微调电容的另一端,在片它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端.如下图所示
2.3.2键盘电路模块的设计
键盘模块由四个独立键盘组成,每个按键的一钟脚接地,另一种脚接一个单片机I/O口。
如下图所示。
2.3.3显示模块的设计
显示模块通过一块16脚的LCD1602组成。
其中1、3脚接地,4、5、6分别接一个I/O口用于控制液晶的显示,7--14接P2的8个I/O口用于数据传输。
15、16脚用于控制液晶的背光,可不接。
液晶1602的简介及驱动原理
1602LCD主要技术参数:
显示容量:
16×
2个字符
芯片工作电压:
4.5—5.5V
工作电流:
2.0mA(5.0V)
模块最佳工作电压:
5.0V
字符尺寸:
2.95×
4.35(W×
H)mm
引脚功能说明
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表10-13所示:
编号
符号
引脚说明
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
背光源负极
表10-13:
引脚接口说明表
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
10.8.2.31602LCD的指令说明及时序
1602液晶模块部的控制器共有11条控制指令,如表10-14所示:
序号
指令
清显示
光标返回
*
置输入模式
I/D
S
显示开/关控制
D
C
B
光标或字符移位
S/C
R/L
置功能
DL
N
F
置字符发生存贮器地址
字符发生存贮器地址
置数据存贮器地址
显示数据存贮器地址
读忙标志或地址
BF
计数器地址
写数到CGRAM或DDRAM)
要写的数据容
从CGRAM或DDRAM读数
读出的数据容
表10-14:
控制命令表
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:
1为高电平、0为低电平)
指令1:
清显示,指令码01H,光标复位到地址00H位置。
指令2:
光标复位,光标返回到地址00H。
指令3:
光标和显示模式设置I/D:
光标移动方向,高电平右移,低电平左移S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时移动显示的文字,低电平时移动光标。
指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低电平时为单行显示,高电平时双行显示F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
与HD44780相兼容的芯片时序表如下:
读状态
输入
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=高脉冲
表10-15:
基本操作时序表
读写操作时序如图10-55和10-56所示:
图10-55读操作时序
图10-56写操作时序
10.8.2.41602LCD的RAM地址映射及标准字库表
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。
要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图10-57是1602的部显示地址。
10.8.2.51602LCD的一般初始化(复位)过程
延时15mS写指令38H(不检测忙信号)延时5mS写指令38H(不检测忙信号)延时5mS
写指令38H(不检测忙信号)以后每次写指令、读/写数据操作均需要检测忙信号
写指令38H:
显示模式设置写指令08H:
显示关闭写指令01H:
显示清屏
写指令06H:
显示光标移动设置写指令0CH:
显示开及光标设置
三、系统的软件设计
3.1程序流程框图
否否否
是是是
四、总结
在整个设计过程中,遇到了很多问题,但在自己的努力和同学的帮助下得到了解决,较好的完成了作品,勉强达到了预期的目的。
并且在这一过程中也学到了许多之前没学过的知识。
在电路焊接时虽然没什么大问题,但从中也知道了焊接在整个作品中的重要性,对电路的设计、布局要先有一个好的构思,然后再焊才可以使电路板美观并且可以减少飞线的使用,并且最好焊接一部分测试一部分。
通过这次设计,特别是通过程序的编写,更深入地了解了单片机的部结构和外围器件的应用。
参考文献:
1.郭天祥《十天叫你学会单片机》
2.《C51入门教程》
3.《8051系列单片机C语言编程完全手册》
附录一:
系统电路图
附录二:
系统程序清单
#include<
reg52.h>
#include<
intrins.h>
sbitLCD_RS=P1^5;
sbitLCD_RW=P1^4;
sbitLCD_EN=P1^3;
sbits1=P2^3;
sbits2=P2^2;
sbits3=P2^0;
unsignedchartt,s1num;
charmiao,fen,shi,yue=1,ri=1,week,nian;
unsignedchara[]="
2000-01-01MON"
;
charb[]="
00:
00:
00"
voiddelay(intms)
{
inti;
while(ms--)
{
for(i=0;
i<
250;
i++)
_nop_();
}
}
delay1(unsignedintz)
{unsignedcharx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
bitlcd_busy()
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
result=(bit)(P3&
0x80);
LCD_EN=0;
returnresult;
voidwrite_(unsignedchar)
while(lcd_busy());
LCD_RW=0;
P3=;
voidwrite_date(unsignedchardate)
LCD_RS=1;
P3=date;
voidwrite_sfm(unsignedcharadd,unsignedchardate)
unsignedcharshi,ge;
shi=date/10;
ge=date%10;
write_(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
voidwrite_nyr(unsignedcharadd,unsignedchardate)
{
unsignedchargw,sw;
gw=date%10;
sw=date/10;
write_(0x80+add);
write_date(0x30+sw);
write_date(0x30+gw);
voidwrite_week(unsignedweek)
write_(0x80+0x0d);
switch(week)
case0:
write_date('
M'
);
write_date('
O'
write_date('
N'
break;
case1:
T'
U'
E'
case2:
W'
D'
case3:
H'
case4:
F'
R'
I'
case5:
S'
A'
case6:
voidinit()
{unsignedinti;
write_(0x38);
delay(5);
write_(0x0c);
write_(0x06);
write_(0x01);
write_(0x80);
for(i=0;
i<
16;
i++)
{write_date(a[i]);
delay1(5);
write_(0x80+0x40);
for(i=0;
12;
{write_date(b[i]);
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
voidkeyscan()
if(s1==0)
delay(5);
if(s1==0)
{s1num++;
while(!
s1);
if(s1num==1)
{
TR0=0;
write_(0x80+4);
write_(0x0f);
}
if(s1num==2)
write_(0x80+7);
if(s1num==3)
write_(0x80+10);
if(s1num==4)
write_(0x80+13);
if(s1num==5)
write_(0x80+0x40+4);
if(s1num==6)
write_(0x80+0x40+7);
if(s1num==7)
write_(0x80+0x40+10);
if(s1num==8)
s1num=0;
write_(0x0c);
TR0=1;
}
if(s1num!
=0)
{
if(s2==0)
delay(5);
if(s2==0)
{
while(!
s2);
if(s1num==7)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_(0x80+0x40+10);
}
if(s1num==6)
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_(0x80+0x40+7);
if(s1num==5)
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_(0x80+0x40+4);
if(s1num==4)
week++;
if(week==7)
week=0;
write_week(week);
write_(0x80+14);
if(s1num==3)
ri++;
if(yue==2&
&
(((nian+2000)%4==0)&
((nian+2000)%100!
=0)||((nian+2000)%400==0))&
ri==30)ri=1;
((nian+2000)%4!
=0)&
ri==29)ri=1;
if((yue==4||yue==6||yue==9||yue==11)&
ri==31)ri=1;
if(ri==32)ri=1;
write_nyr(10,ri);
write_(0x80+10);
if(s1num==2)
yue++;
if(yue>
12)
yue=1;
write_nyr(7,yue);
write_(0x80+7);
if(s1num==1)
nian++;
if(nian>
99)
nian=0;
write_nyr(4,nian);
write_(0x80+4);
}
}
if(s3==0)
if(s3==0)
s3);
miao--;
if(miao==-1)
miao=59;
fen--;
if(fen==-1)
fen=59;
shi--;
if(shi==-1)
shi=23;
write_(0x8