单片机课程设计 LCD显示万年历EPROM存储Word下载.docx
《单片机课程设计 LCD显示万年历EPROM存储Word下载.docx》由会员分享,可在线阅读,更多相关《单片机课程设计 LCD显示万年历EPROM存储Word下载.docx(32页珍藏版)》请在冰豆网上搜索。
1、增强型8051CPU,1T(1024G),单时钟机器周期
2、工作电压5.5-3.5V
3、1280字节RAM
4、通用I/O口,复位后为:
准双向口/弱上拉
可设置成四种模式:
准双向口/弱上拉,强推挽/强上拉,仅为输入/高阻,开漏每个I/O口驱动能力均可达到20mA,但整个芯片最大不要超过120mA
5、有EEPROM功能
6、看门狗
7、内部集成MAX810专用复位电路
8、外部掉电检测电路
9、时钟源:
外部高精度晶体/时钟,内部R/C振荡器常温下内部R/C
振荡器频率为:
5.0V
单片机为:
11~17MHz3.3V
8~12MHz针对电机控制,强干扰场合。
对应电路图中的单片机的周围电路,图为89C51
用protus软件的仿真图使用的是89c51
3.2LCD1602液晶显示模块
液晶显示模块
1602采用标准的16脚接口,其中:
第1脚:
VSS为电源地
第2脚:
VDD接5V电源正极
第3脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4脚:
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:
RW为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作。
第6脚:
E(或EN)端为使能(enable)端。
第7~14脚:
D0~D7为8位双向数据端。
第15~16脚:
空脚或背灯电源。
15脚背光正极,16脚背光负极。
2LCD1602特性
+5V电压,对比度可调 内含复位电路 提供各种控制命令,如:
清屏、字符闪烁、光标闪烁、显示移位等多种功能 有80字节显示数据存储器DDRAM 内建有192个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM
3.2.2LCD1602模块内部结构
LCM1602内部主要寄存器有:
输入/输出缓冲器,指令寄存器(InstuctionRegister,即IR),指令译码器,数据寄存器(DataRegister,即DR),地址计数器(AddressCounter,即AC),忙标识(BusyFlag,即BF)以及显示数据存储器(DisplayDataRAM,即DDRAM),字符发生器(CharacterGenerateROM,即CGROM)。
其各个单元的功能作用如下:
1.输入/输出缓冲器,用于缓存输入/输出的数据与控制信号。
2.指令寄存器(IR),为八位寄存器。
用于存放LCD指令、DDRAM或CGROM地址。
数据输入流程:
数据存入DR,然后将该数据地址与指令存入IR,最后将该数据输入到DDRAM或CGROM。
读取数据流程:
将该数据地址与指令存入IR,DR取得该地址数据。
3.指令译码器,将IR里的指令进行译码,以获取DDRAM或CGROM地址。
4.数据寄存器(DR),连接LCM内部数据总线以及缓存DDRAM或CGROM的存取数据。
当CPU读取DR内容后,DR能自动加载下一个地址的内容。
5.地址计数器(AC),连接LCM内部数据总线以及缓存DDRAM或CGROM的存取数据地址。
当存取DDRAM或CGROM的数据地址,AC能自动加载下一个存储地址。
6.忙标识(BF),表示LCM的当前状态。
若BF=1,则表示LCM处于忙绿状态,无法接收外部数据或指令。
7.显示数据存储器(DDRAM),存储所要显示数据的ASCII码,根据该ASCII码地址,即可到CGROM里找到该字符的显示编码。
8.字符发生器(CGROM),是一个只读存储器,预制所有数据的ASCII码。
其存储的编码表如下(表3-5):
此外,还有自定义字符发生器,串行/并行数据转换器,光标闪烁控制电路,时序产生电路,偏压产生电路,共同端驱动电路以及段驱动电路等。
3.5蜂鸣器
本设计采用的是无源蜂鸣器如下图:
图13无源蜂鸣器
3.6键盘接口
键盘接口电路如图,本次设计中,按键有3个,每个按键各占用一根I/O线,各按键相互独立,彼此的工作状态互不影响,用查询法完成按键功能。
图1键盘接口电路
5EPROM
EPROM是一种具有可擦除功能,擦除后即可进行再编程的ROM内存,写入前必须先把里面的内容用紫外线照射它的IC卡上的透明视窗的方式来清除掉。
这一类芯片比较容易识别,其封装中包含有“石英玻璃窗”,一个编程后的EPROM芯片的“石英玻璃窗”一般使用黑色不干胶纸盖住,以防止遭到阳光直射。
EPROM芯片可重复擦除和写入,解决了PROM芯片只能写入一次的弊端。
EPROM芯片有一个很明显的特征,在其正面的陶瓷封装上,开有一个玻璃窗口,透过该窗口,可以看到其内部的集成电路,紫外线透过该孔照射内部芯片就可以擦除其内的数据,完成芯片擦除的操作要用到EPROM擦除器。
EPROM内资料的写入要用专用的编程器,并且往芯片中写内容时必须要加一定的编程电压(VPP=12—24V,随不同的芯片型号而定)。
EPROM的型号是以27开头的,如27C020(8*256K)是一片2MBits容量的EPROM芯片。
EPROM芯片在写入资料后,还要以不透光的贴纸或胶布把窗口封住,以免受到周围的紫外线照射而使资料受损。
EPROM芯片在空白状态时(用紫外光线擦除后),内部的每一个存储单元的数据都为1(高电平)。
4.系统软件设计
4.1时间程序
使用中断并定时器T0的方式1,时分秒计数,采用24的时钟表示法,时计满23则回0,分秒计满59则回0,键盘输入可调,为4*4对地独立键盘中的某三个键,其中一个为功能键,用于调整时分秒,另外两个键用于调节数字使之上调和下调,其中日期可显示初始化程序,不可调,另外可以显示星期。
初始化时,只需通过P1口中的低两位读取
5.调试
5.1调试步骤
调试分为硬件调试和软件调试。
硬件调试主要是检查硬件电路是否有短路、断路和虚焊等,首先接上电源,电源的指示灯亮了之后,检测一下单片机的电源脚有没有电源输入,如果有这说明焊接无误,然后可以用万用表检查各个元器件的管脚之间的焊接,检查过程中需要细心和耐心。
硬件调试无误后,进行软件调试。
5.2性能分析
将程序烧入单片机后,在proteus软件中进行仿真。
。
经过测试制作完成后的电子万年历,只有部分功能实现,它能显示年、月、日等,但显示不稳定,设计中硬件或软件有待修正。
6.心得
首先拿到板子,依据电路图和板子,画电路图,并生成PCB图。
然后将板子焊接,注意焊接的方法,避免虚焊和过度焊接。
在对芯片的管脚功能和用法有充分的了解后,根据设计要求设计硬件电路,包括单片机控制电路、存储电路、键盘扫描电路、显示电路。
然后通过软件编程,实现了对年、月、日、时、分、秒、星期的自动调整,用按键进行控制,用液晶模块进行显示。
用PROTUS仿真实现相关的软件仿真,芯片采用最普遍的89C51,用KEIL软件编写程序,编写程序前,可以先查阅网上的相关资料,比如LCD芯片的原理图,有关可以借鉴的程序等。
自己编写,然后生成hex文件,仿真实现。
用焊接好的板子,将文件烧录进去,调试,查错。
可能会出现LCD屏幕不显示,或者出现一行黑一行白的现象,可能是插反了,或者驱动程序有问题,这时候需要根据实际的板子的需要,调整延迟时间,等等。
调试成功。
电子万年历可以正常显示时间并进行时间调整,基本完成了预期要实现的目标。
附录1系统电路原理图
SCH文件——选择自上而下的文件画法,可能有些器件的摆放有点乱
单片机级复位电路
数码管和4*4矩阵
ISP和电源接口
LED灯
蜂鸣器和lcd屏
顶层文件
附录2,PCB图
附录四:
PCB3D图
附录3实物图
附录4系统程序清单
/*******************************************************************************************
#include<
reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
#include"
24c02.h"
/***********LCM1602IO口位定义***********/
sbitRS=P2^2;
sbitRW=P2^1;
sbitEN=P2^0;
/*************独立控制按键位定义*****************************************************/
sbitkey1=P1^5;
//功能
sbitkey2=P1^6;
//加
sbitkey3=P1^7;
//减
/*************蜂鸣器IO口定义*****************************************************/
sbitSpeaker=P2^6;
//接蜂鸣器接口
sbitRedLed=P2^7;
ucharkey1n,count;
uinthour,minute,second;
ucharcodetab[]="
2013-7-2THU"
;
//定义初始上电时液晶默认显示状态
/*************延时子函数,延时z毫秒*****************************************************/
voiddelay(uintz)
{
uinti,j;
for(i=0;
i<
z;
i++)
for(j=0;
j<
110;
j++);
}
voiddi()
Speaker=0;
delay(400);
Speaker=1;
////////////////////////////////////////////////////////
/*******************LCD1602有关子函数******************/
///////////////////////////////////////////////////////
/*************
函数功能:
LCD1602写命令函数
入口参数:
com
出口参数:
*****************************************************/
voidwrite_com(ucharcom)
RS=0;
RW=0;
EN=0;
P0=com;
delay(5);
EN=1;
LCD1602写数据函数
dat
voidwrite_data(uchardat)
RS=1;
P0=dat;
时分秒显示函数
voidDisplayTime(ucharadd,uchardat)
i=dat/10;
j=dat%10;
write_com(0x80+0x40+add);
write_data(0x30+i);
write_data(0x30+j);
}
LCM1602初始化
voidinit_LCD1602()
uchari;
minute=0;
hour=0;
second=0;
key1n=0;
count=0;
init_24c02();
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
//日历显示固定符号从第一行第1个位置之后开始显示
15;
{
write_data(tab[i]);
//向液晶屏写日历显示的固定符号部分
delay(5);
}
write_com(0x80+0x40+6);
//写出时间显示部分的两个冒号
write_data('
:
'
);
write_com(0x80+0x40+9);
second=read_add
(1);
//首次上电从AT24C02中读取出存储的数据
minute=read_add
(2);
hour=read_add(3);
DisplayTime(10,second);
//分别送去液晶显示
DisplayTime(7,minute);
DisplayTime(4,hour);
TMOD=0x01;
//设置定时器0工作模式1
TH0=(65536-50000)/256;
//定时器装初值
TL0=(65536-50000)%256;
EA=1;
//开总中断
ET0=1;
//开定时器0中断
TR0=1;
//启动定时器0
/////////////////////////////////////////////////////////////////
/**************按键扫描4*4独立对地矩阵**************************/
/*************
独立对地键盘扫描
;
voidKeyScan()
{
if(key1==0)
if(key1==0)//第一次被按下时
{
key1n++;
while(!
key1);
di();
RedLed=0;
RedLed=1;
if(key1n==1)//第一次被按下时
{
TR0=0;
//关闭定时器
write_com(0x80+0x40+10);
//光标定位到秒位置
write_com(0x0f);
//光标开始闪烁
}
if(key1n==2)//第二次按下光标闪烁定位到分钟位置
write_com(0x80+0x40+7);
if(key1n==3)//第三次按下光标闪烁定位到小时位置
write_com(0x80+0x40+4);
if(key1n==4)//第四次按下
key1n=0;
//记录按键数清零
write_com(0x0c);
//取消光标闪烁
TR0=1;
//启动定时器使时钟开始走
}
}
}
if(key1n!
=0)//只有功能键被按下后,增加和减小键才有效
if(key2==0)
delay(5);
if(key2==0)//增加键确认被按下
while(!
key2);
//按键释放
di();
//每当有按键释放蜂鸣器发出滴声
RedLed=0;
delay(10);
RedLed=1;
if(key1n==1)//若功能键第一次按下
{
second++;
//则调整秒加1
if(second==60)//若满60后将清零
second=0;
DisplayTime(10,second);
//每调节一次送液晶显示一下
write_com(0x80+0x40+10);
//显示位置重新回到调节处
write_add(1,second);
//数据改变立即存入24C02
}
if(key1n==2)//若功能键第二次按下
minute++;
//则调整分钟加1
if(minute==60)//若满60后将清零
minute=0;
DisplayTime(7,minute);
write_com(0x80+0x40+7);
write_add(2,minute);
//数据改变立即存入24C02
if(key1n==3)//若功能键第三次按下
hour++;
//则调整小时加1
if(hour==24)//若满24后将清零
hour=0;
DisplayTime(4,hour);
write_com(0x80+0x40+4);
write_add(3,hour);
if(key3==0)
if(key3==0)//确认减小键被按下
key3);
second--;
//则调整秒减1
if(second==-1)//若减到负数则将其重新设置为59
second=59;
minute--;
//则调整分钟减1
if(minute==-1)//若减到负数则将其重新设置为59
minute=59;
if(key1n==3)//若功能键第二次按下
hour--;
//则调整小时减1
if(hour==-1)//若减到负数则将其重新设置为23
hour=23;
主函数
调用子程序:
voidmain()
init_LCD1602();
//液晶屏初始化
while
(1)
KeyScan();
中断+键值
voidtimer0()interrupt1//取得并显示日历和时间
//再次装定时器初值
count++;
//中断次数累加
if(count==20)//20次50毫秒为1秒
count=0;
second++;
if(second==60)//秒加到60则进位分钟
second=0;
//同时秒数清零
minute++;