1602字符型液晶显示器

作为人机交互的硬件设备,液晶显示屏能提供比数码管更丰富的显示信息,而且液晶显示屏在显示的时候不需要像数码管一样持续的刷新,可以大大地降低单片机的负担。本章介绍的1602液晶显示器就是液晶产品中非常有代表性的一款产品。

21.1

1602液晶概述

21.1.1

1602液晶的特点

1602液晶是字符型液晶显示器,广泛应用于工业和民用领域,它因能显示16个×2排的西文字符而得名。1602液晶模块最初采用的控制芯片是HD44780,之后各厂家生产的1602液晶模块基本上也都采用了与HD44780兼容的控制IC,所以市场上出售的1602液晶的结构和功能都基本相同,驱动程序也可以互相兼容。不同品牌、不同型号的1602液晶只是在供电电压、字符颜色和背光等辅助功能上有些区别。1602液晶的外观如图21-1所示。

21.1.2

1602液晶的引脚功能

1602液晶的引脚总计有16个,其引脚功能如表21-1所示。

21.1.3

1602液晶与单片机的接口

1602液晶与AVR单片机的接口电路如图21-2所示。单片机通过一组I/O口与1602液晶的数据端D0-D7端相连,另外三个I/O口分别与1602液晶的RS、R/W和E端相连。VL端为液晶显示偏压信号调整端,通过一个10K电位器调整电压以改变液晶屏的对比度,BLA、BLK是液晶屏的背光电源正和接地端。

21.2

1602液晶的功能

21.2.1

1602液晶的显示数据RAM 1602液晶的显示数据RAM称为DDRAM,相当于1602液晶的显存,用来存储1602液晶待显示的字符代码。1602液晶的DDRAM共80字节,其地址是不连续的,且分为两排。第一排地址为00H-27H,共计40字节,第二排地址为40H-67H,也是40字节。这两排地址中前16个地址的内容会显示在屏幕上,显示区域与DDRAM地址的对应关系如图21-3所示。

21.2.2

1602液晶的字符发生器

1602液晶的控制器内部有两种类型的字符发生器,一种是CGROM,它的内部存有已经固化好的字模库。另一种称为CGRAM,用于保存用户在程序中自己定义的显示图形。

1.CGROM CGROM中内置了192个常用字符的字模,包含有阿拉伯数字、英文字母的大小写、常用的符号和日文假名等,每一个字符都有一个固定的代码。CGROM中存储的字符和代码如图21-4所示。

表格的第一行列出了字符代码的高四位,第一列列出了字符代码的低四位,二者组合在一起就是一个完整的字符代码,用于对该字符的寻扯。在1602的CGROM中,字符代码20H–7FH为标准的ASCII码,A0H–FFH为日文字符和希腊文字符,其余字符码10H–1FH及80H–9FH没有定义。

从上图中我们可以看出,大写的英文字母“A”的代码高四位是0100,低四位是0001,组合在一起则是01000001B,也就是十六进制的41H。如果我们要在屏幕上显示字母“A”时,只需把“A”的字符代码41H发给1602液晶模块即可,模块会自动把地址41H中的字符点阵数据取出并显示图形。

2.CGRAM 1602液晶提供了64字节的CGRAM,用于保存自定义的点阵图形,其在CGRAM中的存储地址为00H–3FH。这64字节的存储空间每8个分为一组,总计可以存储8个5X8点阵的自定义图形。由于1602液晶仅使用一行5位数据作为字符点阵,所以作为CGRAM字模库仅使用存储单元字节的低5位,而高3位虽然存在但并不作为字模数据使用。

在1602液晶的字符发生器列表中,字符代码00H–0FH就是用户自定义的这8组字模库的访问代码,另8个字符访问代码08H–0FH没有启用。自定义字符代码和CGRAM存储地址的对应关系如表21-2所示。

21.2.3

1602液晶的操作时序

1.读操作

读操作的时序如图21-5所示。对1602液晶的读操作分为读状态字操作和读数据操作两种,其各引脚的逻辑关系如下。

·读状态字操作:RS=0、R/W=1、E=1。当E端由高电平向低电平跳变(下降沿)时,状态字会从液晶的数据总线上被读出。

·读数据操作:RS=1、R/W=1、E=1。当E端由高电平向低电平跳变(下降沿)时,数据会从液晶的数据总线上被读出。

2.写操作

写操作的时序如图21-6所示。对1602液晶的写操作分为写指令和写数据两种,其各引脚的逻辑关系如下。

·写指令操作:RS=0、R/W=0、E=1。当E端由高电平向低电平跳变(下降沿)时,指令会写入液晶显示模块。

·写数据操作:RS=1、R/W=0、E=1。当E端由高电平向低电平跳变(下降沿)时,数据会写入液晶显示模块。

21.2.4

1602液晶的操作指令

对1602液晶的操作是通过一系列的指令来完成的,这些指令主要有以下9个。

1)读取状态字指令:该指令也称为检测忙信号指令,使用本指令可以读回1602

LCD自身的状态。

BF:读/写允许位。当其置1时表示液晶显示器忙,暂时无法接收单片机送来的数据或指令,当该位清零时表示液晶显示器可以接收单片机送来的数据或指令。

AC6:AC0:读取地址计数器AC的内容。

2)工作方式设置指令:本指令用于设定液晶显示器的工作状态。

DL:设置液晶显示器与MCU的接口形式。当该位置1时设定数据总线宽度为8位,即DB7~DB0有效,该位清零时数据总线宽度为4位,即DB7~DB4有效。

N:设置显示字符的行数。当该位置1时为两行字符,清零时为一行字符。

F:设置显示字符的字体。该位置1时为5X11点阵字符体,清零时为5X7点阵字符体。

3)显示状态设置指令:该指令控制着画面、光标和闪烁的开与关。

D:画面显示状态位。该位置1时显示功能开启,清零时显示功能关闭。该指令仅影响显示屏的开关,并不影响显存中的数据。

C:光标显示状态位。该位置1时显示光标,清零时不显示光标。

B:闪烁显示状态位。该位置1时光标闪烁,清零时光标不闪烁。

4)输入方式设置指令:该指令用于设定每次输入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。

I/D:光标移动设定位。该位置1时写入新数据后光标右移,清零时写入新数据后光标左移。

S:字符移动设定位。该位置1时写入新数据后显示屏整体右移1个字符,清零时写入新数据后显示屏不移动。

5)清屏指令:该指令用于清除液晶显示器屏幕信息。

该指令的功能为清除屏幕信息,即将DDRAM的内容全部填入“空白”的ASCII码20H,将光标置为液晶显示屏的左上方,并将地址计数器AC的值设为0。

6)光标归位指令:将光标置于显示屏左上方。

该指令用于把光标撤回到显示屏的左上方,把地址计数器AC的值设置为0并保持DDRAM的内容不变。

7)DDRAM地址设置指令:该指令用于设置DDRAM的访问地址。

该指令将7位的DDRAM地址写入地址指针计数器AC当中,随后的读写操作则是针对DDRAM中该地址的读写操作。

8)光标或画面滚动设置指令:该指令设置光标和画面的特性。

S/C:滚动对象的选择位。该位置1时画面滚动,清零时光标滚动。

R/L:滚动方向的选择位。该位置1时向右滚动,清零时向左滚动。

画面滚动是将DDRAM每一行40个显示单元的第一个单元和最后一个单元连接起来,形成闭环式的滚动,其效果是将屏幕上两行显示内容同时向左或向右移动。光标滚动则是在整个DDRAM范围内,将AC指针计数器的值加一或减一,其效果是最初写入的字符不动,后续字符依次向左或向右写入。本条指令在执行后画面即开始变化,每执行一次画面就变化一次。

9)CGRAM地址设置指令:该指令用于设置CGRAM的访问地址。

该指令用于将6位的CGRAM地址写入地址指针计数器AC内,随后的读写操作则是针对CGRAM的读写操作。

21.2.5

1602液晶的初始化

对1602液晶的初始化,主要是完成对其功能的基本设置。为了简化程序,在实际应用时往往只向1602液晶中写入命令或数据,而并不检测忙信号。以下列出的是一个1602液晶简单的初始化过程:

1)写入指令38H,将1602液晶设置为8位数据线格式,2行字符显示,5×7点阵。

2)写入指令0x0F,将1602液晶设置为显示功能开,有光标且光标闪烁。

3)写入指令0x06,将液晶设置为写入新数据后光标右移,显示屏不移动。

4)写入指令0x01,清除液晶显示器屏幕信息,将光标撤回液晶显示屏的左上方并且将地址计数器AC的值设为0。

需要说明的是,前三条指令的执行速度都很快,大约为在40μs的时间内就可以完成,最后一条清屏指令用时较长,大约需要1.64ms的时间,因此在使用这条指令时,要考虑加入适当的延时。

21.3

1602液晶编程实例

使用杜邦线按照图21-2所示方式连接AVR系统板与1602液晶,系统板上的电位器W1的输出端J2连接液晶屏的VL端,用于偏压调整。打开Atmel Studio 6.1软件,新建名为“LCD1602”的项目,保存在chapter21文件夹下,软件会自动将名为LCD1602.c的源文件添加到新建的项目中。编辑LCD1602.c源文件,具体代码详见代码清单21-1。

代码清单21-1

1602液晶驱动程序

/*

*

LCD1602.c *

LCD1602

液晶驱动程序滚屏显示

*

Created: 2013/10/26

22:27:25

*

Author: GAO */

/*

DATA_BUS=PORTA */

#include 
//
包含AVR 头文件
#define F_CPU 16000000UL //
定义系统时钟
#include 
//
包含延时函数头文件
#define uchar unsigned char #define uint unsigned int #define LCDRS_SET (PORTD|=0x20)
//
置位PD5
#define LCDRS_CLR (PORTD&=0xDF)
//
清零PD5
#define LCDRW_SET (PORTD|=0x40)
//
置位PD6
#define LCDRW_CLR (PORTD&=0xBF)
//
清零PD6
#define LCDEN_SET (PORTD|=0x80)
//
置位PD7
#define LCDEN_CLR (PORTD&=0x7F)
//
清零PD7
const unsigned char table1[]="ATmega32+LCD1602
TEST PROGRAM"; const unsigned char table2[]="QQ:710878209
TEL:13804638210"; void write_com(uchar com); //
向1602
液晶写命令函数声明
void write_inf(uchar inf); //
向1602
液晶写数据函数声明
void init_lcd(void); //1602
液晶初始化函数声明
/**********
主函数**********/
int main(void)
{
uchar num; //
定义循环变量NUM init_lcd(); //
初始化1602
液晶
_delay_ms(5); //
延时以等待液晶清屏指令完成
for(num=0;num<29;num++)
{
write_inf(table1[num]); //
在LCD 第一行写入字符串
_delay_ms(2); //
延时2ms }
for(num=0;num<31;num++)
{
write_com(0x80+0x40+num); //
将地址设为LCD 的第二行
write_inf(table2[num]); //
在LCD 第二行写入字符串
_delay_ms(2); //
延时2ms }
while(1)
{
write_com(0x18); //
让屏幕循环左移
_delay_ms(500); //
延时500ms }
}
/**********
向1602
液晶写命令函数**********/
void write_com(uchar com)
{
LCDRW_CLR; //
将R/W 端清零表示写操作
LCDRS_CLR; //
将RS 端清零表示写命令
PORTA=com; //
数据由PORTA 端口送出
_delay_ms(2); //
延时2ms LCDEN_SET; //
将E 端置高
_delay_ms(2); //
延时2ms LCDEN_CLR; //
将E 端置低产生下降沿,命令写入
}
/*********
向1602
液晶写数据函数***********/
void write_inf(uchar inf)
{
LCDRW_CLR; //
将R/W 端清零表示写操作
LCDRS_SET; //
将RS 端置1
表示写命令数据
PORTA=inf; //
命令由PORTA 端口送出
_delay_ms(2); //
延时2ms LCDEN_SET; //
将E 端置高
_delay_ms(2); //
延时2ms LCDEN_CLR; //
将E 端置低产生下降沿,数据写入
}
/**********
初始化1602
液晶**********/
void init_lcd(void)
{
DDRA=0xFF; DDRD=0xF0; LCDRW_CLR; LCDEN_CLR; LCDRS_CLR; write_com(0x38); //8
位数据线格式,2
行字符,5×7
点阵
write_com(0x0f); //
显示功能开,有光标且光标闪烁
write_com(0x06); //
写入新数据后光标右移,显示屏不移动。
write_com(0x01); //
清屏
}
/**********
结束**********/
源代码经编译后下载到AVR系统板中,程序运行后液晶屏幕上会有文字显示,显示内容会以1秒钟的时间间隔向屏幕的左侧移动,AVR系统板驱动1602液晶的具体情况如图21-7所示。如果此时液晶屏显示模糊,可以用改锥左右旋动系统板上的电位器W1,直至液晶屏显示清晰为止。

 


评论: