1.1 实物与仿真图
实物图
仿真原理图
1.2 LCD1602引脚
1.3、命令
-
命令1:清屏,光标返回地址00H位置(显示屏的左上方)。
-
命令2:光标返回到地址00H位置(显示屏的左上方)。
-
命令3:光标和显示模式设置。
D1——I/D—地址指针加1或减1选择位。
I/D=1,读或写一个字符后地址指针加1;
I/D=0,读或写一个字符后地址指针减1。
D0——S—屏幕上所有字符移动方向是否有效的控制位。
S=1当写入一字符时,整屏显示左移(I/D=1)或右移(I/D=0);
S=0整屏显示不移动。
-
命令4:显示开/关及光标设置。
D2——D—屏幕整体显示控制位,D=0关显示,D=1开显示。
D1——C—光标有无控制位,C=0无光标,C=1有光标。
D0——B—光标闪烁控制位,B=0不闪烁,B=1闪烁。
例如,要求液晶显示器开显示,显示光标且光标闪烁,那么根据显示开关及光标设置命令(命令4),只要令D=1,C=1和B=1,也就是写入命令“00001111B”,即0FH,就可实现所需的显示模式。
-
命令5(0001 D3D2D1D0):光标或字符移位。
D3——S/C—光标或字符移位选择控制位。S/C=1移动显示的字符,S/C=0移动光标。
D2——R/L—移位方向选择控制位。0:左移,1:右移。
-
命令6(001D4 D3D2D1D0):功能设置命令。
D4——DL—传输数据的有效长度选择控制位。1:8位数据线接口;0:4位数据线接口。
D3——N—显示器行数选择控制位。0:单行显示,1:两行显示。
D2——F—字符显示的点阵控制位。0:显示5´7点阵字符,1:显示5´10点阵字符。
例如,将显示模式设置为“16´2显示,5´7点阵,8位数据接口”,只需要向1602写入功能设置命令(命令6)“00111000B”,即38H即可。
-
命令7(01XX XXXX):CGRAM地址设置。
0X40~0X40+8*8共有64字节空间,用来存放8个自定义的5X8点阵(5列8行)的字符。
这里点阵是高电平点亮,逐行扫描,仅用低5列。
注意命令6中F位为字符显示的点阵控制位,0:显示5X7点阵(此时仅显示前7行,最后一行不显示),1:显示5X10点阵(此时显示5X8点阵)。
字符取模流程举例:
第一步:生成8X8点阵(不直接用5X8点阵),并点亮生成字符的相似图像。(仅低5列有效)(如果直接用5列X8行点阵,不好生成列码。因为是顺向,且高3位又没用。)
第二步:根据点阵原理进行如下设置,最终生成字符对应的列码。
列码:0x1F,0x19,0x11,0x11,0x11,0x11,0x11,0x1F
-
命令8(1XXX XXXX):DDRAM地址设置。
LCD内部有一个数据地址指针,用 户可通过它访问内部全部80字节的数据显示RAM。命令格式为:80H+地址码。其中,80H为命令码。
地址码如下:
当向DDRAM的00H~0FH(第1行)、40H~4FH(第2行)地址的任一处写数据时,LCD立即 显示出来,该区域称为可显示区域。
而当写入10H~27H或50H~67H地址处时,字符不会显示出来,该区域称为隐藏区域。如果要 显示写入到隐藏区域的字符,需要通过字符移位命令(命令5)将它们移入到可显示区域方可 正常显示。
-
命令9(RS=0,RW=1,看D7):读忙标志或地址。
D7——BF—忙标志。BF=1表示LCD忙,此时LCD不能接受命令或数据;BF=0表示LCD不忙,可以能接受命令或数据。
-
命令10(RS=1,RW=0,D7~D0):写数据。
0x00~0x07是自定义的8个字符;其他的是,字符与ASCII码一一对应。
-
命令11(RS=1,RW=1,D7~D0):读数据。
1.4、基础操作
①读状态
对LCD输入:RS=0,RW=1,E=1。
LCD输出:D7~D0=状态字,主要看D7是否=1,=1则表示LCD正忙。
②写命令
对LCD输入:RS=0,RW=0,D7~D0=命令,E=正脉冲(最开始=0,然后=1,最后=0)。
LCD输出:无输出。
③读数据
对LCD输入:RS=1,RW=1,E=1。
LCD输出:D7~D0=数据。
④写数据
对LCD输入:RS=1,RW=0,D7~D0=数据,E=正脉冲(最开始=0,然后=1,最后=0)。
LCD输出:无输出。
1.5、举例
参考程序:
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define out P2
sbit RS=P3^0; //位变量
sbit RW=P3^1; //位变量
sbit E=P3^2; //位变量
void lcd_initial(void); //LCD初始化函数
void check_busy(void); //检查忙标志函数
void write_command(uchar com); //写命令函数
void write_data(uchar dat); //写数据函数
void string(uchar ad,uchar *s);
void lcd_test(void);
void delay(uint); //延时函数
void main(void) //主程序
{
lcd_initial(); //调用对LCD初始化函数
while(1)
{ string(0x85,"Welcome"); //显示字符串
string(0xC2,"Harbin Institute"); //显示字符串
delay(100); //延时
write_command(0x01); //写入清屏命令
delay(100);
}
}
void delay(uint i) //延时子程序
{
uchar t;
while(i--)
{ for(t=0;t<250;t++);}
}
void check_busy(void) //检查忙标志函数
{
uchar dt;
do
{ dt=0xff;
E=0;
RS=0;
RW=1;
E=1;
dt=out;
}while(dt&0x80);
E=0;
}
void write_command(uchar com) //写命令函数
{
check_busy();
E=0;
RS=0;
RW=0;
out=com;
E=1;
_nop_();
E=0;
delay(1);
}
void write_data(uchar dat) //写数据函数
{
check_busy();
E=0;
RS=1;
RW=0;
out=dat;
E=1;
_nop_();
E=0;
delay(1);
}
void LCD_initial(void) //液晶显示器初始化函数
{
write_command(0x38); //写入命令0x38:8位两行显示,5*7点阵字符
write_command(0x0C); //写入命令0x0C:开整体显示,光标关,无黑块
write_command(0x06); //写入命令0x06:光标右移
write_command(0x01); //写入命令0x01:清屏
delay(1);
}
void string(uchar ad,uchar *s) //输出显示字符串的函数,uchar *s 指针(这是一个指针,指针指向的地址中存放的数据是uchar数据类型),所以是输入数组第0个元素,或者是字符串第0个字符。调用时,uchar &数组,或uchar数组,都是得到数组的第0个元素的地址指针。
{
write_command(ad);
while(*s>0)
{
write_data(*s++); //输出字符串,且指针增1
delay(100);
}
}