LCD1602液晶

文章目录

      • 1. 1602引脚与原理图
      • 2. 1602读写时序
        • (1)、读状态:
        • (2)、读数据:
        • (3)、写指令:
        • (4)、写数据:
      • 3. 1602液晶的指令
        • (1)、显示模式设置:
        • (2)、显示开/关以及光标设置指令:
        • (3)、清屏指令:
        • (4)、RAM地址设置指令:
      • 4. 1602代码

1. 1602引脚与原理图

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

2. 1602读写时序

1602液晶内部带了80个字节的显示RAM,用来储存发送的数据。
LCD1602液晶_第3张图片
第一行的地址是 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
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);//清屏
}

你可能感兴趣的:(制作实时时钟,51单片机)