项目2 通用型1602LCD液晶操作方法
液晶显示器的英文名是Liquid Crystal Display, 简称 LCD。 液晶显示器作为显示器件具有体积小、重量轻、功耗低等优点,所以 LCD 日渐成为各种便携式电子产品的理想显示器,如计算器,电子表,汽车电子仪表等。根据LCD的显示内容划分,可以分为段式LCD、字符式LCD和点阵式LCD 3种。其中,字符式LCD以其廉价、显示内容丰富、美观、使用方便等特点,成为LED数码管的理想替代品。
1. 1602字符型液晶简介
字符型LCD专门用于显示数字、字母、图形符号以及少量自定义符号。这类显示器把LCD控制器、点阵驱动器、字符存储器等做在一块板上,再与液晶屏一起组成一个显示模块。如下图所示。
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
图1 LCD1602的外形图
目前字符型LCD常用的有16字X1行、16字X2行、20字X2行、20字X4行等液晶模块,型号通常用 XXX1602、XXX1604、XXX2002、XXX2004等 其中XXX为厂家商标名称 16代表液晶每行可以显示16个字符;02代表共有2行,也就是说这个液晶一共可以显示32字符。
2 通用型1602液晶操作方法
1602液晶也叫1602字符型液晶 它是一种专门用来显示字母、数字、符号等的点阵型液晶模块 它有若干个5X7或5X11点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔 每行之间也有间隔 起到了字符间距和行间距的作用,正因为如此 所以他不能显示图形(用自定义CGRAM,显示效果也不好)1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg 图2 LCD1602的背面引脚图如图2所示,字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),从左到右分别是1引脚到16引脚
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1
编号 | 符号 | 引脚说明 | 编号 | 符号 | 引脚说明 | 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 LCD1602接口信号说明
第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脚:背光源负极。
3 下面几个表是1602指令集
1)寄存器选择功能
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
表2 寄存器选择功能
2)11条指令表
指令 | 指令码 | 说明 | 指令周期 fosc=250kHz | RS | R/W | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | 清屏 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 清除屏幕,置AC为0,光标回位。 | 1.64ms | 光标返回 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | * | DDRAM地址为0,显示回原位,DDRAM内容不变. | 1.64ms | 设置输入 方式 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S | 设置光标移动方向并指定显示是否移动。 | 40µs | 显示开关 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | 设置显示开或关D、光标开关C、光标所在字符闪烁B. | 40µs | 移位 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | * | * | 移动光标及整体显示,同时不改变DDRAM内容。 | 40µs | 功能设置 | 0 | 0 | 0 | 0 | 1 | DL | N | F | * | * | 设置接口数据位数DL、显示行数L、字符字体F。 | 40µs | CGRAM 地址设置 | 0 | 0 | 0 | 1 | ACG | 设置CGRAM地址。设置后发送接收数据。 | 40µs | DDRAM 地址设置 | 0 | 0 | 1 | ADD | 设置DDRAM地址。设置后发送接收数据。 | 40µs | 忙标志/读地址计数器 | 0 | 1 | BF | AC | 读忙标志BF标志正在执行内部操作并读地址计数器内容。 | 0µs | CGRAM/DDRAM数据写 | 1 | 0 | 写数据 | 从CGRAM或DDRAM写数据。 | 40µs | CGRAM/DDRAM数据读 | 1 | 1 | 读数据 | 从CGRAM或DDRAM读数据。 | 40µs | | | | | | I/D=1:增量方式;I/D=0:减量方式 S=1:移位 S/C=1:显示移位;S/C=0:光标移位 R/L=1:右移;R/L=0:左移 DL=1:8位;DL=0:4位 N=1:2行;N=0:1行 F=1:5 x 10字体 F=0:5 x 7字体 BF=1:执行内部操作;BF=0可接收指令 | DDRAM:显示数据RAM CGRAM:字符发生器RAM ACG:CGRAM地址 ADD:DDRAM地址及光标 地址 AC:地址计数器,用于 DDRAM和CGRAM | 执行周期主频改变而改变。 例如当fcp或 fosc=270KHZ 时:40μs x 250/270=37μs |
表3 11条指令表
3)标准字符库
High 4BIT | MSB | 2 | 3 | 4 | 5 | 6 | 7 | 8 | A | B | C | D | E | F | LOW 4BIT | RAM0000 | 0 | (1) | | 0 | @ | P | ˋ | p | | | ー | タ | ミ | α | p | 1 | (2) | ! | 1 | A | Q | a | q | | 。 | ア | チ | ム | ä | q | 2 | (3) | “ | 2 | B | R | b | r | | ┌ | イ | ッ | メ | β | θ | 3 | (4) | # | 3 | C | S | c | s | | ┘ | ウ | テ | モ | ε | ∞ | 4 | (5) | $ | 4 | D | T | d | t | | 、 | エ | ト | ャ | μ | Ω | 5 | (6) | % | 5 | E | U | e | u | | • | オ | ナ | ュ | σ | ü | 6 | (7) | & | 6 | F | V | f | v | | ゝ | カ | ニ | ヨ | ρ | Σ | 7 | (8) | ’ | 7 | G | W | g | w | | ァ | キ | ヌ | ラ | g | π | 8 | (1) | ( | 8 | H | X | h | x | | ィ | ク | ネ | リ | √ | _х | 9 | (2) | ) | 9 | I | Y | i | y | | ゥ | ケ | ノ | ル | ¨ | y | A | (3) | * | : | J | Z | j | z | | ェ | コ | ハ | レ | j | 千 | B | (4) | + | ; | K | [ | k | { | | ォ | サ | ヒ | ロ | ` | 万 | C | (5) | , | < | L | ¥ | l | | | | ャ | シ | フ | ヮ | φ | 円 | D | (6) | - | = | M | | m | } | | ュ | ス | ヘ | ン | キ | ÷ | E | (7) | . | > | N | ^ | n | → | | ョ | セ | ホ | ゛ | _n | | F | (8) | / | ? | O | _ | o | ← | | ッ | ソ | マ | ゜ | | |
表4 标准字符库
DDRAM就是显示数据RAM, 用来寄存待显示的字符代码,共80个字节,其地址和对应的关系如下表:也就是说在屏幕上第一行第一列要显示“A“字,就要向DDRAM中的00H处写入A的代码就行,但具体的写入要按LCD1602的指令格式来进行,一行有40个地址,我们就用前16个就行,第二行也同样用前16个就行。对应如下:
显 示 位 序 号 | 1 2 3 4 5 …………………… 40 | DD RAM 地 址(HEX) | 第 一 行 | 00 01 02 03 04 ..……………….. 27 | 第 二 行 | 40 41 42 43 44 ………………….. 67 |
表5 显示位与DDRAM地址的对应关系
1602型LCD显示字符的过程
。
在这里要说明的是:
1) 要用1602型LCD显示字符必须解决3个问题:(1)待显示字符ASCII标准码产生;(2)液晶显示模式的设置;(3)字符显示位置的指定
2) 若想在00H处显示数据的话,则必须将00H加上80H,即0x00H+0x80H,若要在01H处显示数据,也必须加0x80H, 例如要将某字符显示在第2行第5列,则确定地址的指令代码应为80H+44H=C4H。依次类推
3) CGRAM是用户自定义的字符图形,可以定义8个
4) LCD1602只有11条指令,学会使用这11条指令,就可以轻松控制。
5) 要让液晶显示字符,必须对有无光标、光标的移动方向、光标是否闪烁及字符的移动方向等进行设置,才能获得所需的显示效果。1602液晶显示模式的设置是通过控制指令对内部的控制器控制而实现的,常用的控制指令见表8-5.例如,要将显示模式设置为“16X2显示,5X7点阵,8位数据接口”,只要向液晶模块写二进制指令代码00111 000B,即16进制代码38H就可以了。
6) LCD是一个慢显示器件,所以在写每条指令前一定要先读LCD的忙碌状态。如果LCD正忙于处理其他指令,就等待;如果不忙,再执行写指令。为此,1602型LCD专门设了一个忙碌标志位BF,该位链接在8位双向数据线的DB7位上。如果BF为低电平“0”,表示LCD不忙;如果BF为高电平“1”,则表示LCD处于忙碌状态,需要等待。假定1602型LCD的8位双向数据线(DB0~DB7)是通过单片机的P0口进行数据传递的,那么只要检测P0口的P0.7引脚电平(DB连P0.7)就可以知道忙碌标志位BF的状态
4. 对照上面的表格,我们对11条指令作如下分解:
● 对DDRAM的内容和地址操作,HD44780的指令集及其设置说明,共有11条指令:1)清屏指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg功能:<1> 清除液晶显示器,即将DDRAM的内容全部填入“空白”的字符<2> 光标归位,即将光标撤回液晶显示屏的左上方;
<3> 将地址计数器(AC)的值设为0。 2)光标归位指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg功能:<1> 把光标撤回到显示器的左上方;
<2> 把地址计数器(AC)的值设置为0;
<3> 保持DDRAM的内容不变 3).输入模式设置指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg功能:设定每次写入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
I/D=0写入新数据后光标左移 I/D=1写入新数据后光标右移
S=0写入新数据后显示屏不移动 S=1写入新数据后显示屏整体右移或左移,以得到光标不移动而屏幕移动 效果 4)显示开关控制指令file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。参数设定的情况如下:
D=0显示功能关 D=1显示功能开
C=0无光标 C=1有光标
B=0光标不闪烁 B=1光标闪烁 5).设定显示屏或光标移动方向指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image015.jpg
S/C | R/L | 设定情况 | 0 | 0 | 光标左移1格,且AC值减1 | 0 | 1 | 光标右移1格,且AC值加1 | 1 | 0 | 显示器上字符全部左移一格,但光标不动 | 1 | 1 | 显示器上字符全部右移一格,但光标不动 |
6).功能设定指令 (非常重要的指令)file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image017.jpg 功能:设定数据总线位数、显示的行数及字型。参数设定的情况如下:
DL=0 数据总线为4位 DL=1数据总线为8位
N=0 显示1行 N=1 显示2行
F=0 5×7点阵/每字符 F=1 5×10点阵/每字符7).设定CGRAM地址指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image019.jpg功能:设定下一个要存入数据的CGRAM的地址8).设定DDRAM地址指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image021.jpg功能:设定下一个要存入数据的CGRAM的地址。 (注意这里我们送地址的时候应该是0x80+Address,这也是前面说到写地址命令的时候要加上0x80的原因) 9).读取忙信号或AC地址指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image022.jpg功能:<1> 读取忙碌信号BF的内容,BF=1表示液晶显示器忙,暂时无法接收单片机送来的数据或指令; 当BF=0时,液晶显示器可以接收单片机送来的数据或指令; <2> 读取地址计数器(AC)的内容。 10).数据写入DDRAM或CGRAM指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image024.jpg功能:<1> 将字符码写入DDRAM,以使液晶显示屏显示出相对应的字符; <2> 将用户自己设计的图形存入CGRAM。 11)从CGRAM或DDRAM读出数据的指令 file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image026.jpg功能:读取DDRAM或CGRAM中的内容。
基本操作时序:
读状态 输入:RS=L,RW=H,E=H 输出:DB0~DB7=状态字
写指令 输入:RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码
输出:无
读数据 输入:RS=H,RW=H,E=H 输出:DB0~DB7=数据
写数据 输入:RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据
输出:无说明:平时我们只用到常用的3—4条指令,学生不需去记录,只需以后做项目时用到去查这些指令即可。5.读写操作时序图:
1)读操作时序(用的不多)
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image028.jpg2)写操作时序
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image030.jpg
下面我们亲自操作LCD1602,在我们是实验板上实现如下描述
6. 举例说明
1)用LCD循环右移显示"Welcome to china"
2)实验电路图
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image032.jpg
注意:1602VR 是1602液晶的对比度调节电位器,如果液晶不显示或者显示文字不清晰,可以调节此电位器,来达到最理想的显示效果。
15脚是背光灯正极引脚 接到实验的JPBG跳线端 通过JPBG来控制背光灯的亮灭。
3 )操作步骤
将 JPP0跳线端的跳线帽拔掉 以免干扰1602液晶显示
将JPSMG 数码管控制跳线拔掉 使数码管停止工作。
插上1602LCD液晶
将JPBG液晶背光跳线插上
4) 液晶显示流程图
file:///C:/Users/d/AppData/Local/Temp/msohtmlclip1/01/clip_image034.jpg
5) C语言源程序
//用LCD循环右移显示"Welcome to China"#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚unsigned char code string[ ]={"Welcome to China"}; /*****************************************************函数功能:延时1ms(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒***************************************************/void delay1ms(){ unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<33;j++) ; } /*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/ void delay(unsigned char n) { unsigned char i; for(i=0;i<n;i++) delay1ms(); }/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。result=1,忙碌;result=0,不忙***************************************************/ unsigned char BusyTest(void) { bit result; RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; //E=1,才允许读写 _nop_(); //空操作 _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 result=BF; //将忙碌标志电平赋给result E=0; return result; }/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate***************************************************/void WriteInstruction (unsigned char dictate){ while(BusyTest()==1); //如果忙就等待 RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" _nop_(); _nop_(); //空操作两个机器周期,给硬件反应时间 P0=dictate; //将数据送入P0口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 }/*****************************************************函数功能:指定字符显示的实际地址入口参数:x***************************************************/ void WriteAddress(unsigned char x) {WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x" }/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/ void WriteData(unsigned char y) { while(BusyTest()==1); RS=1; //RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" P0=y; //将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 }/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void LcdInitiate(void){ delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38)//显示模式设置:16×2显示,5×7点阵,8位数据接口 delay(5); //延时5ms WriteInstruction(0x38); delay(5); WriteInstruction(0x38); delay(5); WriteInstruction(0x0f);//显示模式设置:显示开,有光标,光标闪烁 delay(5); WriteInstruction(0x06); //显示模式设置:光标右移,字符不移 delay(5); WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除 delay(5); }void main(void) //主函数 { unsigned char i; LcdInitiate(); //调用LCD初始化函数 delay(10); while(1) { WriteInstruction(0x01);//清显示:清屏幕指令 WriteAddress(0x00); // 设置显示位置为第一行的第5个字 i = 0; while(string != '\0') { WriteData(string); i++; delay(150); } for(i=0;i<4;i++) delay(250); } }
7.实时演练操作
演练1: 1)LCD第一行显示: CHINESE
LCD第二行显示: NEWYEAR
2)先将两行字符写入DDRAM中,然后从右至左逐字移出显示。
3)在指定位置停留1.6秒后,闪烁2次,清屏。
4)反复循环上述显示方式。
|