一、认识LCD
LCD == Liquid Crystal Display ==液晶显示器
LCD1602表示一种液晶屏,能同时显示2行16列,共32个字符,这个字符可以是字母,数字,符号等
LCD结构上主要由3部分组成:
液晶:液态晶体,液晶本身不发光,但他在通电的时候可以让光线透过去,不通电时光线透不过去;
光源:这个光源才是点亮LCD的关键;
偏光片:又上下两片,液晶就在上下偏光片之间,改变偏光片的角度就可以让光线在特定的地方透过
上下两片偏光片有点像两个石子交叉的百叶窗,自己去脑补一下。
二、LCD1602的管脚以及管脚功能
管脚序号 | 管脚符号 | 管脚说明 |
1 | VSS | 电源地, |
2 | VDD | 电源正极,是LCD1602驱动系统的电源 |
3 | VO | 液晶显示对比度调整管脚,接正电源是对比度最低,接地时对比度最高,但是对比度太高,就容易看到一些不该看到的东西,俗称“鬼影”,一般在这个脚通过电阻再接地。 |
4 | RS | Register Select的缩写,字面意思就是寄存器选择;当RS=1的时候,通讯的是数据;当RS=0的时候,通讯的是命令。 |
5 | R/W | 读,写选择,当R/W = 1的时候表示读LCD里面的数据,R/W = 0的时候表示往LCD里面写数据。 |
6 | E | 使能信号,当E=1的时候读取信息,当E由1变为0的时候,液晶模块开始执行命令;要配合控制时序来用。 |
7 | D0 | 数据第0位,D0--D7是双向的数据线,对LCD模块进行读写。 |
8 | D1 | 数据第1位 |
9 | D2 | 数据第2位 |
10 | D3 | 数据第3位 |
11 | D4 | 数据第4位 |
12 | D5 | 数据第5位 |
13 | D6 | 数据第6位 |
14 | D7 | 数据第7位 |
15 | BLA | 背光源正极,可以理解为那个背光LED的正极电源,可以直接接VDD |
16 | BLK | 背光源负极,可以理解为那个背光LED的负极电源,可以直接接VSS |
三、LCD1602 的RAM地址映射
LCD1602能同时显示2行16列,一共32个位置,每个位置都对应着一个地址,每个地址里面可以促一个字节的字符,需要在哪个位置显示某种字符,就在他对应的地址上写入某种字符。
下图就是这32个显示位置所对应的地址,这个地址也就是DDRAM地址;

其实LCD1602的DDRAM一共有80个地址,依然是两行,每行40个地址,但是LCD1602一行只能同时显示16个地址的数据,剩下的24个在后面隐藏着。怎么办,只能用光标移动的方法把隐藏的部分显示出来。

四、LCD1602的显示设置
比如你想在第1行,第3列的位置显示个字符A,该怎么处理?
首先确定位置,第1行第3列的地址是02,转换为2进制就是0000 0010,但是LCD1602有自己的规矩,就是写地址的时候,最高位必须是1,也就是说写进LCD的地址应该为1000 0010。
然后确定字符,LCD1602模块里面有个字符产生器,简称CGROM(Character Generator ROM)里面存着一些常用的字模,你只需要根据地址来查询就可以了,比如字符A的地址就是0x41。
五、LCD1602的命令列表

六、单片机控制LCD1602电路

七、LCD1602驱动代码编写
1、检查BUSY位,
无论是写数据、还是写命令、还是读数据、都需要检查LCD1602的忙碌状态,怎么检测?
首先检查busy是读LCD里面的东西,那R/W就应该为高电平;
然后检测状态应该是命令,RS就应该为低电平;
当都准备好了,把使能为从低电平变为高电平,在高电平读取的数据才是有效的;
现在MCU开始检查BUSY引脚,也就是LCD1602的DB7脚,对应单片机的P07脚(看你电路图是连的那个脚);
如果DB7是高电平,就表示LCD现在处于忙碌状态,你得等着;
一直到DB7位低电平,就是不忙的时候,再把使能为拉低(没事的时候,或者要让LCD执行某个命令的时候都要把使能位拉低)
//检测LCD是否在忙碌,忙碌就等着
void waitBusy(void)
{
LCD_PIN = 0xFF; //先把液晶的所有数据引脚都拉高
do
{
LCD_EN = 0; //准备阶段或者闲的时候就把EN拉低
LCD_RS = 0; //RS拉低,表示命令
LCD_RW =1; //RW拉高,表示读
LCD_EN = 1; //把EN拉高,开始准备读BUSY位的电平
}while(LCD_BUSY == 1); //BUSY位为高电平的时候,表示忙,那就一直等着
LCD_EN = 0; //如果BUSY位不是高电平,就能运行到这里了,把使能为拉低
}
2、向LCD1602写命令
首先还是要检查LCD1602是否在忙着;
不忙的时候就可以开始做哪几件事了,设置EN、RS、RW的电平,根据是读还是写,是数据还是命令
//写入命令
void lcdWriteCmd(unsigned char cmd)
{
waitBusy();
LCD_EN = 0; //使能拉低
LCD_RS = 0; //命令
LCD_RW = 0; //写
LCD_PIN = cmd; //把命令写在液晶的数据口上,
LCD_EN = 1; //数据准备好了,相当于箭上弦了
LCD_EN = 0; //使能拉低,相当于发射了
}
3、向LCD1602写数据
跟写命令差不多,就是把那个RS位设为高电平
//向LCD1602写数据
void lcdWriteData(unsigned char dat)
{
waitBusy(); //检查LCD1602是否在忙
LCD_EN = 0; //使能拉低
LCD_RS = 1; //命令
LCD_RW = 0; //写
LCD_PIN = dat; //把命令写在液晶的数据口上(DB0--DB7)
LCD_EN = 1; //命令准备好了,相当于箭上弦了
LCD_EN = 0; //使能拉低,相当于发射了
}
4、LCD1602清屏
这是一条命令,命令码是0x01,用写命令函数就可以实现清屏
lcdWriteCmd(0x01)
5、LCD1602功能设置
这个功能设置,就是设置用几位数据接口,我们常用8位数据接口(DB0--DB7);
还设置用几行来显示,LCD1602有两行,那就都用上吧;
还设置点阵是几个点的,我这边用的是5*7点阵;
不同的设置就对应着不同的功能码。

比如我们设置为八位数据接口、两行显示、5*7点阵,那么功能码就是0x38,用写命令函数类似实现
lcdWriteCmd(0x38);
6、LCD1602显示开关设置

7、LCD1602光标画面位移

8、LCD1602输入方式设置

10、写多个字节的数据
先把首个字节的地址发过去,设置输入方式,然后把数据内容发过去
void lcdWriteString(unsigned char startAddr, unsigned char* p)
{
lcdWriteCmd(startAddr);
while(*p != '\0')
{
lcdWriteData(*p++);
}
}
LCD1602的指令都理解之后,就是怎么应用了,自己多尝试吧,单独的LCD显示意义不大,一般用来显示项目中的某个或某些参数,后续慢慢展开。。。。。。