1.LCD1602的认识

  • 液晶显示屏简称液晶、LCD。各种型号的液晶通常是按显示字符的行数或液晶点阵的行、列进行命名的。1602的意思就是每一行显示16个字符,共可以显示2行,常见的液晶还有0801、0802、1601等,这类液晶是字符型液晶,只能显示ASCII码字符。而LCD12864属于图形型液晶,由128*64个像素点构成,可以显示各种图形包括汉字。
  • LCD1602可显示2行ASCII码字符,每行包括16个5*10点阵(像素),有16个引脚,其实物图如下所示:
    在这里插入图片描述

2.LCD1602的引脚及其功能

在这里插入图片描述

3.LCD模块的内部结构

  • LCD1602模块的内部结构分为三部分:LCD控制器、LCD驱动器、LCD显示器
    在这里插入图片描述
  • LCD控制器和LCD驱动器一般由专用集成电路实现,大部分是HD44780或兼容芯片,HD44780是低功耗CMOS大规模点阵LCD控制器,它包含有下面的电路,他们的功能如下表:
    在这里插入图片描述
  • LCD1602显示字符的过程
    HD447780内部有80*8bit的DDRAM缓冲区,其显示位置与DDRAM地址的对应关系如下表:
    在这里插入图片描述
  • 一行有40个地址,可以存入40个字符数据,但每行最多只能显示其中的16个。可以用多余的地址存入其他数据,实现显示的快速切换。注意:编程时需要将表中的地址加上80H才能正确显示,如果要在第一行显示“R”,应该将“R”的ASCII码(0x52)写到地址0x80+ox03即0x83处。

4.LCD1602的工作时序

  • LCD1602的读操作时序
    在这里插入图片描述
    LCD1602读操作编程流程:
  • 给RS加电平(1为数据,0为指令)给R/W加高电平(读模式)
  • E = 1(使能,高电平有效),延时
  • LCD1602送数据到DB0~DB7
  • E = 0
  • 读结束
  • LCD1602的写操作时序
    在这里插入图片描述
    LCD1602的写操作编程流程:
  • 给RS加电平(1为数据,0为指令),R/W = 0(为写)
  • 单片机送数据到DB0~DB7
  • E = 1 (拉高使能线)
  • E = 0,写入生效
  • 改变RS、R/W的状态,为下次操作做准备

5.LCD1602的指令说明

在这里插入图片描述
LCD1602液晶模块共有11条指令,下面根据上面的表格做出说明:

  • 指令一:清除显示,指令码为0x01,其实质是将DDRAM全部写入空格的ASCII码0x20,地址计数器AC清零。该过程需要时间较长。
  • 指令二:光标复位,光标返回00H(复位到屏的左上方),地址计数器AC清零,DDRAM内容不变
  • 指令三:光标和显示模式设置。N——设置光标的移动方向,N=1时,读或写一个字符后,地址加1,光标加1;N=0时,地址减1,光标减1.S——用于设置整屏字符是否左移或右移,当S= 1且N = 1时,写一个字符整平左移,当S= 1且N = 0时,写一个字符时整屏显示右移,若S = 0,则整屏字符移动无效,因此常用的光标右移指令为0x06
  • 指令4:显示开/关控制D——控制整体显示的开与关,高电平显示,低电平关显示;C——控制光标的开关,高电平表示有光标,低电平无光标;B——控制光标是否杉树,高电平闪烁,低电平不闪烁常用的开显示关光标的指令为0x0c
  • 指令5:命令光标或字符移动。S/C控制光标或字符,R/L控制左右
    (S/C)(R/L) = (0)(0),文字不动,光标左移一格,AC减1
    (S/C)(R/L) = (0)(1),文字不动,光标右移一格,AC加1
    (S/C)(R/L) = (1)(0),文字全部右移一格,光标不动
    (S/C)(R/L) = (1)(1),文字全部左移一格,光标不动
  • 指令六:功能设置命令DL——高电平为8位数据总线,低电平为4位数据总线;N——低电平单行显示,高电平双行显示;F——低电平显示57的点阵字符,高电平显示510的点阵字符,常用的两行、八位数据总线、5*7的点阵指令为0x38
  • 指令七:指令为0x40+add(当D5-D0全为0时,D7~D0为0x40)该指令用于设置自定义字符的CGRAM地址。ADD前三位用于选择字符,后三位用于选择字符的8位字模数据
  • 指令八:指令为0x80+add,用于设置下一个要存入数据的DDRAM地址。add的范围是0x00~0x27,对应第一行,0x40-0x67对应显示第二行,每行可输入40个字符,默认只能显示前16个,可以通过指令3的字符移动指令来显示其他内容
  • 指令九:读忙信号和光标地址。BF:忙标志位,高电平表示忙,此时模块不能就收命令或数据,如果为低电平表示闲,可以操作
  • 指令10:写数据
  • 指令11:读数据

6.LCD1602的编程实例

  • 这是我的液晶电路原理图,主要看一下与哪个引脚相连。
    在这里插入图片描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
/*******引脚定义*******/

sbit RS = P1^0;
sbit RW = P1^1;
sbit E = P1^2;
#define data1602 P0
sbit BF = data1602^7; //BF表示data1602的最高位,判断是忙还是闲
/*******延时函数*******/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*******忙检测函数*******/
bit LCD_busy()
{
bit busy;
P0 = 0xff;//防止干扰
RS = 0; //命令模式
RW = 1; //读模式
E = 1;
busy = BF;//将忙标志位的数值赋给busy
E = 0;
return busy;
}
/*******写命令函数*******/
void LCD_write_cmd(uchar cmd)//cmd为需要写的命令
{
while(LCD_busy());//只有当LCD_busy()为0(闲)时才跳出循环
RS = 0; //命令模式
RW = 0; //写模式
data1602 = cmd; //将命令内容的十六进制送到P0端口
E = 1;
E = 0; //使能端,高电平有效,使命令送到LCD1602的DB0~DB7
}
/*******写数据函数*******/
void LCD_write_data(uchar dat)//dat为需要写的数据
{
while(LCD_busy());//只有当LCD_busy()为0(闲)时才跳出循环
RS = 1; //数据模式
RW = 0; //写模式
data1602 = dat; //将数据内容的十六进制送到P0端口
E = 1;
E = 0; //使能端,高电平有效,使命令送到LCD1602的DB0~DB7
}
/*******LCD初始化函数*******/
void LCD_init()
{
LCD_write_cmd(0x38); //将设置“两行、八位数据、5*7的点阵”命令写入LCD的控制器
LCD_write_cmd(0x0c); //开显示关光标
LCD_write_cmd(0x06); //光标右移指令
LCD_write_cmd(0x01); //清除显示
}
/*******LCD写显示地址函数*******/
void LCD_write_address(uchar x,uchar y)
{
x&=0x0f; //列地址限制在0~15之间
y&=0x01; //行地址限制在0~1
if(y==0)
LCD_write_cmd(x|0x80);//数据指针=80+地址变量,写入列地址
else
LCD_write_cmd((x+0x40)|0x80); //如果是第二行,将列地址写入
}
/*******LCD显示函数*******/
void LCD_display(uchar x,uchar y,uchar buf) //x:列 y:行,buf:显示的字符
{
LCD_write_address(x,y);//先将地址写入
LCD_write_data(buf); //再写入要显示的数据
}
/*******main函数*******/
void main()
{
LCD_init();
LCD_display(2,0,'H');
LCD_display(3,0,'e');
LCD_display(4,0,'l');
LCD_display(5,0,'l');
LCD_display(6,0,'o');
LCD_display(8,0,'W');
LCD_display(9,0,'o');
LCD_display(10,0,'r');
LCD_display(11,0,'l');
LCD_display(12,0,'d');

LCD_display(8,1,'W');
LCD_display(9,1,'D');
while(1);
}

效果如下:
在这里插入图片描述