LCD1602液晶使用介绍–(完整版)

LCD1602液晶使用介绍–(完整版)lcd1602+c51介绍文章目录LCD1602介绍1602引脚信号说明控制器接口介绍1、基本操作时许2、状态字说明3、指令说明RAM地址映射控制时序图代码实现写入命令写数据试验例程CGRAM自定义字模(简易汉字显示)LCD1602介绍LCD1602液晶在实际的产品运用中也是比较多产品,应为前一段时间也正好用到了所以惊天就对LCD1602液晶做一个总结,方便以后阅读同时也希望能够帮住到需要的人,总结的可能存在错误欢迎指出!所谓的1602是指显示的时候,有2行内容每行有16个字符。其实这类字符型产

大家好,又见面了,我是你们的朋友全栈君。

lcd1602 +c51 介绍

LCD1602介绍

LCD1602液晶在实际的产品运用中也是比较多产品,应为前一段时间也正好用到了,所以今天就对LCD1602液晶做一个总结,方便以后阅读同时也希望能够帮住到需要的人,总结的可能存在错误欢迎指出!

所谓的1602是指显示的时候,有2行内容每行有16个字符。其实这类字符型产品都可以这样解读比如:lcd12864就是有128行64列。目前市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理大多相同。因此基于HD44780写的液晶控制程序可以很方便适用于市面上大多数字符型液晶产品。
在这里插入图片描述

1602引脚信号说明

字符型LCD1602通常分为14条引脚和16引脚两种,16引脚多出来的是背光电源线VCC(15引脚)和地线(16引脚),其控制原理与14引脚LCD完全一样,引脚定义如下表:

引脚号 引脚名 电平 输入/输出 作用
1 Vss 电源地
2 Vcc 电源(+5V)
3 Vee 对比调整电压
4 RS 0/1 输入 0=输入指令;1=输出数据
5 R/W 0/1 输入 0=向LCD写入指令或数据; 1=从LCD读取信息
6 E 1,1->0 输入 使能信号,1时读取信息,1->0(下降沿)执行指令
7 DB0 0/1 输入/输出 数据总线line0(最低位)
8 DB1 0/1 输入/输出 数据总线line1
9 DB2 0/1 输入/输出 数据总线line2
10 DB3 0/1 输入/输出 数据总线line3
11 DB4 0/1 输入/输出 数据总线line4
12 DB5 0/1 输入/输出 数据总线line5
13 DB6 0/1 输入/输出 数据总线line6
14 DB7 0/1 输入/输出 数据总线line7
15 A +Vcc LCD背光灯源正极
16 K 接地 LCD背光灯源负极

控制器接口介绍

1、基本操作时许

  • 1.1读状态:输入:RS=L,RW=H,E=H
    —-输出:D0~D7=状态字
  • 1.2写指令:输入:RS=L,RW=L,D0~D7=指令码
    —-输出:无
  • 1.3读数据:输入:RS=H,RW=H,E=H
    —-输出:D0~D7=数据
  • 1.4写数据:输入:RS=H,RW=L,D0~D7=数据,E=高脉冲
    —-输出:无

2、状态字说明

STA7 D7 STA6 D6 STA5 D5 STA4 D4 STA3 D3 STA2 D2 STA1 D1 STA0 D0

STA0-6 当前数据地址指针的数值
STA7 读写操作使能 1:禁止 0:允许

对控制器每次进行读写操作前,都必须进行读写检测,确保STA7为0

3、指令说明

初始化设置
显示模式设置

在这里插入图片描述
显示开/关光标设置
在这里插入图片描述
在这里插入图片描述
数据控制
控制器内部没有一个数据地址指针,可以通过他们来访问内部的全部80字节RAM。
其他设置

指令码 功能
01H 显示清屏:1.数据指针清零 2.所有显示清零
02H 显示回车:1.数据指针清零

初始化过程:

延时
写指令38H
延时
写指令38H
延时
写指令38H
(每次写指令、读/写数据操作之前均需检测信号)
写指令38H:显示模式设置
写指令08H:显示关闭
写指令01H:显示清屏
写指令06H:显示光标移动设置
写指令0CH:显示开及光标设置

代码:

void LcdInit(){ 
   //LCD初始化程序
Delay1ms(15);
LcdWriteCom(0x38);
Delay1ms(5);
LcdWriteCom(0x38);
Delay1ms(5);
LcdWriteCom(0x38);//设置显示模式
LcdWriteCom(0x0C);//开显示不显示光标,光标不闪烁
LcdWriteCom(0x06);//写一个数据,指针加1
LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点。
}

RAM地址映射

HD44780内置DDRAM、CGROM和CGRAM。
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,地址和屏幕的对应关系如下:

显示位置 1 2 3 4 5 6 7 … … 40
第一行 00H 01H 02H 03H 04H 05H 06H … … 27H
第二行 40H 41H 42H 43H 44H 45H 46H … … 67H

也就是说想要在LCD1602屏幕上的第一行第一个位置显示一个“A”,就要向DDRAM的00H地址写“A”字的代码就OK了,但具体的写入是要按照LCD模块的指令格式来进行的。
但是我们发现每一行有40个地址,而我们们每行只能显示16个字符,其实际多的位置可以实现字符的移动,我们在看大佬作品的时候可能会见到有的字符是从左面移过来,他的实现形式就用到了着些多的地址。将数据先写到未显示的地址然后使用指令进行左移就可以了。
那么1602显示的地址又是什么呐?下图就是DDRAM地址与现实位置的对应关系。
LCD1602液晶使用介绍--(完整版)

控制时序图

1、读操作时序图:
在这里插入图片描述
2、写操作时序图:
在这里插入图片描述
3、时序参数
在这里插入图片描述

代码实现

LCDE = E //使能信号

写入命令

RS=L,RW=L,D0~D7=指令码,E=高脉冲。

void LcdWriteCom(unsigned char com){ 
   //写入命令
	RS = 0;
	RW = 0;
	GPIO_LCD=com;
	Delay1ms(10);
	LCDE = 1; //给一个高脉冲
	Delay1ms(10);
	LCDE = 0;
}

写数据

RS=H,RW=L,D0~D7=数据,E=高脉冲。

void LcdWriteData(unsigned char dat){ 
   //写入数据
	RS = 1;
	RW = 0;
	GPIO_LCD=dat;
	Delay1ms(10);
	LCDE = 1; //给一个高脉冲
	Delay1ms(10);
	LCDE = 0;

试验例程

main.c文件

#include<reg52.h>
#include"lcd.h"

unsigned char CnCh[] = "012345678912345";
unsigned char CnCh1[] = "ABCDEFGIJKLMNOP";

unsigned char i,a =0,j,n;
unsigned char code Data_1[]=" I Love You ";  // 第一行显示,共十六个字符
unsigned char code Data_2[]="Good Good Study,Day Day Up !";  // 第二行显示,共28个字符

unsigned char i;
void main(){ 
   
	lcd_Init();
	lcd_write_com(0x80);
	for(i = 0;i<16;i++){ 
   
		lcd_read_busy();
		lcd_write_dat(CnCh[i]);
	}
	lcd_write_com(0xc0);
	for(i = 0;i<16;i++){ 
   
		lcd_read_busy();
		lcd_write_dat(CnCh1[i]);
	}
	while(1);
}

void zimo(){ 
   
	unsigned char code Data_0[]={ 
   0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02, 0x02};  // 汉字 年 的字模
	unsigned char code Data_1[]={ 
   0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x0b, 0x11};  // 汉字 月 的字模 
	unsigned char code Data_2[]={ 
   0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00};  // 汉字 日 的字模

	lcd_Init();  // LCD1602 初始化
	lcd_write_com(0x40);  // 0100 0000; 指令 0x40 向 CGRAM 地址0 写入自定义数据
	for(i=0; i<8; i++){ 
   
		lcd_write_dat(Data_0[i]);  // 写入自定义字符字模
	}

	lcd_write_com(0x48);  // 0100 1000; 指令 0x48 向 CGRAM 地址1 写入自定义数据
	for(i=0; i<8; i++){ 
   
		lcd_write_dat(Data_1[i]);  // 写入自定义字符字模
	}

	lcd_write_com(0x50);  // 0101 0000; 指令 0x50 向 CGRAM 地址2 写入自定义数据
	for(i=0; i<8; i++){ 
   
		lcd_write_dat(Data_2[i]);  // 写入自定义字符字模
	}
	lcd_write_com(0x00 + 0x80);  // 在第一行第一列显示 第一个字符
	lcd_write_dat(0);

	lcd_write_com(0x02 + 0x80);  // 在第一行第三列显示 第二个字符
	lcd_write_dat(1);

	lcd_write_com(0x04 + 0x80);  // 在第一行第五列显示 第一个字符
	lcd_write_dat(2);
	while(1);
	/* //分割线******************************************************************* unsigned char table[]={0x15,0x0A,0x15,0x0A,0x15,0x0A,0x15,0x0A}; lcd_Init(); lcd_write_com(0x40); for(i=0;i<8;i++){ lcd_write_dat(table[i]); } lcd_write_com(0x80); lcd_write_dat(0x00); while(1); */
}

//单行移动显示**************************************************************
void dh(){ 
   
	lcd_Init();

	lcd_write_com(0x80);  // 第一行第一列地址
	for(i=0; i<16; i++){ 
        
		lcd_write_dat(Data_1[i]);  // 显示第一行
	}
	while(1){ 
   
		lcd_read_busy();
		lcd_write_com(0xc0);  // 第二行第一列地址
		for(j=n; j<28+n; j++){ 
        
			lcd_write_dat(Data_2[j]);  // 显示第二行
		}
		n++;

		if(n >= (28-15)){ 
     // 当数据移动到最后时,n 重置 0,停顿 500 ms,重新开始移动显示
			n = 0;
			delay1ms(50);
		}
		delay1ms(20);  // 控制移动速度
	}
}

lcd.c文件

#include"lcd.h"

void delay1ms(unsigned char d)   //误差 0us
{ 
   
    unsigned char a,b,c;
    for(c=0;c<d;c++)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}

void lcd_Init(){ 
   
	lcd_write_com(0x38);
	delay1ms(1);
	lcd_write_com(0x38);	//设置显示模式
	lcd_write_com(0x0c);	//开显示不显示贯标
	lcd_write_com(0x06);	//指针自动加一
	lcd_write_com(0x01);	//清屏
	lcd_write_com(0x80);	//设置数据指针起点
}

void lcd_write_com(unsigned char com){ 
   
	RS = 0;
	RW = 0;
	E = 0;
	
	P0 = com;
	delay1ms(10);
	E = 1;
	delay1ms(10);
	E = 0;
}

void lcd_write_dat(unsigned char dat){ 
   
	RS = 1;
	RW = 0;
	E = 0;
	
	P0 = dat;
	delay1ms(10);
	E = 1;
	delay1ms(10);
	E = 0; 
}


void lcd_xy(unsigned char x,unsigned char y){ 
   
	lcd_write_com(x+y);
}

void lcd_read_busy(){ 
   
	unsigned char he,a;
	RS = 0;
	RW = 1;
	E = 1;
	he = P0;
	while(1){ 
   
		he = P0;
		E = 0;
		if(!(he&0x80))//当he&0x80为0时跳出循环,表明不忙。
			break;
		E = 1;
		a++;
		if(a>=10)
			break;
	}
}

lcd.h文件

#ifndef __LCD_H_
#define __LCD_H_
#include<reg52.h>

sbit RS = P2^0;
sbit RW = P2^1;
sbit E = P2^2;

void delay1ms(unsigned char d);		//延时函数
void lcd_Init();		//初始化
void lcd_write_com(unsigned char com);		//写指令
void lcd_write_dat(unsigned char dat);		//写数据
void lcd_xy(unsigned char x,unsigned char y);  //写位置
void lcd_read_busy();		//检测标志位
#endif

CGRAM自定义字模(简易汉字显示)

这里说明一下lcd1602液晶是不能显示汉字的,因为它的显示原理是由若干个5X7或者5X11的点阵字符位组成的,又因为汉字较为复杂,所以1602的主要作用就是显示字母、数字、符号的。但是真的不能显示汉字吗?也并非绝对不能。接就是下面要说的CGRAM自定义字模。

要显示我们自定义的字符,就要用到LCD中的CGRAM存储器(character generate RAM),而我们之前用的显示自带的字符用到的是DDRAM,两个是不同的。看手册我们知道,CGRAM的容量是64个字节,而一个字符是8个字节,所以一共能显示8个自定义的字符。内部常用字符的显示是从0x20开始的,0x00 ~ 0x0F是专门留给自定义字符显示用的,0x00-0x07和0x08~0x0F显示的内容是一样的,也就是说0x00=0x08,0x01=0x09,以此类推。CGRAM共128个位,地址是0x40-0x7F,128/8=16正好对应的是0x00-0x0F共16个,刚才说了,0x00与0x08对应,0x01与0x09对应,共16个,这并不矛盾!说了这么多,那么怎样显示一个自定义字符呢?
首先我们要清楚LCD1602显示字符的点阵大小,眼力好的可以看出来,LCD1602一个显示字符的位置是58的点阵,也就是说它所能显示的点阵图形的大小是58的!要显示一个自定义的字符,首先我们要知道所显示自定义字符的点阵数据,也就是在一个58的点阵上那个点是黑的(将该点点黑,就是高电平—-1),哪个点是白的(该点不显示,为低电平—-0),但是我们送入到LCD中的是ASCII码,它是8位的数据,而一个显示字符的点阵大小只是58的,显然不够,显示的办法是8*8点阵的前三列不用,也就是不显示,我们只用后面的5列来显示。
然后设定我们是要定义第几个自定义字符,前面已经介绍了,LCD1602最多显示8个自定义字符;然后要规定在液晶的什么位置显示自定义字符,看过数据手册我们知道,第一行第一个位置的地址是0x80,第二行一个位置的地址是0xC0。最后就是要显示我们定义的第几个字符其对应CGRAM地址的关系式是:

0x00:第一个(0x40) 0x01:第二个(0x48)
0x02:第三个(0x50) 0x03:第四个(0x58)
0x04:第五个(0x60) 0x05:第六个(0x68)
0x06:第七个(0x70) 0x07:第八个(0x78)

每个字符由5X8点阵组成(也可选用5X10) ,想要实现显示,只需如下图:
例:以5X8点阵为例,显示字符 A

0代表灭,1代表亮
只需将想要显示的字符的对应位置1,就能显示该字符

01110	□█ █ █□
10001	█ □□□ █
10001	█ □□□ █
10001	█ □□□ █
11111	█ ███ █
10001	█ □□□ █
10001	█ □□□ █
10001	█ □□□ █
A={0x0e,0x11,0x11,0x11,0x1f,0x11,0x11,0x11}

代码
流程

首先创建自定义字模
把字模存入CGRAM中对应的自定义位置,位置在上表中以显示出来了
在LCD1602中显示出来

void type_model_diy(){ 
   
	unsigned char code Data_0[]={ 
   0x0e,0x11,0x11,0x11,0x1f,0x11,0x11,0x11};  // 字母A
	lcd_Init();  // LCD1602 初始化
	lcd_write_com(0x40);  // 0100 0000; 指令 0x40 向 CGRAM 地址0 写入自定义数据
	for(i=0; i<8; i++){ 
   
		lcd_write_dat(Data_0[i]);  // 写入自定义字符字模
	}
	lcd_write_com(0x00 + 0x80);  // 在第一行第一列显示 第一个字符
	lcd_write_dat(0);
	while(1);
}

END!
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160148.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python3菜鸟教程笔记

    python3菜鸟教程笔记python2和python3的一些差异:*print函数变了,python3中的print函数必须要加括号*xrange函数合并到了range中,2到5的序列可以直接用range(2,5

    2022年7月6日
    23
  • ECSHOP发货滚动,显视发货人,配送方式名,配送单号及发货日期

    ECSHOP发货滚动,显视发货人,配送方式名,配送单号及发货日期

    2021年8月21日
    65
  • matlab画图操作(修改坐标轴及字体,加粗,颜色修改,适合论文画图)「建议收藏」

    matlab画图操作(修改坐标轴及字体,加粗,颜色修改,适合论文画图)「建议收藏」matlab常用画图操作1.设置坐标轴2.设置figure大小3.matlab线条设置4.子图设置5.颜色查询6.colorbar设置7.线条透明度设置8.设置坐标轴刻度形式9.图例设置1.设置坐标轴%设置坐标轴格式title(‘Title’,’fontsize’,12,’fontname’,’Times’);xlabel(‘Times(s)’,’fontsize’,12,’fontname’,’Times’)ylabel(‘Value’,’fontsize’,12,’fontname’,’Tim

    2022年9月20日
    0
  • 使用outlook制作签名

    使用outlook制作签名使用outlook制作签名制作签名的几种方法直接在编辑器中编辑在Word中编辑好了复制过去直接在生成的文件上编辑直接用word新建htm格式编辑图片不清晰问题制作签名的几种方法你好,最近公司需要我制作公司签名,之前就想着不就是签名嘛,多简单的事。但是经过一系列的尝试之后,发现还真不容易。主要是因为outlook新建签名的编辑栏不支持直接使用html编辑。下面我介绍我尝试的几种方法直接在编辑…

    2022年10月16日
    0
  • 软件测试常用的黑盒测试方法有哪些,简述什么是黑盒测试方法(最常用的黑盒测试方法)…[通俗易懂]

    软件测试常用的黑盒测试方法有哪些,简述什么是黑盒测试方法(最常用的黑盒测试方法)…[通俗易懂]黑盒(又叫功能测试、数据驱动测试):1.黑盒测试发现错误类型:功能错误和遗漏界面错误数据库错误性能错误初始化和终止错误2.黑盒测试:程序外部接口进行的3.黑盒测试就是根据功能需求来设计测试用例,验证软件是否按照预期要求工作。4.黑盒测试技术主要有等价类划分法、边界值法、判定表法、因果图法、场景法等。5.等价类划分法测试技术是依据软件系统输入集合、输出集合或操作集合实现功能的相同性为依据,对其进行的…

    2022年9月27日
    0
  • 单利模式的四种方式

    单利模式相关内容内容角色使用场景优点与单利模式功能相似的概念:全局变量、静态变量(方法)试问?为什么用单例模式,不用全局变量呢?答、全局变量可能会有名称空间的干扰,如果有重名的可能会被覆

    2022年3月29日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号