十一、LCD1602

实物图

LCD1602实物图

 

LCD1602电路连接图

LCD1602电路连接图

LCD1602主要技术参数

LCD1602主要技术参数

LCD1602 液晶引脚功能

LCD1602 液晶引脚功能
1602 内部 RAM 结构图

第一行的地址是 0x00H 到 0x27,第二行的地址从 0x40 到 0x67,其中第一行 0x00 到 0x0F是与液晶上第一行 16 个字符显示位置相对应的,第二行 0x40 到 0x4F 是与第二行 16 个字符显示位置相对应的。而每行都多出来一部分,是为了显示移动字幕设置的。

1602 液晶状态字

1602 液晶状态字

最高位表示了当前液晶是不是“忙”,如果这个位是 1 表示液晶正“忙”,禁止我们读写数据或者命令,如果是 0,则可以进行读写。而低 7 位就表示了当前数据地址指针的位置。

LCD1602的四个基本操作时序:

一、读状态:RS=L,R/W=H,E=H。

二、读数据:RS=H,R/W=H,E=H。

三、写指令:RS=L,R/W=L,D0~D7=指令码,E=高脉冲。读完了液晶状态,指令或者数据会通过P0口输出,为释放P0口,读完后应将E置位为0。

四、写数据:RS=H,R/W=L,D0~D7=数据,E=高脉冲。读完了液晶状态,指令或者数据会通过P0口输出,为释放P0口,读完后应将E置位为0。

 

指令介绍

1、显示模式设置。

写指令 0x38,设置 16x2 显示,5x7 点阵,8 位数据接口。这条指令对我们这个液晶来说是固定的,必须写 0x38,大家仔细看会发现我们的液晶实际上内部点阵是 5x8 的,还有一些1602 液晶还兼容串行通信,用 2 个 IO 口即可,但是速度慢,我们这个液晶就是固定的 0x38模式。

2、显示开/关以及光标设置指令

显示开/关以及光标设置指令

3、清屏指令

写入 0x01 表示显示清屏,包含了数据指针清零,所有的显示清零。写入0x02 则仅仅是数据指针清零,显示不清零。

4、RAM 地址设置指令

该指令码的最高位为 1,低 7 位为 RAM 的地址。通常在读写数据之前都要先设置好地址,然后再进行数据的读写操作。

简单实例:

代码:

#include <reg52.h>

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[] = "he bei ruan jian!";
	InitLcd1602();  //初始化液晶
	LcdShowStr(2,0,str);
	LcdShowStr(0,1,"heruan");
	while(1);
}

/*等待液晶准备好 */
void LcdWaitReady()
{
	unsigned char sta;
	P0 = 0xff;    
	LCD1602_RS = 0; //指令
	LCD1602_RW = 1; //读
	do{
	   LCD1602_E = 1; //高脉冲期间读取液晶状态
	   sta = P0;       
	   LCD1602_E = 0;

	}while(sta&0x80);  //sta高位为0表示不忙,跳出循环

}
/*向LCD写指令 */
void LcdWriteCmd(unsigned char cmd)
{
	LcdWaitReady();  //等待液晶准备好
	LCD1602_RS = 0;  //指令
	LCD1602_RW = 0;  //写入
	P0 = cmd;		 //P0赋予指令
	LCD1602_E = 1;	 //高脉冲写入液晶
	LCD1602_E = 0;
}
/*向LCD写数据 */
void LcdWriteDat(unsigned char dat)
{
	LcdWaitReady();  //等待液晶准备好
	LCD1602_RS = 1;  //数据
	LCD1602_RW = 0;  //写入
	P0 = dat;		 //P0赋予指令
	LCD1602_E = 1;	 //高脉冲写入液晶
	LCD1602_E = 0;
}
/* 设置显示 RAM 起始地址,(x,y)对应数学坐标第三象限 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
	unsigned char addr;
	if(y==0)   //如果LCD第0行
	{
		addr = 0x00 + x;	//第0行地址从0开始
	}
	else        //如果第一行
	{
		addr = 0x40 + x;	 //第一行地址从0x40开始
	}
	LcdWriteCmd(addr | 0x80); //设置 RAM 地址 最高位必须为1
}
/* 在液晶上显示字符串,str字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
	LcdSetCursor(x,y);
	while(*str != '\0')
	{
		LcdWriteDat(*str);
		str++;
	}
}

/* 初始化 1602 液晶 */
void InitLcd1602()
{
	LcdWriteCmd(0x38); //0011 1000    16*2 显示,5*7 点阵,8 位数据接口
	LcdWriteCmd(0x0C); //0000 1100 显示器开,光标关闭
	LcdWriteCmd(0x06); //0000 0110    文字不动,地址自动+1
	LcdWriteCmd(0x01); //0000 0001  清屏
}

 

调用关系:

模块化调用关系

 

LCD读写时序

读操作时序
写操作时序

 

简单实例:

mian()函数:

#include <reg52.h>
bit flag500ms = 0;
unsigned char T0RH = 0;
unsigned char T0RL = 0;

unsigned char code str1[] = "hebeiruanjia";
unsigned char code str2[] = "LCD1602 move";
void ConfigTimer0(unsigned int ms);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str,unsigned char len);

void main()
{
	unsigned char i;
	unsigned char index = 0;
	unsigned char pdata bufMove1[16+sizeof(str1)+16];
	unsigned char pdata bufMove2[16+sizeof(str2)+16];
	EA = 1;
	ConfigTimer0(10);
	InitLcd1602();
	for(i=0;i<16;i++)      //缓冲区前16位填充空格
	{
		bufMove1[i]=' ';
		bufMove2[i]=' ';
	}
	for(i=0;i<sizeof(str1)-1;i++)	  //将显示字符复制到缓冲区中间位置,	sizeof(str1)中包含了字符串末尾的\0
	{
		bufMove1[i+16]=str1[i];
		bufMove2[i+16]=str2[i];
	}
	for(i=(16+sizeof(str1)-1);i<sizeof(bufMove1);i++)
	{
		bufMove1[i] = ' ';
		bufMove2[i] = ' ';
	}
	while(1)
	{
		if(flag500ms)
		{
			flag500ms = 0;
			LcdShowStr(0,0,bufMove1+index,16);
			LcdShowStr(0,1,bufMove2+index,16);
			index++;
			if(index>=(16+sizeof(str1)-1))
			{
				index = 0;
			}
		}
	}
}

void ConfigTimer0(unsigned int ms)
{
	unsigned long tmp;
	tmp = 65536 - ms/1000/(11059200/12);
	T0RH = (unsigned char)(tmp>>8);
	T0RL = (unsigned char)tmp;
	TMOD &= 0xf0;
	TMOD |= 0x01;
	TH0 = T0RH;
	TL0 = T0RL;
	ET0 = 1;
	TR0 = 1;
}
void InterruptTimer0() interrupt 1
{
	static unsigned char tmr500ms = 0;
	TH0 = T0RH;
	TL0 = T0RL;
	tmr500ms++;
	if(tmr500ms >= 50)
	{
		tmr500ms = 0;
		flag500ms = 1;
	}
}

Lcd1602.c:

#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;

/*等待LCD1602准备好*/
void LcdWaitReady()
{
	unsigned char sta;
	LCD1602_DB = 0xff;			//先置高电平
	LCD1602_RS = 0;    //指令
	LCD1602_RW = 1;     //读
	do{
		//高脉冲
		LCD1602_E = 1;
		sta = LCD1602_DB;       //读取LCD1602当前是否忙
		LCD1602_E = 0;
	}while(sta & 0x80);  //当高位为0不忙时,才能跳出循环
}

/*向LCD1602写一字节指令*/
void LcdWriteCmd(unsigned char cmd)
{
	LcdWaitReady();   //等待LCD准备好
	LCD1602_RS = 0;  //指令
	LCD1602_RW = 0;   //写
	LCD1602_DB = cmd;		  //数据通过p0口写入LCD
	LCD1602_E = 1;    //高脉冲
	LCD1602_E = 0;
}

/*向LCD1602写一字节数据*/
void LcdWriteDat(unsigned char dat)
{
	LcdWaitReady();
	LCD1602_RS = 1;  //数据
	LCD1602_RW = 0;  //写
	LCD1602_DB = dat;        //将数据通过p0口送入LCD
	LCD1602_E = 1;	 //高脉冲
	LCD1602_E = 0;
}

/*设置RAM*/
void LcdSetCursor(unsigned char x,unsigned char y)
{
   unsigned char addr;
   if(y==0)
   {
   		addr = 0x00 + x;
   }
   else
   {
   		addr = 0x40 + x;
   }
   LcdWriteCmd(addr|0x80);
}

/*液晶显示字符串*/
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str,unsigned char len)
{
	LcdSetCursor(x,y);
	while(len--)
	{
		LcdWriteDat(*str++);
	}
}

/*液晶初始化*/
void InitLcd1602()
{
	LcdWriteCmd(0x38); //16*2 显示,5*7 点阵,8 位数据接口
	LcdWriteCmd(0x0c);	//显示器开,光标关闭
	LcdWriteCmd(0x06);	 //文字不动,地址自动+1
	LcdWriteCmd(0x01);	//清屏
}

 

 

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值