7.1 液晶概述
液晶(Liquid Crystal)是一种高分子材料,因为其特殊的物理、化学、光学特性,20世纪中叶开始广泛应用在轻薄型显示器上。
液晶显示器(Liquid Crystal Display,LCD)的主要原理是以电流刺激液晶分子产生点、线、面并配合背部灯管构成画面。为叙述简便,通常把各种液晶显示器都直接叫做液晶。各种型号的液晶通常是按照显示字符的行数或液晶点阵的行、列数来命名的。比如:1602的意思是每行显示16个字符,一共可以显示两行;类似的命名还有0801,0802,1601等,这类液晶通常都是字符型液晶,即只能显示 ASCII 码字符,如数字、大小写字母、各种符号等。12232 液晶属于图形型液晶,她的意思是液晶由122列、32行组成,即共有122*32个点来显示各种图形,我们可以通过程序控制这 122*32 个点中的任一个点显示或不显示。类似的命名还有 12864,19264,192128,320240等,根据客户需要,厂家可以设计出任意数组合的点阵液晶。
液晶体积小、功耗低、显示操作简单,但是它有一个致命的弱点,其使用的温度范围很窄,通用型液晶正常工作温度范围为0℃~+55℃,存储温度范围为-20℃~+60℃,即使是宽温级液晶,其正常工作温度范围也仅为-20℃~+70℃,存储温度范围为-30℃~+80℃,因此在设计相应产品时,务必要考虑周全,选取合适的液晶。
本章主要介绍三种具有代表性的常用液晶,同时详细讲解并行操作方式和串行操作方式。市场上使用的1602液晶以并行操作方式居多,但也有并、串口同时具有的,用户可以选择用并口或串口操作。12232液晶同样也有这两种操作方式。
7.2 常用1602液晶操作实例
此处TX-1C使用的1602液晶为5V电压驱动,带背光,可显示两行,每行16个字符,不能显示汉字,内置含128个字符的 ASCII 字符集字库,只有并行接口,无串行接口。
1. 1602型液晶接口信号说明
2. 1602型液晶主要技术参数
3. 基本操作时序
4. RAM地址映射图
控制器内部带有80B的RAM缓冲区,如下所示:
当向上图中的 00~0F、40~4F 地址中的任一处写入显示数据时,液晶都可立即显示出来,当写入到10~27或50~67 地址处时,必须通过移屏指令将它们移入可显示区域方可正常显示。
5. 状态字说明
注意:原则上每次对控制器进行读/写操作之前,都必须进行读/写检测,确保STA7为0。实际上,由于单片机的操作速度慢于液晶控制器的反应速度,因此可以不进行读/写检测,或只进行简短延时即可。
6. 数据指针设置
控制器内部设有一个数据地址指针,用户可以通过其访问内部的全部80B的RAM,如下表所示:
7. 其他设置
8. 初始化设置
(1)显示模式设置
(2)显示开/关及光标设置
9. 写操作时序
分析时序图可知操作1602液晶的流程如下:
(1)分析RS确定是写数据还是写命令
写命令包括使液晶的光标显示与否、光标闪烁与否、是否需要移屏、液晶在何处显示等等。
(2)读/写控制端设置为写模式,即低电平;
(3)将数据或命令送达数据线上;
(4)给E一个高脉冲将数据送入液晶显示器,完成写操作
TX-1C实验板上1602液晶与单片机接口如下图所示:
例1:单纯显示,功能详见注释
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code character_table1[]="I am Chaijin";
uchar code character_table2[]="My mom is Shiyan";
sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7; //声明U2锁存器的锁存端
sbit lcden=P3^4; //声明1602液晶写数据/写命令选择端
sbit lcdrs=P3^5; //声明1602液晶使能信号端
void main()
{
uint character_num;
void write_Command(uchar Com); //写命令函数
void write_Data(uchar Data); //写数据函数
void init(); //初始函数
void delayxms(uint xms); //延时函数
init(); //初始化函数
write_Command(0x80); //将数据指针定位到第一行第一个字处
for(character_num=0;character_num<12;character_num++)
{
write_Data(character_table1[character_num]);
delayxms(200); //每个字之间要做简短延时,太短会影响控制器接收数据的稳定性,调节显示字符的速度
}
write_Command(0x80+0x40); //将数据指针定位到第二行第一个字处,加0x40
for(character_num=0;character_num<21;character_num++)
{
write_Data(character_table2[character_num]);
delayxms(200); //调节显示字符的速度
}
while(1);
}
void write_Command(uchar Com) //写命令函数
{
void delayxms(uint xms); //延时函数
lcdrs=0; //选择写命令模式
P0=Com; //将要写的命令字送到数据总线上
delayxms(5); //稍作延时5ms等待数据稳定
lcden=1; //使能信号置高得到一个高脉冲(初始化中lcden=0)
delayxms(5); //延时5ms等待数据稳定
lcden=0; //使能信号置低完成高脉冲
}
void write_Data(uchar Data) //写数据函数
{
void delayxms(uint xms); //延时函数
lcdrs=1; //选择写数据模式
P0=Data; //将要写的数据字送到数据总线上
delayxms(5); //稍作延时5ms等待数据稳定
lcden=1; //使能信号置高得到一个高脉冲(初始化中lcden=0)
delayxms(5); //延时5ms等待数据稳定
lcden=0; //使能信号置低完成高脉冲
}
void init() //初始函数
{
void write_Command(uchar Com); //写命令函数
dula=0; //关闭数码管位段选,防止同时开启数码管和液晶导致供电不足液晶不亮
wela=0; //同上
lcden=0; //初始化状态下使能信号置低
write_Command(0x38); //设置16×2显示,5×7点阵,8位数据接口,对应指令码00111000
write_Command(0x0e); //显示开显示,显示光标,光标不闪烁
write_Command(0x06); //写一个字符后地址指针+1
write_Command(0x01); //显示清0,数据指针清0
}
void delayxms(uint xms) //延时函数
{
uint x,y;
for(x=xms;x>0;x--)
for(y=124;y>0;y--);
}
例2: 向左移屏,功能详见注释
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code character_table1[]="I am Chaijin";
uchar code character_table2[]="My mom is Shiyan";
sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7; //声明U2锁存器的锁存端
sbit lcden=P3^4; //声明1602液晶写数据/写命令选择端
sbit lcdrs=P3^5; //声明1602液晶使能信号端
void main()
{
uint character_num;
void write_Command(uchar Com); //写命令函数
void write_Data(uchar Data); //写数据函数
void init(); //初始函数
void delayxms(uint xms); //延时函数
init(); //初始化函数
write_Command(0x80+0x10); //将定位数据指针指向液晶第一行非现实区域地址处
for(character_num=0;character_num<12;character_num++)
{
write_Data(character_table1[character_num]);
delayxms(5);
}
write_Command(0x80+0x50); //将定位数据指针指向液晶第二行非现实区域地址处
for(character_num=0;character_num<21;character_num++)
{
write_Data(character_table2[character_num]);
delayxms(5);
}
for(character_num=0;character_num<16;character_num++)
{
write_Command(0x18); //整屏左移一格,一共移动16次可切换所有数据
delayxms(500);
}
while(1);
}
void write_Command(uchar Com) //写命令函数
{
void delayxms(uint xms); //延时函数
lcdrs=0; //选择写命令模式
P0=Com; //将要写的命令字送到数据总线上
delayxms(5); //稍作延时5ms等待数据稳定
lcden=1; //使能信号置高得到一个高脉冲(初始化中lcden=0)
delayxms(5); //延时5ms等待数据稳定
lcden=0; //使能信号置低完成高脉冲
}
void write_Data(uchar Data) //写数据函数
{
void delayxms(uint xms); //延时函数
lcdrs=1; //选择写数据模式
P0=Data; //将要写的数据字送到数据总线上
delayxms(5); //稍作延时5ms等待数据稳定
lcden=1; //使能信号置高得到一个高脉冲(初始化中lcden=0)
delayxms(5); //延时5ms等待数据稳定
lcden=0; //使能信号置低完成高脉冲
}
void init() //初始函数
{
void write_Command(uchar Com); //写命令函数
dula=0; //关闭数码管位段选,防止同时开启数码管和液晶导致供电不足液晶不亮
wela=0; //同上
lcden=0; //初始化状态下使能信号置低
write_Command(0x38); //设置16×2显示,5×7点阵,8位数据接口,对应指令码00111000
write_Command(0x0e); //显示开显示,显示光标,光标不闪烁
write_Command(0x06); //写一个字符后地址指针+1
write_Command(0x01); //显示清0,数据指针清0
}
void delayxms(uint xms) //延时函数
{
uint x,y;
for(x=xms;x>0;x--)
for(y=124;y>0;y--);
}
参考资料:
[1] 郭天祥. 新概念51单片机C语言教程:入门、提高、开发、拓展全攻略[M]. 北京: 电子工业出版社, 2009.