单片机是如何控制LCD模块的以及液晶显示模块与单机片的接口技术
写寄存器函数(LCD_RegWrite)
数据写函数(LCD_DataWrite)
数据读函数(LCD_DataRead)
这三个函数需要严格的按照 LCD 所要求的时序来编写,下面可以看看 MzL02 模块时序图:
MzL02 模块的 6800 时序示意
注意:上图是该模块的控制 IC 资料中的原版时序图,其实有些示意不是太稳妥(少标出了RW 线信号的要求),或者说是不太严谨,不过这些不作讨论,请看分析即可;而 EP 的有效触发沿在图中很有可能示意有误,实测为上升沿。图中 CS1B(CS2)的信号即为片选 CS,RS 即为数据/寄存器的选择端口 A0 信号,E 为 EP;当作写入寄存器数据操作时,首先要将 A0 置低,以通知 LCD 模块即将进行的是对寄存器的操作;而 RW 线需要置低,以示即将要进行的是写入的操作;然后片选 CS 信号置低,装载数据至总线,然后在 EP 线上产生一个上升沿以触发 LCD 模块将总线上的数据最终载入;在前面的操作完成后一般都会将各个信号线的状态恢复。而数据(显存)写入、数据读出的操作时序也比较类似,这里就不多作介绍,直接参考例程即可。
//=======================================================
// 函数: void LCD_RegWrite(unsigned char Command)
// 描述: 写一个字节的数据至 LCD 中的控制寄存器当中
// 参数: Command 写入的数据,低八位有效(byte)
// 返回: 无
//======================================================
void LCD_RegWrite(unsigned char Command)
{
LCD_A0 = 0; //A0 置低,示意进行寄存器操作
LCD_RW = 0; //RW 置低,示意进行写入操作
LCD_EP = 0; //EP 先置低,以便后面产生跳变沿
LCD_CS = 0; //片选 CS 置低
DAT_PORT = Command; //装载数据置总线
LCD_EP = 1; //产生有效的跳变沿
LCD_CS = 1; //片选置高
}
数据写入以及读出的函数源码如下:
//==========================================================
// 函数: void LCD_DataWrite(unsigned char Dat)
// 描述: 写一个字节的显示数据至 LCD 中的显示缓冲 RAM 当中
// 参数: Data 写入的数据
// 返回: 无
//==========================================================
void LCD_DataWrite(unsigned char Dat)
{
LCD_A0 = 1; //A0 置高,示意进行显存数据操作
LCD_RW = 0; //RW 置低,示意进行写入操作
LCD_EP = 0; //EP 先置低,以便后面产生跳变沿
LCD_CS = 0; //片选 CS 置低
DAT_PORT = Dat; //装载数据置总线
LCD_EP = 1; //产生有效的跳变沿
LCD_CS = 1; //片选置高
}
//=========================================================
// 函数: unsigned char LCD_DataRead(void)
// 描述: 从 LCD 中的显示缓冲 RAM 当中读一个字节的显示数据
// 参数: 无
// 返回: 读出的数据,
//==========================================================
unsigned char LCD_DataRead(void)
{
unsigned char Read_Data;
DAT_PORT = 0xff; //51 的端口想要输入前,要先给端口全置 1
LCD_A0 = 1; //A0 置高,示意进行显存数据操作
LCD_RW = 1; //RW 置高,示意进行读出操作
LCD_EP = 0; //EP 先置低,以便后面产生跳变沿
LCD_CS = 0; //片选 CS 置低
LCD_EP = 1; //产生有效的跳变沿
LCD_EP = 0;
Read_Data = DAT_PORT; //读出数据
LCD_CS = 1; //片选置高
return Read_Data; //返回读到的数据
}
以上便是要介绍的最基本的时序操作程序,它们几乎是整个 LCD 驱动程序当中与底层硬件打交道的代码了,这样的话,当要改变驱动 LCD 的 MCU 端口时或者换用别的 MCU 来驱动 LCD 时,基本上只需要在这些代码里作一下修改即可。
关于读 LCD 状态
而在一般的 LCD 模块当中,还有一个功能同样重要,就是读 LCD 状态;可以通过此操作获取当前 LCD 模块的忙状态以及一些相关的状态信息,当 LCD 模块正处于忙状态时,则不宜对它进行数据的写入或读出操作(有很多较老式的 LCD 控制器规定在忙的状态下时不允许写入或读出数据)。
所以在很多 LCD 的驱动程序当中,会在寄存器写入、数据写入/读出的操作前加入读取 LCD状态并判别忙状态的代码;这点可以参考网上流传的很多 LCD 驱动程序。不过,对于 MzL02这样的较新出的 LCD 控制器来说,已经对忙状态不是很在乎了,或者说影响已经很小甚至没有了;所以我们在前面的代码当中并没有加入这样的代码。至于有没有必要加读状态判忙的代码,要视具体的 LCD 控制器而定。
关于时序的时间要求
时序的一个非常重要的数据就是类似上图中标出的tAS88之类的时间长短要求,只是上图中并没有标出它们的具体最大最小值要求而已;但在编写这类的时序接口程序时它们还是非常重要的,当然还要看 MCU 的端口操作速度以及 MCU 的指令执行速度。打个比方,有的时序里就会有要求某些信号的电平保持最小宽度,而如果 MCU 的指令执行速度以及端口操作速度非常快的话,就需要酌情在连续操作端口的代码之间加入适量的延时(通用用空操作来代替,具体多少个多少时长视具体的 MCU 以及 LCD 控制器而定)以保证该信号的脉冲宽度满足要求。
液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。 字符型液晶模块是一种用5x7点阵图形来显示字符的液晶显示器,根据显示的容量可以分为1行16个字、2行16个字、2行20个字等等,这里以常用的2行16个字的dm-162液晶模块来介绍它的编程方法,dm-162采用标准的14脚接口,其中vss为地电源,vdd接5v正电源,v0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10k的电位器调整对比度。rs为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。rw为读写信号线,高电平时进行读操作,低电平时进行写操作。当rs和rw共同为低电平时可以写入指令或者显示地址,当rs为低电平rw为高电平时可以读忙信号,当rs为高电平rw为低电平时可以写入数据。e端为使能端,当e端由高电平跳变成低电平时,液晶模块执行命令。d0~d7为8位双向数据线。
dm-162液晶模块内部的字符发生存储器(cgrom)已经存储了160个不同的点阵字符图形,如表1所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“a”的代码是01000001b(41h),显示时模块把地址41h中的点阵字符图形显示出来,我们就能看到字母“a” dm-162液晶模块内部的控制器共有11条控制指令,如表2所示,它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1为高电平、0为低电平) 指令1:清显示,指令码01h,光标复位到地址00h位置 指令2:光标复位,光标返回到地址00h 指令3:光标和显示模式设置 i/d:光标移动方向,高电平右移,低电平左移 s:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效 指令4:显示开关控制。
d:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 c:控制光标的开与关,高电平表示有光标,低电平表示无光标 b:控制光标是否闪烁,高电平闪烁,低电平不闪烁 指令5:光标或显示移位 s/c:高电平时移动显示的文字,低电平时移动光标 指令6:功能设置命令 dl:高电平时为4位总线,低电平时为8位总线 n:低电平时为单行显示,高电平时双行显示
f: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符 指令7:字符发生器ram地址设置 指令8:ddram地址设置 指令9:读忙信号和光标地址 bf:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。 指令10:写数据 指令11:读数据 dm-162液晶显示模块可以和单片机at89c51直接接口,电路如图1所示。 液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,
是dm-162的内部显示地址,比如第二行第一个字符的地址是40h,那么是否直接写入40h就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位d7恒定为高电平1所以实际写入的数据应该是01000000b(40h)+10000000b(80h)=11000000b(c0h) 以下是在液晶模块的第二行第一个字符的位置显示字母“a”的程序: rs equ p3.7 rw equ p3.6 e equ p3.5 org 0000h mov p1,#00000001b ;清屏 acall enable mov p1,#00111000b ;8位2行5x7点阵 acall enable mov p1,#00001111b ;显示器开、光标开、闪烁开 acall enable mov p1,#00000110b ;文字不动,光标自动右移 acall enable mov p1,#0c0h ;写入显示起始地址(第二行第一个位置) acall enable mov p1,#01000001b ;字母a的代码 setb rs ;rs=1 clr rw ;rw=0 clr e ;e=0 acall delay setb e ;e=1 ajmp $ enable: clr rs ;写入控制命令的子程序 clr rw clr e acall delay setb e ret delay: mov p1,#0ffh ;判断液晶显示器是否忙的子程序 clr rs setb rw clr e nop setb e jb p1.7,delay ;如果p1.7为高电平表示忙就循环等待 ret end
随着科技的发展,液晶显示模块的应用前景更加广阔,目前已广泛应用于电子表、计算器、液晶电视机、便携式电脑、掌上型电子玩具、复印机、传真机等许多方面。
液晶显示(LCD)大体分为笔段型、字符型、点阵图形型等几大类,字符型液晶显示模块是一类专门用于显示字母、数字、符号等的点阵型液晶显示模块,它是由若干个5×7或5×11等点阵字符组成。每一个点阵字符位都可以显示一个字符,点阵字符位之间的一个点距的间隔起字符间距和行距的作用。目前市面上常用的有16字×1行、16字×2行、20字×2行和40字×2行等字符模型,这些LCD虽然显示的字数各不相同,但是都具有相同的输入输出界面。本文介绍的TC1602A是一种16字×2行的字符型液晶显示模块,其显示面积为64.5×13.8mm2。
1TC1602A的引脚功能和内部结构
1.1TC1602A的引脚功能
TC1602A的引脚排列如图1所示,它有16个引脚可与外界相连,各引脚功能如下:
1脚VSS:接地;
2脚Vdd:接+5V电源;
3脚VO:对比度调整端,LCD驱动电压范围为Vdd~VO。当VO接地时,对比度最强;
4脚RS:寄存器选择端,RS为0时,选择命令寄存器IR;RS为1时,选择数据寄存器DR;
5脚:读写控制端,为1时,选择读出;为0时,则选择写入;
6脚Enable:使能控制端,Enable为1时,使能;Enable为0,禁止;
7脚~14脚D0~D7:数据总线;
15脚LED+:背景光源,接+5V;
16脚LED-:背景光源,接地。
1.2TC1602A的内部结构
TC1602A的内部结构如图2所示,它主要由DDRAM、CGROM、CGRAM、IR、DR、BF、AC等大规模集成电路组成。
DDRAM为数据显示用的RAM(DataDisplayRAM,简称DDRAM),用以存放要LCD显示的数据,只要将标准的ASCII码放入DDRAM,内部控制线路就会自动将数据传送到显示器上,并显示出该ASCII码对应的字符;
CGROM为字符产生器ROM(CharacterGeneratorROM,简称CGORM),它存储了192个5×7的点阵字型,但只能读出不能写入;
CGRAM为字型、字符产生器的RAM(CharacterGeneratorRAM,简称CGRAM),可供使用者存储特殊造型的造型码,CGRAM最多可存8个造型;
IR为指令寄存器(InstructionRegister,简称IR),负责存储MCU要写给LCD的指令码,当RS及R/W引脚信号为0且Enable引脚信号由1变为0时,D0~D7引脚上的数据便会存入到IR寄存器中;
DR为数据寄存器(DataRegister,简称DR),它们负责存储微机要写到CGRAM或DDRAM的数据,或者存储MCU要从CGRAM或DDRAM读出的数据。因此,可将DR视为一个数据缓冲区,当RS及R/W引脚信号为1且Enable引脚信号由1变为0时,读取数据;当RS引脚信号为1,R/W引脚信号为0且Enable引脚信号由1变为0时,存入数据;
BF为忙碌信号(BusyFlag,简称BF),当BF为1时,不接收微机送来的数据或指令;当BR为0时,接收外部数据或指令,所以,在写数据或指令到LCD之前,必须查看BF是否为0;
TC1602A可分2行共显示32个字符,每行显示16个字符。
2TC1602A的控制指令
TC1602A的控制指令共11条,其中9条是针对命令寄存器IR的,另外2条是针对数据寄存器DR的,具体指令如表1所列。需要说明的是:表中*表示可以为0或1,表中的相关命令字设置如下:
3TC1602A相关的子程序
TC1602A与单片机AT89C51的接口电路如图3所示,下面是TC1602A相关的子程序:
(1)查看忙碌信号子程序
(4)清TC1604A显示器子程序
LCR:
MOVA,#00000001B
CALLWtoiR
RET
(5)启动TC1602A子程序
当供电电源符合一定要求时,TC1602A通电后能自启动,并进入默认置。TC1602A自启动后,单片机(MCU)只要依照系统所需的功能重新对其下达功能设定指令、显示器开/关控制指令及进入模式设定指令即可。通过下面的子程序可以让TC1602A5×7的字型显示器显示2行8bit数据,同时显示光标但不闪烁,且可在每一次资料输入DDRAM后光标向右移动一格。
责任编辑:Davia
【免责声明】
1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。
2、本文的引用仅供读者交流学习使用,不涉及商业目的。
3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。
4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。
拍明芯城拥有对此声明的最终解释权。