1.引脚功能介绍
1602 液晶就是可以显示 2 行,每行 16 个字符的液晶,一共 16 个引脚,每个引脚的功能,我们都可以在它的数据手册上获得。
液晶的电源 1 脚 2 脚、背光电源 15 脚 16 脚正常接即可。
3 脚叫做液晶显示偏压信号,调节电压来调节显示的对比度。
4 脚,当这个引脚是 H高电平的时候,是数据,当这个引脚是 L低电平的时候,是命令。
5 脚和 4 脚用法类似,功能是读写选择端,液晶本身内部有 RAM。这个引脚我们接到了 ADDR1 上,通过跳线帽和 P1.1 连接在一起。
6 脚是使能信号,这个引脚我们通过跳线帽接到了 ENLCD 上,这个位置的跳线是为了和另外一个 12864 液晶的切换使用而设计的。
7 到 14 引脚就是 8 个数据引脚了,我们就是通过这 8 个引脚读写数据和命令的。
液晶有一个状态字字节,我们通过读取这个状态字的内容,就可以知道 1602 液晶的一
些内部情况。
2.基本操作时序
1602 的基本操作时序,一共有 4 个
我们这里要做 1602 液晶的程序,因此先把用到的总线接口做一个统一声明:
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;
1、读状态:RS=L,R/W=H,E=H。
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0; //读完撤销使能,防止液晶输出数据干扰 P0 总线
} while (sta & 0x80);
//bit7 等于 1 表示液晶正忙,重复检测直到其等于 0 为止
2、读数据:RS=H,R/W=H,E=H。
3、写指令:RS=L,R/W=L,D0~D7=指令码,E=高脉冲。
4、写数据:RS=H,R/W=L,D0~D7=数据,E=高脉冲。
3. 1602 液晶的指令介绍
1、显示模式设置
写指令 0x38,设置 16x2 显示,5x7 点阵,8 位数据接口。
2、显示开/关以及光标设置指令。
0b0000_ _ _ _
第一条指令,一个字节中 8 位,其中高 5 位是固定的 0b00001,低 3位我们分别用 DCB 从高到低表示,D=1/0表开/关显示;C控制显示光标;B控制光标闪烁。
第二条指令,高 6 位是固定的 0b000001,低 2 位我们分别用 NS 从高到低表示,其中N=1 表示读或者写一个字符后,指针自动加 1,光标自动加 1,N=0 表示减;S=1 表示写一个字符后,整屏显示左移(N=1)或右移(N=0),以达到光标不移动而屏幕移动的效果,而 S=0 则不移动。
3、清屏指令。
固定的,写入 0x01 表示显示清屏,其中包含了数据指针清零,所有的显示清零。写入
0x02 则仅仅是数据指针清零,显示不清零。
4、RAM 地址设置指令
该指令码的最高位为 1,低 7 位为 RAM 的地址,RAM 地址与液晶上字符的关系如上图
12-2 所示。通常,我们在读写数据之前都要先设置好地址,然后再进行数据的读写操作。
4.实例
#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;
void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void main()
{
unsigned char str[] = "Kingst Studio";
InitLcd1602();
LcdShowStr(2, 0, str);
LcdShowStr(0, 1, "Welcome to KST51");
while (1);
}
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重复检测直到其等于 0 为止
}
/* 向 LCD1602 液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向 LCD1602 液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 设置显示 RAM 起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示 RAM 的地址
addr = 0x00 + x; //第一行字符地址从 0x00 起始
else
addr = 0x40 + x; //第二行字符地址从 0x40 起始
LcdWriteCmd(addr | 0x80); //设置 RAM 地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //设置起始地址
while (*str != '\0') //连续写入字符串数据,直到检测到结束符
{
LcdWriteDat(*str++); //先取 str 指向的数据,然后 str 自加 1
} }
/* 初始化 1602 液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2 显示,5*7 点阵,8 位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}
液晶的左上角的坐标是 x=0,y=0,往右边是 x+偏移,下边是 y+偏移