LCD字符型液晶显示器控制.docx
《LCD字符型液晶显示器控制.docx》由会员分享,可在线阅读,更多相关《LCD字符型液晶显示器控制.docx(21页珍藏版)》请在冰豆网上搜索。
LCD字符型液晶显示器控制
LCD字符型液晶显示器控制
实现功能:
在实验平台上扩展一块LCD点阵字符型液晶显示器,要求:
设计接口电路并编程使液晶显示器显示“当前时间”;并用按键输入与或修改时间。
工作原理及设计思路:
点阵字符型液晶显示器是专门用于显示数字、字母图形符号及少量自定义字符的显示器。
在zks-03实验仪上有一标准的LCD液晶显示器接口J4,标注为DS1602。
它与P87C52X2单片机以总线方式连接,其硬件连接如图1所示。
图1
由此可以看出LCD的命令寄存器的地址为:
0xf800而数据寄存器的地址是:
0xf801。
实验箱上的J4接口如图4所示:
J4J5
DS1602(SIP16)LCD_L
从左到右对应的管脚分别为:
1:
GND
2:
VCC
3:
V0——接0~5V电压,调节LCD的对比度(实验箱上让它接地,使对比度达到最大)
4:
RS——寄存器选择:
“0”选指令寄存器;“1”选数据寄存器
5:
R/W——“1”读操作;“0”写操作
6:
EN——使能信号
7~14:
DB0~DB7——八位双向数据信号线
15~16:
LCD背光电源
将液晶显示器与J4接口对应连接好,编写读写程序,便对液晶显示器进行控制。
电路仿真
程序
#include
#defineuintunsignedint
#defineucharunsignedchar
uchara,miao,shi,fen,ri,yue,nian,week,flag,temp,key1n;
#defineyh0x80//第一行的初始位置
#defineer0x80+0x40//第二行初始位置
//sbitcs1=P3^7;
//sbitledk=P2^5;
sbitdula=P2^6;
sbitwela=P2^7;
sbitwr=P1^1;
sbitrs=P1^0;
sbiten=P2^5;
sbitSCLK=P2^1;//6P1.1
sbitIO=P2^0;//7P1.0
sbitRST=P2^4;//时钟5P1.2
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitkey=P3^7;
sbitkey1=P3^0;
sbitkey2=P3^1;
sbitkey3=P3^2;
ucharcodetab1[]={"2009--THU"};
ucharcodetab2[]={":
:
"};
voiddelay(uintxms)//延时函数
{
uintx,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
/******************液晶写入************************/
write_1602com(ucharcom)//液晶写入指令函数
{
rs=0;//置为写入命令
P0=com;//送入数据
delay
(1);
en=1;//拉高使能端
delay
(1);
en=0;//完成高脉冲
}
write_1602dat(uchardat)
{
rs=1;//置为写入数据
P0=dat;//送入数据
delay
(1);
en=1;
delay
(1);
en=0;
}
/*********************over***********************/
/********************ds1302****************************/
voidwrite_byte(uchardat)
{
ACC=dat;
RST=1;
for(a=8;a>0;a--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
ucharread_byte()
{
RST=1;
for(a=8;a>0;a--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return(ACC);
}
voidwrite_1302(ucharadd,uchardat)
{
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
ucharread_1302(ucharadd)
{
uchartemp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
ucharBCD_Decimal(ucharbcd)
{
ucharDecimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
voidds1302_init()
{
RST=0;
SCLK=0;
write_1302(0x80,miao|0x00);//允许写
}
voidwrite_sfm(ucharadd,uchardat)//写时分秒
{
uchargw,sw;
gw=dat%10;
sw=dat/10;
write_1602com(er+add);
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);
}
voidwrite_nyr(ucharadd,uchardat)
{
uchargw,sw;
gw=dat%10;
sw=dat/10;
write_1602com(yh+add);
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);
}
voidwrite_week(ucharweek)//写星期函数
{
write_1602com(yh+0x0d);
switch(week)
{
case1:
write_1602dat('M');//delay(5);
write_1602dat('O');//delay(5);
write_1602dat('N');
break;
case2:
write_1602dat('T');//delay(5);
write_1602dat('U');//delay(5);
write_1602dat('E');
break;
case3:
write_1602dat('W');//delay(5);
write_1602dat('E');//delay(5);
write_1602dat('D');
break;
case4:
write_1602dat('T');//delay(5);
write_1602dat('H');//delay(5);
write_1602dat('U');
break;
case5:
write_1602dat('F');//delay(5);
write_1602dat('R');//delay(5);
write_1602dat('I');
break;
case6:
write_1602dat('S');//delay(5);
write_1602dat('T');//delay(5);
write_1602dat('A');
break;
case7:
write_1602dat('S');//delay(5);
write_1602dat('U');//delay(5);
write_1602dat('N');
break;
}
}
lcd_init()//液晶初始化函数
{wr=0;
write_1602com(0x38);//设置液晶工作模式
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,指针加一
write_1602com(0x01);
write_1602com(yh+2);//字符写入的位置
for(a=0;a<14;a++)
{
write_1602dat(tab1[a]);
//delay(3);
}
write_1602com(er+4);
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);
//delay(3);
}
}
voidkeyscan()
{
key=0;
if(key1==0)//key1为功能键
{
delay(5);
if(key1==0)
{
while(!
key1);
key1n++;
if(key1n==9)
key1n=1;
switch(key1n)
{
case1:
TR0=0;//关闭定时器
//TR1=0;
write_1602com(er+0x0b);//写入光标位置
write_1602com(0x0f);//设置光标为闪烁
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x80|temp);//miao
write_1302(0x8e,0x80);
break;
case2:
write_1602com(er+8);//fen
//write_1602com(0x0f);
break;
case3:
write_1602com(er+5);//shi
//write_1602com(0x0f);
break;
case4:
write_1602com(yh+0x0f);//week
//write_1602com(0x0f);
break;
case5:
write_1602com(yh+0x0b);//ri
//write_1602com(0x0f);
break;
case6:
write_1602com(yh+0x08);//yue
//write_1602com(0x0f);
break;
case7:
write_1602com(yh+0x05);//nian
//write_1602com(0x0f);
break;
case8:
write_1602com(0x0c);//设置光标不闪烁
TR0=1;//打开定时器
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x00|temp);//miao
write_1302(0x8e,0x80);
break;
}
}
}
if(key1n!
=0)//当key1按下以下。
再按以下键才有效
{
if(key2==0)//上调键
{
delay(5);
if(key2==0)
{
while(!
key2);
switch(key1n)
{
case1:
miao++;
if(miao==60)
miao=0;
write_sfm(0x0a,miao);//写入新的秒数
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x80|temp);
write_1302(0x8e,0x80);
write_1602com(er+0x0b);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
//write_1602com(0x0b);
break;
case2:
fen++;
if(fen==60)
fen=0;
write_sfm(0x07,fen);
temp=(fen)/10*16+(fen)%10;
write_1302(0x8e,0x00);
write_1302(0x82,temp);
write_1302(0x8e,0x80);
write_1602com(er+8);
break;
case3:
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
temp=(shi)/10*16+(shi)%10;
write_1302(0x8e,0x00);
write_1302(0x84,temp);
write_1302(0x8e,0x80);
write_1602com(er+5);
break;
case4:
week++;
if(week==8)
week=0;
write_week(week);
write_1602com(yh+0x0f);
break;
case5:
ri++;
if(ri==31)
ri=0;
write_nyr(10,ri);
temp=(ri)/10*16+(ri)%10;
write_1302(0x8e,0x00);
write_1302(0x86,temp);
write_1302(0x8e,0x80);
write_1602com(yh+11);
break;
case6:
yue++;
if(yue==13)
yue=0;
write_nyr(7,yue);
temp=(yue)/10*16+(yue)%10;
write_1302(0x8e,0x00);
write_1302(0x88,temp);
write_1302(0x8e,0x80);
write_1602com(yh+8);
break;
case7:
nian++;
if(nian==100)
nian=0;
write_nyr(4,nian);
write_1602com(yh+5);
break;
}
}
}
if(key3==0)
{
delay(5);
if(key3==0)
{
while(!
key3);
switch(key1n)
{
case1:
miao--;
if(miao==-1)
miao=59;
write_sfm(0x0a,miao);//写入新的秒数
write_1602com(er+0x0b);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
//write_1602com(0x0b);
break;
case2:
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
temp=(fen)/10*16+(fen)%10;
write_1302(0x8e,0x00);
write_1302(0x82,temp);
write_1302(0x8e,0x80);
write_1602com(er+8);
break;
case3:
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
temp=(shi)/10*16+(shi)%10;
write_1302(0x8e,0x00);
write_1302(0x84,temp);
write_1302(0x8e,0x80);
write_1602com(er+5);
break;
case4:
week--;
if(week==-1)
week=7;
write_week(week);
write_1602com(yh+0x0f);
break;
case5:
ri--;
if(ri==-1)
ri=30;
write_nyr(10,ri);
temp=(ri)/10*16+(ri)%10;
write_1302(0x8e,0x00);
write_1302(0x86,temp);
write_1302(0x8e,0x80);
write_1602com(yh+11);
break;
case6:
yue--;
if(yue==-1)
yue=12;
write_nyr(7,yue);
temp=(yue)/10*16+(yue)%10;
write_1302(0x8e,0x00);
write_1302(0x88,temp);
write_1302(0x8e,0x80);
write_1602com(yh+8);
break;
case7:
nian--;
if(nian==-1)
nian=99;
write_nyr(4,nian);
write_1602com(yh+5);
break;
}
}
}
}
}
voidinit()
{
TMOD=0x11;
TH0=0;
TL0=0;
EA=1;
ET0=1;
TR0=1;
}
voidcmg(void)//数码管锁存函数
{
dula=1;
P0=0x00;
dula=0;
wela=1;
P0=0x00;
wela=0;
}
voidmain()
{
cmg();//数码管锁存
lcd_init();
ds1302_init();
init();
while
(1)
{
//TH0=(65536-60000)/256;
//TL0=(65536-60000)%256;
keyscan();
}
}
voidtimer0()interrupt1
{
miao=BCD_Decimal(read_1302(0x81));
fen=BCD_Decimal(read_1302(0x83));
shi=BCD_Decimal(read_1302(0x85));
ri=BCD_Decimal(read_1302(0x87));
yue=BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
week=BCD_Decimal(read_1302(0x8b));
//keyscan();
write_sfm(10,miao);
//write_1602com(er+0x0a);
//write_1602dat(':
');
write_sfm(7,fen);
//write_1602com(er+0x07);
//write_1602dat(':
');
write_sfm(4,shi);
//write_nyr(4,nian);
write_nyr(10,ri);
write_nyr(7,yue);
//write_week(week);
}