欢迎光临散文网 会员登陆 & 注册

51单片机编程开发(十)之液晶显示

2022-08-01 21:16 作者:落木青云  | 我要投稿

显示屏

前面我们介绍数码管时讲到过显示器在单片机应用中是非常常见的,数码管是最基础的一种显示器。现在的人机交互场景中显示器是比按键更常见的一种工具,因为带有触摸屏的显示器在很多地方都能取代按键。这一点通过对比现在的手机和十几年的手机就可以看出来了。我们前面说过当我们使用少数几个数码管时是可以使用单片机IO口直接驱动显示的,但需要显示众多内容时如果单纯靠单片机驱动就可能不合适了,一方面是占用太多IO口,造成单片机资源浪费,另一方面是,数码管都是通过LED点亮的,比较耗能。基于这些现实显示驱动应运而生,同时一些带有显示驱动的单片机也随着出现,另外更多新型的显示器也不断出现,又促成各种显示驱动芯片推陈出新。像GPU,显卡这样的高级模块就是为复杂显示而生,当然这里面又涉及到显示器的发展历史,内容过于丰富,就不细说,有兴趣的朋友可以去了解一下。

今天我们要介绍的主角——LCD1602液晶屏,它是一种点阵液晶屏,与数码管相比它能显示更多内容,也相对节能。当然它是一种单色屏,相较于电视,电脑,手机等彩屏肯定就显得单调了。并且在项目开发过程中我们用到LCD1602液晶屏的概率是微乎其微,但它又确实是入门学习不可缺少的一部分。万变不离其宗,我们能掌握使用它的方法后上手其他显示屏就容易了。以后若做手机,电脑等应用端开发时都不用你接触底层显示原理,早有现成的驱动,也会有人负责UI,你直接调用就好了。当然这是另外一码事了,做单片机开发肯定还是会使用到各种屏幕的。另外工作的过程中你可能还会遇到一种液晶屏——段码液晶屏,它更像是数码管和液晶屏的结合体,因其在价格,能耗与制作工艺方面具备优势,所以应用非常广泛,具体内容我们以后再单独做介绍。网络上有各种屏幕的图片,想提前了解的初学者可以自行搜索一下,我这里就暂不做过多说明了。接下来我们先来了解一下LCD1602液晶屏的工作原理。

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 <reg52.h>

#include <intrins.h>


#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++;

 }

}

这段代码看起来比原来的程序都复杂一点,但还是一些比较基础的内容,所以大家先自己理解一下,不理解地方可以先看一下资料,这段程序中使用到了我之前没提到过的内容——指针,后面我会单独列出出来进行讲解。

结语:

今天这篇文章我们将1602显示器的使用做了一个简单的讲解,51单片机的基础应用部分知识就介绍完了,后面我们再介绍一些其他扩展功能。如果需要程序源码或仿真电路图文件的朋友可以私信,我将会整理一份资料包进行共享。

51单片机编程开发(十)之液晶显示的评论 (共 条)

分享到微博请遵守国家法律