最新LCD1602原理及显示程序.docx
《最新LCD1602原理及显示程序.docx》由会员分享,可在线阅读,更多相关《最新LCD1602原理及显示程序.docx(20页珍藏版)》请在冰点文库上搜索。
最新LCD1602原理及显示程序
LCD1602原理及显示程序
在日常生活中,我们对液晶显示器并不陌生。
液晶显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。
在单片机的人机交流界面中,一般的输出方式有以下几种:
发光管、LED数码管、液晶显示器。
发光管和LED数码管比拟常用,软硬件都比拟简单,在前面章节已经介绍过,在此不作介绍,本章重点介绍字符型液晶显示器的应用。
在单片机系统中应用晶液显示器作为输出器件有以下几个优点:
显示质量高
由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器〔CRT〕那样需要不断刷新新亮点。
因此,液晶显示器画质高且不会闪烁。
数字式接口
液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
体积小、重量轻
液晶显示器通过显示屏上的电极控制液晶分子状态来到达显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
功耗低
相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。
10.8.1液晶显示简介
①液晶显示原理
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。
液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。
②液晶显示器的分类
液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。
除了黑白显示外,液晶显示器还有多灰度有彩色显示等。
如果根据驱动方式来分,可以分为静态驱动〔Static〕、单纯矩阵驱动〔SimpleMatrix〕和主
“1〞的点亮,为“0〞的不亮。
这样一来就组成某个字符。
但由于内带字符发生器的控制器来说,显示字符就比拟简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
汉字的显示
汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码〔一般用字模提取软件〕,每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字。
10.8.21602字符型LCD简介
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。
下面以长沙太阳人电子有限公司的1602字符型液晶显示器为例,介绍其用法。
一般1602字符型液晶显示器实物如图10-53:
图10-531602字符型液晶显示器实物图
10.8.2.11602LCD的根本参数及引脚功能
1602LCD分为带背光和不带背光两种,基控制器大局部为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差异,两者尺寸差异如下列图10-54所示:
图10-541602LCD尺寸图
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所示:
序号
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清显示
0
0
0
0
0
0
0
0
0
1
2
光标返回
0
0
0
0
0
0
0
0
1
*
3
置输入模式
0
0
0
0
0
0
0
1
I/D
S
4
显示开/关控制
0
0
0
0
0
0
1
D
C
B
5
光标或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符发生存贮器地址
0
0
0
1
字符发生存贮器地址
8
置数据存贮器地址
0
0
1
显示数据存贮器地址
9
读忙标志或地址
0
1
BF
计数器地址
10
写数到CGRAM或DDRAM〕
1
0
要写的数据内容
11
从CGRAM或DDRAM读数
1
1
读出的数据内容
表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-571602LCD内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?
这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B〔40H〕+10000000B(80H)=11000000B(C0H)。
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。
每次输入指令前都要判断液晶模块是否处于忙的状态。
1602液晶模块内部的字符发生存储器〔CGROM〕已经存储了160个不同的点阵字符图形,如图10-58所示,这些字符有:
阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比方大写的英文字母“A〞的代码是01000001B〔41H〕,显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A〞
图10-58字符代码与图形对应图
10.8.2.51602LCD的一般初始化〔复位〕过程
延时15mS
写指令38H〔不检测忙信号〕
延时5mS
写指令38H〔不检测忙信号〕
延时5mS
写指令38H〔不检测忙信号〕
以后每次写指令、读/写数据操作均需要检测忙信号
写指令38H:
显示模式设置
写指令08H:
显示关闭
写指令01H:
显示清屏
写指令06H:
显示光标移动设置
写指令0CH:
显示开及光标设置
10.8.31602LCD的软硬件设计实例
在1602LCD第一行显示网站名:
在第二行显示联系电话:
0571-********。
实验前应先将显示切换开关切换到LCD工作状态。
10.8.3.1硬件原理图
LCD液晶显示,用16F877A写程序如下:
写一个字符串程序:
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDBPORTD//定义端口
#definersRB0
#defineeRB1
__CONFIG(0x3B31);
constuchardata[]="happyeveryday";//输入的字符串第一行
constuchardata1[]="xiexie";//第二行
voidinit();
voidwrite_commond(uchardat);//写指令函数
voidwrite_data(uchardat);//写数据函数
voiddelay(uintx);
voiddelay(uintx)
{
uinta,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
voidinit()//初始化指令
{
write_commond(0x01);//0000000001,去除屏幕显示
write_commond(0x28);//设置4位格式,2行,5X7,功能设定
write_commond(0x0C);//0000001100,开显示,无光标,不闪烁
write_commond(0x06);//0000000110,置输入模式,光标右移,屏幕上的文字不移动
write_commond(0x14);//0001000100,设定CGRAM地址显示屏或光标移动方向
}
voidwrite_commond(uchardat)
{
rs=0;//指令
DB=dat;
e=1;//允许下降沿触发1-0
delay(5);
e=0;
DB=DB<<4;//左移四位从RD4~RD7进入LCD
delay(5);
e=1;
delay(5);
e=0;
}
voidwrite_data(uchardat)
{
rs=1;//数据
DB=dat;
e=1;//允许
delay(5);
e=0;
delay(5);
DB=DB<<4;
e=1;
delay(5);
e=0;
}
voidmain()
{
uchari;
TRISD=0X00;//定义端口存放器
PORTD=0X00;
PORTB=0X00;
TRISB=0X00;
init();
write_commond(0x80);//第一行的DDRAM的地址,不加0x10时,也可以从//最左边开始
for(i=0;i<12;i++)
{
write_data(data[i]);//第一行的数据字符
delay(5);
}
write_commond(0xc0);//第二行的DDRAM地址不加0x10也可
for(i=0;i<16;i++)
{
write_data(data[i]);//第二行的数据字符
delay(5);
}
/*for(i=0;i<16;i++)
{
write_commond(0x18);//光标不动,数据左移一位
delay(5);
}*/
while
(1);
}
写近一个字符A程序如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDBPORTD
#definersRB0
#defineeRB1
__CONFIG(0x3B31);
voidinit();
voidwrite_commond(uchardat);//写指令函数
voidwrite_data(uchardat);//写数据函数
voiddisp_char(ucharx,uchary,uchardat);//在屏幕某个位置显示一个字符,x(0-16),y(1-2)
voiddelay(uintx);
voiddelay(uintx)
{
uinta,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
voidinit()//初始化指令
{
write_commond(0x01);//0000000001,去除屏幕显示
write_commond(0x28);//设置4位格式,2行,5X7,功能设定
write_commond(0x0C);//0000001100,开显示,无光标,不闪烁
write_commond(0x06);//0000000110,置输入模式,光标右移,屏幕上的文字不移动
write_commond(0x80);//0001000100,设定CGRAM地址显示屏或光标移动方向
}
voidwrite_commond(uchardat)
{
rs=0;//指令
DB=dat;
e=1;//允许
delay(5);
e=0;
DB=DB<<4;
delay(5);
e=1;
delay(5);
e=0;
}
voidwrite_data(uchardat)
{
rs=1;//数据
DB=dat;
e=1;//允许
delay(5);
e=0;
delay(5);
DB=DB<<4;
e=1;
delay(5);
e=0;
}
voiddisp_char(ucharx,uchary,uchardat)
{
ucharaddress;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
write_commond(address);
write_data(dat);
delay(5);
}
voidmain()
{
TRISD=0X00;
PORTD=0X00;
PORTB=0X00;
TRISB=0X00;
init();
disp_char(0,1,'A');
while
(1);
}
也可以是如下:
voiddisp_char(ucharx,uchary,uchardat)
{
uchari;
write_commond(0x80+x);
if(i=0;i<16;i++)
{
write_data('A');
delay(5);
}
}