LCD液晶屏显示原理
液晶(Liquid Crystal)是一种高分子材料,因为其特殊的物理、化学、光学特性,20世纪中叶开始广泛应用在轻薄型显示器上。
液晶显示器(Liquid Crystal Display,LCD)主要原理是以电流刺激液晶分子产生点、线、面并配合背部灯管构成画面。
现在来了解一下液晶的物理特性:LCD本身是不能发光的,它需要借助光源进行显示,即我们平时所说的背光。当光束通过这层液晶时,液晶本身会排排站立或扭转呈不规则状,因而阻隔或使光束顺利通过。
大多数液晶都属于有机复合物,由长棒状的分子构成。在自然状态下,这些棒状分子的长轴大致平行。将液晶倒入一个经精良加工的开槽平面,液晶分子会顺着槽排列,所以假如那些槽非常平行,则各分子也是完全平行的。
也就是说,若一个平面上的分子南北向排列,则另一平面上的分子东西向排列,而位于两个平面之间的分子被强迫进入一种90度扭转的状态。由于光线顺着分子的排列方向传播,所以光线经过液晶时也被扭转90度。但当液晶上加一个电压时,分子便会重新垂直排列,使光线能直射出去,而不发生任何扭转。
极化滤光器实际是一系列越来越细的平行线。这些线形成一张网,阻断不与这些线平行的所有光线。极化滤光器的线正好与第一个垂直,所以能完全阻断那些已经极化的光线。只有两个滤光器的线完全平行,或者光线本身已扭转到与第二个极化滤光器相匹配,光线才得以穿透。
所以通过这些特定方向的偏光片再施加电压就可以让部分区域光通过,另外部分区域光遮挡,这些明暗相间的点按照一定的像素排列起来的图像就是我们想要显示的信息了。
1602液晶显示模块内部包含驱动芯片为HD44780(HITACHI)或其他兼容芯片,内部提供了192种字符的库,用户可以直接调用。它可以显示两行字符,每行包括16个5×8点阵块组成的显示字符块,每个点阵块为一个字符位,字符间距和行距都为一个点的宽度。
接下来
LCD1602显示控制
了解LCD显示原理之后,那要怎样才能让它显示字符呢?这就要先了解其内部驱动芯片的特点和控制方式。单片机控制显示器驱动也是需要进行通信的,这里就又涉及到我们之前一直强调的时序了,上一节讲解uart时我们知道uart通信是要有严格的时序要求的,所以它才需要精准的波特率来控制,液晶显示器控制时序虽然不用像uart那样精准,但也需要一定的要求。我们先来看一下它的常用接口和引脚说明。
●VSS:电源地引脚。
●VDD:供电电源引脚。
●Vo:液晶显示偏压信号引脚,外加0 ~5V电压以调节显示对比度。
●RS:寄存器选择引脚,为高电平时选择数据寄存器;为低电平时选择指令寄存器。
●R/W:读、写操作选择引脚,高电平时为读操作;低电平时为写操作。
●E:使能信号引脚,低电平有效。
●DB0 ~ DB7:数据总线引脚,用于输入驱动1602液晶模块显示的数据。
●A:背光5V电源引脚。
●K:背光地信号引脚。
现在我们再来了解它的控制时序:
从图中可以看出,它的读写操作中RS,R/W,E三个控制引脚的时序变化是不一样的。并且数据与指令也有区别,这样就具体可以分为一下4种情况:
读状态——输入:RS=L,R/W=H,E=H;输出:D0~D7=状态字。
读数据——输入:RS=H,R/W=H,E=H;输出:无。
写指令——输入:RS=L,R/W=L,E=H,D0~D7=指令码,E=H;输出:D0~D7=数据。
写数据——输入:RS=H,R/W=L,E=H,D0~D7=数据,E=H;输出:无。
显示器内部驱动芯片带有80字节的RAM缓冲区,其地址对应如下:
但是我们知道显示屏界面做多只能显示16*2个字符,那它内部要怎么处理所有的缓冲区呢?
向图中的00H~0FH、40H~4FH地址中的任意处写显示数据时,液晶都可以立即显示出来;但写入到10H~27H或50H~67H地址处时,必须通过移屏指令将他们移入可显示区域才能正常显示。
显示器内部内置字符串分布表如下:
显示驱动的控制指令如下:
以上内容比较多,并且还有部分信息没有完全列出,这里也不一一列出了,使用时不用记忆,只需对照资料进行编程就好。
LCD1602显示示例
以上介绍了1602液晶显示器相关的主要内容,现在我们绘制一个简单的电路图再编程测试一下。
什么的电路中我们将显示器数据端口连接在P0上,其他3根控制引脚连接在P2.2~P2.4上。
现在我们编程让它来显示一些简单的字符:
/*
*这是一个LCD1602显示程序
*目的是通过显示屏显示一些字符
*/
#include
#include
#define DB1602 P0 //1602数据口
typedef unsigned char u8;
typedef unsigned int u16;
sbit rs_1602=P2^2;
sbit rw_1602=P2^3;
sbit en_1602=P2^4;
void delay(u8 ms);
void lcd1602_check_busy();
void Write_Byte_1602(u8 Byte,bit dat);
void lcd1602_Init();
void Write_char1_1602(bit x,u8 y,u8 dat1);
void Write_string_1602(bit x,u8 y,u8 *str);
void main(void)
{
lcd1602_Init();
Write_string_1602(0,0," Hello guy!");
Write_char1_1602(1,6,'-');
Write_string_1602(1,7,"--LCD1602");
while(1)
{
}
}
void delay(u8 ms)
{
u8 i,j;
for(i=0; i< ms; i++)
{
for(j=0; j< 110; j++)
{
;
}
}
}
void lcd1602_check_busy()
{
u8 busy;
bit via;
do
{
rs_1602=0;
rw_1602=1;
DB1602|=0xf0;
en_1602=1;
busy=DB1602;
en_1602=0;
en_1602=1; //
en_1602=0; //
via=(bit)(busy&0x80);
}while(via);
}
void Write_Byte_1602(u8 Byte,bit dat)
{
lcd1602_check_busy(); //忙则等待
rs_1602=dat; //数据命令选择位
rw_1602=0;
en_1602=1;
DB1602=Byte;
_nop_();
en_1602=0;
}
void lcd1602_Init()
{
Write_Byte_1602(0x38,0); //设置16×2显示,5×7点阵,8位数据接口
Write_Byte_1602(0x08,0);
Write_Byte_1602(0x01,0); //显示清屏
Write_Byte_1602(0x06,0); //显示光标移动设置
Write_Byte_1602(0x0c,0); //显示开及光标设置
}
void Write_char1_1602(bit x,u8 y,u8 dat1)
{
if(x==0)
{
Write_Byte_1602(0x80+y,0);
}
else
{
Write_Byte_1602(0xc0+y,0);
}
//dat1+=0x30;
Write_Byte_1602(dat1,1);
}
void Write_string_1602(bit x,u8 y,u8 *str)
{
if(x==0)
{
Write_Byte_1602(0x80+y,0);
}
else
{
Write_Byte_1602(0xc0+y,0);
}
while(*str)
{
Write_Byte_1602(*str,1);
str++;
}
}
这段代码看起来比原来的程序都复杂一点,但还是一些比较基础的内容,所以大家先自己理解一下,不理解地方可以先看一下资料,这段程序中使用到了我之前没提到过的内容——指针,后面我会单独列出出来进行讲解。
评论
查看更多