LCD1602液晶

1602液晶

1.1602引脚与原理图

1602液晶,从名字就可以看出它的显示容量,就是可以显示2行,每行 16个字符的液晶。一共16个引脚,每个引脚功能如下:
这里写图片描述这里写图片描述
使用液晶时,按照以下原理图与单片机进行连接:
原理图
1、2、15、16引脚不再说。3引脚VL用来调整显示的黑点和不显示的黑点之间的对比度,可直接使用一个1~1.5KΩ的下拉电阻。4~14引脚如上图连接单片对应的IO端口。

2.1602读写时序

1602液晶内部带了80个字节的显示RAM,用来储存发送的数据。
1602内部RAM结构图
第一行的地址是 0x00H 到 0x27,第二行的地址从 0x40 到 0x67,其中第一行 0x00 到 0x0F是与液晶上第一行 16 个字符显示位置相对应的,第二行 0x40 到 0x4F 是与第二行 16 个字符显示位置相对应的。而每行都多出来一部分,是为了显示移动字幕设置的。

液晶有一个状态字字节,共8位,最高位(第7位)是读写操作时能,1为禁止、0为允许。

要写1602的程序,先把要用到的总线接口做统一声明:

#define LCD1602_DB P0
sbit LCD1602_RS = P2^7;
sbit LCD1602_RW = P2^6;
sbit LCD1602_E = P2^5;

(1)、读状态:RS=L,R/W=H,E=H。这是个很简单的逻辑,我们直接写

LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
LCD1602_E = 1;
sta = LCD1602_DB;

这样就把当前液晶的状态字读到了 sta 这个变量中,我们可以通过判断 sta 最高位的值来了解当前液晶是否处于“忙”状态,也可以得知当前数据的指针位置。其次我们读完了状态,通常要把这个引脚拉低来释放P0总线,这里我们用了一个 do…while 循环语句来实现。

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=L,E=H。
(3)、写指令:RS=L,R/W=L,D0~D7=指令码,E=高脉冲。
(4)、写数据:RS=H,R/W=L,D0~D7=数据,E=高脉冲。
*这里的高脉冲是指:E 使能引脚先从低拉高,再从高拉低,形成一个高脉冲。

3.1602液晶的指令

(1)、显示模式设置:
写指令0x38,设置16X2显示,5X7点阵,8位数据接口。

(2)、显示开/关以及光标设置指令:
这里一共有两条指令。第一条指令,一个字节中8位,其中高5位是固定的0b00001,低3位分别用DCB从高到低表示,D=1表示开显示,D=0表示管显示;C=1表示显示光标,C=0表示不显示光标;B=1表示光标闪烁,B=0表示光标不闪烁。

(3)、清屏指令:
写入0x01表示显示清屏,包括数据指针清零、所有显示清零;
写入0x02仅仅指针清零,显示不清零。

(4)、RAM地址设置指令:
最高位为1,低七位为RAM的地址。

4.1602代码

#include<reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;

#define Lcd1602_DB P0
sbit Lcd1602_RS = P2^7;
sbit Lcd1602_RW = P2^6;
sbit Lcd1602_E = P2^5;

/* 等待液晶准备好 */
void LcdWriteReady()
{
    u8 sta;

    Lcd1602_DB = 0xFF;//P0口拉高
    Lcd1602_RS = 0;
    Lcd1602_RW = 1;
    do{
        Lcd1602_E = 1;
        sta = Lcd1602_DB; //读取状态字
        Lcd1602_E = 0;
    }while(sta&0x80); //状态位最高位bit7=1表示液晶正忙,重复检测知道bit7=0
}
/* 向LCD1602液晶写入一字节命令,cmd为待写入的值  */
void LcdWriteCmd(u8 cmd)
{
    LcdWriteReady();
    Lcd1602_RS = 0;
    Lcd1602_RW = 0;
    Lcd1602_DB = cmd;
    Lcd1602_E = 1;
    Lcd1602_E = 0;
}
/*向1602液晶写入一字节数据,dat为待写入数据值 */
void LcdWriteDat(u8 dat)
{
    LcdWriteReady();
    Lcd1602_RS = 1;
    Lcd1602_RW = 0;
    Lcd1602_DB = dat;
    Lcd1602_E = 1;
    Lcd1602_E = 0;
}
/* 设置显示RAM起始地址,亦即光标设置,(x,y)为对应屏幕上的字符坐标 */
void LcdSetCursor(u8 x,u8 y)
{
    u8 addr;

    if(y == 0)
        addr = 0x00 + x;
    else 
        addr = 0x40 + x;
    LcdWriteCmd(addr | 0x80);
}
/* 在液晶上显示字符串 */
void LcdShowStr(u8 x,u8 y,u8 *str, u8 len)
{
    LcdSetCursor(x,y);
    while(len--)
    {
        LcdWriteDat(*str++);
    }
}
/* 初始化1602 */
void Init1602()
{
    LcdWriteCmd(0x38);
    LcdWriteCmd(0x0C);//0000 1100 = 0x0C  显示器开 光标关闭
    LcdWriteCmd(0x06);//0000 0100 = 0x06 文字不动,地址自动+1
    LcdWriteCmd(0x01);//清屏
}

猜你喜欢

转载自blog.csdn.net/qq_37369201/article/details/81903894