LCD12864等液晶接口的设计本文介绍了图形液晶显示器MGLS12864与单片机W78E58的硬件设计和软件设计技术。同时给出了ASCII码8×16字库、汉字16×16字库建立的程序及在液晶上显示数字、字符和汉字的程序。引言液晶显示器(LCD)具有功耗低、体积小、重量轻、超薄等许多其它显示器无法比拟的优点,近几年来被广泛用于单片机控制的智能仪器、仪表和低功耗电子产品中。LCD可分为段位式LCD、字符式LCD和点阵式LCD。其中,段位式LCD和字符式LCD只能用于字符和数字的简单显示,不能满足图形曲线和汉字显示的要求;而点阵式LCD不仅可以显示字符、数字,还可以显示各种图形、曲线及汉字,并且可以实现屏幕上下左右滚动,动画功能,分区开窗口,反转,闪烁等功能,用途十分广泛。本文介绍了点阵式液晶显示器MGLS12864与单片机的接口及编程的方法,同时介绍了创建8×16字符和16×16点阵汉字的方法,及常用的字符显示和汉字显示程序。硬件设计这里着重介绍液晶显示器与单片机的接口技术。有关MGLS12864图形液晶引脚功能及控制器HD61202的接口时序波形,可查看图形液晶显示器产品有关手册。单片机可以通过数据总线与控制信号直接采用存储器访问形式、I/O设备访问形式控制该液晶显示模块。本文以华邦公司的W78E58为例,它是51系列单片机兼容的微控制器,其内部有32KB的FLASHEEPROM,用户编制的程序及需要显示的英文字母、数字、汉字、曲线和图形都可以存储在里面,免去了扩展外部存储器的麻烦,使得以W78E58单片机为核心的控制系统电路更简单。因此十分适用于液晶显示。MGLS12864与W78E58单片机接口电路如图1所示。该图采用直接访问方式,单片机通过低位地址A2控制CSA;A3控制CSB,以选通液晶显示屏上各区的控制器HD61202;同时W78E58用地址A1作为R/W信号控制数据总线的数据流向;用地址A0作为D/I信号控制寄存器的选择;E信号由W78E58的读信号/RD和写信号/WR合成产生;另外单片机的复位脚(9脚)经反相器后连接到液晶显示器复位脚(17脚/RST),当单片机上电复位或手动复位时,液晶显示器同时也复位;从而实现了W78E58对内置HD61202图形液晶显示器模块的电路连接。电路中LCD电源控制端VO是用来调节显示屏灰度的,调节该端的电压,可改变显示屏字符、图形的颜色深浅。单片机对液晶显示模块的操作可分为两部分,即左半屏和右半屏操作。下面是根据图1的连接确定对应左半屏(前64×64)和右半屏(后64×64)操作地址:CWADR1EQU0004H左半屏写指令代码地址DWADR1EQU0005H左半屏写显示数据地址CRADR1EQU0006H左半屏读状态字地址DRADR1EQU0007H左半屏读显示数据地址CWADR2EQU0008H右半屏写指令代码地址DWADR2EQU0009H右半屏写显示数据地址CRADR2EQU000AH右半屏读状态字地址DRADR2EQU000BH右半屏读显示数据地址图1MGLS12864与W78E58接口图软件设计液晶控制器HD61202一共有七条指令,从作用上可分为两类,显示状态设置指令和数据读/写操作指令。详见指令系统可查看图形液晶显示器产品有关手册。显示起始行设置中L5~L0为显示起始行的地址,取值在0-3FH(1-64行)范围内。页面地址设置中P2-P0为选择的页面地址,取值范围为0-7H,代表1-8页。列地址设置中C5-C0为Y地址计数器的内容,取值在0-3FH(1-64行)范围内。显示器上128点×64点,每8点为一字节数据,都对应着显示数据RAM(在HD61202芯片内),一点对应一个bit,计算机写入或读出显示存储器的数据代表显示屏上某一点列上的垂直8点行的数据。D0代表最上一行的点数据,D1为第二行的点数据,…….,D7为第八行的点数据。该bit=1时该点则显示黑点出来,该bit=0时该点则消失。另外LCD指令中有-条displayON/OFF指令,displayON时显示RAM数据对应显示的画面;displayOFF则画面消失,RAM中显示数据仍存在。点阵字模文件的建立:由于MGLS12864液晶显示器没有内部字符发生器,所以在屏幕上显示的任何字符、汉字等须自己建立点阵字模库,然后均按图形方式进行显示。由于HD61202显示存储器的特性,不能将计算机内的汉字库和其它字模库提出直接使用,需要将其旋转90度后再写入。点阵字模库建立包括以下几个方面:(1)建立8×16点阵常用字符、数字、符号字模库。可选用计算机BIOS中ASCII的8×16字模库,所有字符按照ASCII值从小到大升序排列。asm{movax,1130h/*AH=11h—功能调用。装入字库至软字库*/movbh,6/*AL=30h取点阵信息*/int10h/*BH=6取ROM8X16点阵指针(VGA)*/movax,es/*出口:ES:BP指向字库指针*/movascii_es,axmovax,bpmovascii_bp,ax};ascii_offset=ascii_bp+16*asciicode;for(j=0;j16;j++)buf[j]=peekb(ascii_es,ascii_offset+j);/*读16字节点阵数据*/for(m=0;m16;m++)/*点阵数据转换成LCD格式数据*/{if(m8){beginbyte=7;shiftn=7;}else{beginbyte=15;shiftn=15;}for(j=0;j8;j++)ascii8x16[m]=(ascii8x16[m]+(buf[beginbyte-j](shiftn-m))&0x01)1;}也可选用UCDOS的ASC16文件做字模库。ASC16文件的字符为8×16点阵。所有字符按照ASCII值从小到大升序排列。计算字符首地址的公式:字符首地址=字符的ASCII码值×16+字模库首地址。(2)建立所用到的16×16点阵字模库。汉字字符可选用UCDOS的HZK16文件做字模库。HZK16文件的字符为16×16点阵。所有字符按照区位码从小到大升序排列。计算汉字字符首地址的公式如下:汉字首地址=((区码-1)×94+位码-1)×32。作者用C语言编写的读取UCDOS点阵字库字模程序,完成字模读取、数据重新排列,并按MCS-51汇编程序的要求写成相应格式的文本文件。p=((quma-1)*94+weima-1)*32;cclibfile=fopen(HZK16,rb);fseek(cclibfile,(long)p,SEEK_SET);fread(buf,sizeof(unsignedchar),32,cclibfile);/*读32字节点阵数据*/for(m=0;m32;m++){/*点阵数据转换成LCD格式数据*/if(m8){beginbyte=14;shiftn=7;}elseif(m=8&&m16){beginbyte=15;shiftn=15;}elseif(m=16&&m24){beginbyte=30;shiftn=23;}else{beginbyte=31;shiftn=31;}for(j=0;j8;j++)hzk16x16[m]=(hzk16x16[m]+(buf[beginbyte-2*j](shiftn-m))&0x01)1;}(3)常用图形(如产品商标等)的点阵图形的建立。对已有的图形可采用扫描仪进行扫描,然后用图形处理软件进行处理,再将BMP格式文件转换成MCS-51的汇编文件的格式。以上所有的字模数据都存放在单片机W78E58的程序存储器中,如用到的汉字、图形较多,可选用较大容量的程序存储器。通用子程序:通用子程序分左半屏、右半屏写指令代码子程序和写显示数据子程序。液晶显示驱动器HD16202内部有个忙标志寄存器,当BF=1时,表示内部操作正在运行,不能接受外部数据或指令。下面子程序中设指令代码寄存器为COMM,数据寄存器为DATA。(COMMEQU20H/*指令寄存器*/DATAEQU21H/*数据寄存器*/)(1)左半屏写指令子程序WR_CMD1:MOVDPTR,#CRADR1;/*读状态字口地址*/WAIT1:MOVXA,@DPTR;/*读状态字*/JBACC.7,WAIT1;/*判忙标志BF,如BF=1忙,等待*/MOVDPTR,#CWADR1;/*写指令字口地址*/MOVA,COMM;/*取指令代码*/MOVX@DPTR,A;/*写指令代码*/RET(2)左半屏写数据子程序WR_DATA1:MOVDPTR,#CRADR1;/*读状态字口地址*/WAIT11:MOVXA,@DPTR;/*读状态字*/JBACC.7,WAIT11;/*判忙标志BF,如BF=1忙,等待*/MOVDPTR,#DWADR1;/*写数据字口地址*/MOVA,DATA;/*取数据/MOVX@DPTR,A;/*写数据*/RET(3)右半屏写指令子程序WR_CMD2和右半屏写数据子程序WR_DATA2的编制同左半屏子程序相同,只是对应口地址不同。8X16字符显示子程序:MGLS12864液晶显示屏由二片HD61202控制,LCD显示中应尽量避免一个字符一半在左半屏显示,另一半在右半屏显示的情况。设列地址寄存器为COLUMN,页地址寄存器为PAGE,要显示的字符代码寄存器为ASCIICODE,W78E58内RAM28H-RAM37H共16个字节存放8×16的点阵数据,生成的8×16点阵库文件存放在单片机W78E58存储器中的首地址定义为ASCII_DOT816。DISP_ASCII816:MOVDPTR,#ASCII_DOT816;8×16点阵库首地址MOVA,ASCIICODE;显示字符代码ASCIICODEMOVB,#16;每个字符点阵占16个字节MULAB;计算显示字符在字库的首地址ADDA,DPLMOVDPL,AMOVA,DPHADDCA,BMOVDPH,A;MOVR0,#28H;将点阵数据放到RAM28H-RAM37HMOVR2,#00HLP_MOVDOT16:MOVA,R2MOVCA,@A+DPTRMOV@R0,A;如要将字符反显(黑底白字),则读出点INCR0;阵数据后求反放入单片机的RAM中INCR2CJNER2,#16,LP_MOVDOT16;PUSHCOLUMNMOVA,COLUMN;显示列数COLUMN是否在右半屏CJNEA,#64,ASCII_IF64ASCII_IF64:JNCASCII_YGE64MOVDPTR,#CWADR1;在左半屏时,选择左半屏写指令代码地址CLRFIRST0_SECOND1_BIT;左半屏列数标志BIT=0SJMPALL_COLUMNASCII_YGE64:CLRCSUBBA,#64MOVCOLUMN,AMOVDPTR,#CWADR2;在右半屏时,选择右半屏写指令代码地址SETBFIRST0_SECOND1_BIT;右半屏列数标志BIT=1ALL_COLUMN:MOVA,PAGEADDA,#10111000B;设置页地址命令MOVX@DPTR,AMOVA,COLUMN;设置列地址命令ADDA,#01000000BMOVX@DPTR,AMOVDPTR,DWADR1;根据左右半屏列数标志,选择写显示数据地址JNBFIRST0_SECOND1_BIT,ALLMOV1MOVDPTR,DWADR2ALLMOV1:MOVR0,#28HMOV_8BYTE1:MOVA,@R0MOVX@DPTR,A;写显示数据NOPINCR0CJNER0,#30H,MOV_8BYTE1;MOVDPTR,#CWADR1JNBFIRST0_SECOND_BIT,ALLMOV2MOVDPTR,#CWADR2ALLMOV2:MOVA,PAGEINCA;页地址加1ADDA,#10111000BMOVX@DPTR,A;设置页地址命令MOVA,COLUMN;设置列地址命令ADDA,#