文章目录[隐藏]
1. 参考资料:
本文在此LCD1602中文资料的基础上修改完成。
2. 中文资料
2.1. 液晶显示器各种图形的显示原理
2.1.1 基本原理
点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16=1024个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。例如屏的第一行的亮暗由RAM区的000H——00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=FFH,……(00EH)=FFH,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。这就是LCD显示的基本原理。
2.1.2 字符的显示
用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
2.1.3 汉字的显示
汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字
2.2 1602字符型LCD简介
-
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用161,162,202和402行等的模块。下面以长沙太阳人电子有限公司的1602字符型液晶显示器为例,介绍其用法。一般1602字符型液晶显示器实物如图
图一 -
1602LCD的基本参数及引脚功能
1602LCD分为带背光和不带背光两种,控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图
图二 -
LCD1602主要技术参数:
- 显示容量:16×2个字符
- 芯片工作电压:4.5—5.5V
- 工作电流:2.0mA(5.0V)
- 模块最佳工作电压:5.0V
- 字符尺寸:2.95×4.35(W×H)mm
-
引脚功能说明
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表
编号 | 符号 | 引脚说明 | 编号 | 符号 | 引脚说明 |
---|---|---|---|---|---|
1 | VSS | 电源地 | 9 | D2 | 数据 |
2 | VDD | 电源正极 | 10 | D3 | 数据 |
3 | VL | 液晶显示偏压,对比度调节 | 11 | D4 | 数据 |
4 | RS | 数据/命令选择 | 12 | D5 | 数据 |
5 | R/W | 读/写选择 | 13 | D6 | 数据 |
6 | E | 使能信号 | 14 | D7 | 数据 |
7 | D0 | 数据 | 15 | BLA | 背光源正极 |
8 | D1 | 数据 | 16 | BLK | 背光源负极 |
表1 引脚接口说明表
- 第1脚:VSS为地电源。
- 第2脚:VDD接5V正电源。
- 第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
- 第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
- 第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
- 第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
- 第7~14脚:D0~D7为8位双向数据线。
- 第15脚:背光源正极。
- 第16脚:背光源负极。
- 其与单片机的连接如下图所示
2.3 1602存储空间
2.3.1 DDRAM :
显示用RAM直接和屏幕上的点相对应,屏幕上的一个点和DDRAM中的一个位对应,字符屏的DDRAM和图形屏的DDRAM有一点点区别。
2.3.2 CGROM:
字模存储用空间。你要显示某个ASCII字符时,要显示字符的字模就存在这里,对于字符屏,要显示某个字符时,往DDRAM里写字符的索引(一般都是ASCII码)就可以完成显示。比如你写0x38,则显示为数字8。
字符屏的DDRAM一般和IC能显示的最大字符数相同。有的IC可以控制显示80个字符,但屏幕只显示20个字符。对于图形屏,往DDRAM里写什么样的数据,屏幕上就会显示什么样的点,比如你写0x38, 则显示00111000。图形屏的DDRAM一般都会比屏幕显示大个2倍以上,为的是简化翻屏,以及实现其他特殊显示效果 。
CGRAM是用户自建字模区,有时ASCII码表不能满足个人对字符的要求,则需要在这里写入字模。字模的方式和CGROM中的一样。
一般写入到这里的字模,其索引值为(0x00~0x07),建立好字模后,往DDRAM中写索引0x00,新建的字符就会显示出来。
2.4 1602控制指令
1602液晶模块内部的控制器共有11条控制指令
如下表所示:
序号 | 指令 | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 清显示 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | 光标返回 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | * |
3 | 置输入模式 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S |
4 | 显示开/关控制 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B |
5 | 光标或字符移位 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | * | * |
6 | 置功能 | 0 | 0 | 0 | 0 | 1 | DL | N | F | * | * |
7 | 置字符发生存贮器地址 | 0 | 0 | 0 | 1 | 字符发生存贮器地址 | |||||
8 | 置数据存贮器地址 | 0 | 0 | 1 | 显示数据存贮器地址 | ||||||
9 | 读忙标志或地址 | 0 | 1 | BF | 计数器地址 | ||||||
10 | 写数到CGRAM或DDRAM) | 1 | 0 | 要写的数据内容 | |||||||
11 | 从CGRAM或DDRAM读数 | 1 | 1 | 读出的数据内容 |
1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。(说明1为高电平,0为低电平)
- 指令1:清显示,指令码01H,光标复位到地址00H位置
- 指令2:光标复位,光标返回到地址00H
- 指令3:输入方式选择指令,用于设置光标和画面移动方式:
I/D = 1:表示数据读写操作后,AC自动加1;
I/D = 0:表示数据读写操作后,AC自动减1;
S = 1:表示数据读写操作后,画面平移;
S= 0:表示数据读写操作后,画面保持不变; - 指令4:显示开关控制。
D:显示开关:D= 1:开;D = 0:关;
C:光标开关:C= 1:开;C= 0:关;
B:闪烁开关:B= 1:开;B= 0:关;。 - 指令5:光标或显示移位 ,用于在不影响DDRAM的情况下使光标、画面移动:
S/C = 1:画面平移1个字符位;
S/C = 0:光标平移1个字符位;
R/L = 1:右移;
R/L = 0:左移; - 指令6:功能设置命令,用于设置工作方式(初始化指令):
DL= 1:表示8位数据接口;
DL = 0:表示4位数据接口;
N = 1:表示2行显示;
N = 0:表示1行显示;
F = 1:表示510的点阵字符;
F = 0:表示57的点阵字符; - 指令7:字符发生器RAM地址设置。
- 指令8:DDRAM地址设置。
- 指令9:读忙信号和光标地址, BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。
- 指令10:写数据指令,用于将地址码写入DDRAM以使LCD显示出相应的图形或将用户自创的图形存入CGRAM内:
- 指令11:读数据指令,根据当前设置的地址,从DDRAM和CGRAM中读出数据
2.5 基本操作时序表
与HD44780相兼容,时序表如下:
读状态 | 输入 | RS=L,R/W=H,E=H | 输出 | D0—D7=状态字 |
---|---|---|---|---|
写指令 | 输入 | RS=L,R/W=L,D0—D7=指令码,E=高脉冲 | 输出 | 无 |
读数据 | 输入 | RS=H,R/W=H,E=H | 输出 | D0—D7=数据 |
写数据 | 输入 | RS=H,R/W=L,D0—D7=数据,E=高脉冲 | 输出 | 无 |
2.5.1 读写操作时序如图所示
- 读操作时序
- 写操作时序
2.6 1602LCD的RAM地址映射及标准字库表
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在,哪里显示字符,图是1602的内部显示地址。
图:LCD1602内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。每次输入指令前都要判断液晶模块是否处于忙的状态。
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如图10-58所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
LCD1602程序详见:http://www.51hei.com/mcu/2210.html
3. 51单片机驱动LCD1602的电路图+程序
3.1 编程思路:
- 设置1602液晶的功能;
- 设置1602液晶的输入方式;
- 设置1602液晶的显示方式;
- 清屏;
3.2 仿真电路图
我的电路图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200220113836983.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Fja3RvbWFz,size_16,color_FFFFFF,t_70 =80*120)
以下内容来源于:单片机教程网
上图是仿真效果 显示2行字符.
/*****************************************
电路连接
P0------DB0~DB7
P2.6------RS
P2.5------RW
P2.7------E
*****************************************/
3.2 代码:
- main.c
#include <reg52.h>
#include "lcd1602.h"
void lcdInit();
uchar code table[]="i study mcu";
uchar code table1[]="2020-02-20";
void main()
{
uchar num;
lcdInit();
lcdWriteCom(0x80);
for(num=0;num<11;num++)
{
lcdWriteData(table[num]);
delay_n10us(50);
}
lcdWriteCom(0x80+0x40);
for(num=0;num<10;num++)
{
lcdWriteData(table1[num]);
delay_n10us(50);
}
while(1);
}
void lcdInit()
{
lcdWriteCom(0x38); //设置8位数据格式,2行,5*7
lcdWriteCom(0x0c);//设置显示开,关光标,不闪烁。
lcdWriteCom(0x06);//写字符后,地址指针+1;
lcdWriteCom(0x01);//显示清0,数据指针清0
delay_n10us(500); //延时5MS
}
- lcd1602.h
#ifndef _LCD1602_H
#define _LCD1602_H
#include "reg52.h"
#ifndef uint
#define uint unsigned int
#endif
#ifndef uchar
#define uchar unsigned char
#endif
#define LCD_DB P0
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
void lcdWriteData(uchar dat);
void lcdWriteCom(uchar com);
void delay_n10us(uint n);
#endif
- lcd1602.c
#include "lcd1602.h"
void delay_n10us(uint n);
void lcdWriteCom(uchar com)
{
LCD_DB=com;
LCD_RS=0; //指令
LCD_RW=0; //写入
LCD_E=1; //允许
delay_n10us(5); //不知道是什么原因,这里不加延时,第2行不能显示。
LCD_E=0; //产生下降沿
delay_n10us(5);
}
void lcdWriteData(uchar dat)
{
LCD_DB=dat;
LCD_RS=1; //数据
LCD_RW=0; //写入
LCD_E=1;
//delay_n10us(5);//这里延时有没有都可以。
LCD_E=0;
delay_n10us(5);
}
void delay_n10us(uint n) //延时10us的整数倍。
{
uchar a;
uint b;
for(b=n;b>0;b--)
for(a=2;a>0;a--);
}
版权声明:本文为CSDN博主「acktomas」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/acktomas/article/details/104315525
暂无评论