基于不带字库的图形LCD模块汉字显示解决方案
基于不带字库的图形LCD模块汉字显示解决方案
摘要 针对不带汉字字库的图形点阵液晶模块的系统,嵌入GB2312-80字库芯片,利用国标区位码和液晶模块的特点实现汉字和西文字符的混合显示。本文介绍了汉字机内码与区位码的相互转换关系,以及利用T6963C作控制器的液晶模块YJ240D的基本原理,探讨了实际应用中此类液晶模块在嵌入式仪器仪表中混合显示的硬件设计和软件实现方法。
关键词 液晶模块 区位码 汉字字模库
引言目前,在嵌入式智能仪器仪表中,常用的LCD模块一般不带有字库,而实际应用中的人机界面需要显示汉字,如果直接把汉字点阵字库放在程序空间需要占有大量的程序空间,并且字库不一定完整。本文以深圳莱德电子的LCD显示模块YJ240D和国标汉字库GB2312-80为例,介绍了一种基于无汉字字库的图形LCD模块汉字显示的解决方案。
1 单片机与液晶模块的接口
1.1 YJ240D的基本结构
YJ240D是一款图形点阵液晶显示模块,它由控制器T6963C、行驱动器、列驱动器及240×128全图形点阵液晶显示器组成。可显示常用字符及图形,也可以显示15×8个(16×16点阵)汉字,内带32K显示缓冲数据存储器,可储存八屏图形显示数据。5V单电源供电,模块内带负压发生器,用于驱动LCD,内带LED背光,通过调节VLCD的电压可以调节液晶的对比度。
T6963C 是日本东芝公司专门为中等规模LCD模块设计的一款控制器,它通过外部MCU方便地实现对LCD驱动器和显示缓存的管理。其特点为8位总线,内部有128个常用字符表,可管理外部扩展显示缓存64KB(本模块为32KB),并具有丰富的指令供MCU实现对LCD显示屏幕的操作与编辑
YJ240D接口简单,可通过软件编程方便地对液晶控制,其硬件接口定义如表1
表1 YJ240D的硬件接口
引脚编号 |
标号 |
电平 |
功能描述 |
1 |
A (LED+) |
- |
LED背光正电源输入端(+5V) |
2 |
K (LED-) |
0V |
LED 接地端 |
3 |
VSS |
0V |
信号地 |
4 |
VDD |
+5V |
逻辑和LCD正驱动电源信号地 |
5 |
VLCD |
-10V<VLCD<VDD |
对比度调节输入(内部负压时空接) |
6 |
\WR |
L |
写信号 |
7 |
\RD |
L |
读信号 |
8 |
\CE |
L |
片选信号 |
9 |
C\D |
H/L |
指令/数据选择(H: 指令 L:数据) |
10 |
RES |
L |
复位 |
11 |
DB0 |
H/L |
数据总线0 (三态数据总线) |
12 |
DB1 |
H/L |
数据总线1 |
13 |
DB2 |
H/L |
数据总线2 |
14 |
DB3 |
H/L |
数据总线3 |
15 |
DB4 |
H/L |
数据总线4 |
16 |
DB5 |
H/L |
数据总线5 |
17 |
DB6 |
H/L |
数据总线6 |
18 |
DB7 |
H/L |
数据总线7 |
19 |
FS |
H/L |
字体选择 (H:6X8 点;L:8X8 点,图形方式时接低) |
20 |
VEE |
-15V |
内部负压输出 |
1.2 YJ240D与单片机的接口
图1为单片机和液晶显示器的接口示意图,其中用单片机的P1.2、P1.3来控制液晶模块的片选(CE)和指令/数据选择(C/D);P0口与液晶的8位数据线(P0-P7)相接;读(WR)写(RD)线分别与MCU的读写线相连。
1.3 YJ240D的读写时序
该液晶模块与MCU的接口采用八位并行数据线,可交换命令和数据。向液晶模块写时,如果C/D为高,表示向液晶模块传输命令;如果C/D为低,表示向液晶模块传输数据。当从液晶读时,C/D必须为高,读出的值为模块内的状态字。
液晶模块的详细命令集可参见T6963C数据手册。
2 字库芯片与单片机的接口
2.1 汉字的编码标准
为了用0、1代码串表示汉字,规定了汉字的信息交换码:GB 2312-80,简称国标码,共有字符7445个,包括汉字和其他字符。一级汉字3755个,按汉语拼音顺序排列;二级汉字3008个,按部首和笔画排列。其他字符有常用符号、序号、GB1988图形字符集、希腊字符、制表符等。国标码的每一个符号都用两个字节(16位二进制)代码来表示一个汉字。
1) 国标码:行、列各94(0-93),用先行后列的两个7位二进制数表示。
2) 区位码:由于二进制国标码表示不很方便,因此汉字也可用十进制区位码表示。区、位各94(1-94),用先区后位的两个2位十进制数表示。
3) 机内码:是计算机内部表示汉字的代码,在微机中多用两字节(最高位为1)代码作为机内码。
2.2区位码和机内码的相互转换
西文系统的交换码和机内码都采用美国标准信息交换码ASCII,用一个字节表示,一般只用低七位,可以表示128可符号。在软件中嵌入的汉字经编译器编译后存放的格式为机内码。区位码和机内码之间的转换关系可概括为:(区位码的十六进制表示)+A0A0H=机内码。以汉字“大”为例,“大”字的区内码的十六进制表示为1453H,加上A0A0H得到机内码为B4F3H。
2.3 汉字字模库
汉字的输出是将汉字的笔划离散化,用点阵来表示。点阵的中每个点位只有两种状态:有笔画(1)、无笔画(0)。
描述汉字点阵信息的二进制代码集称为汉字的字模。所有汉字和符号的点阵信息就组成了汉字库。
2.3 混合字符的显示
在本系统中,每个汉字的显示采用16×16图形点阵方式显示。国标GB2312-80一、二级汉字点阵库存放在一片ROM芯片AT27C040中,每个汉字占用32个字节。当需要显示汉字时,首先根据区码和位码计算出该汉字点阵在ROM中存放的起始地址,然后从此地址连续的取出32个字节的汉字点阵,并写入LCD模块对应的地址中,就可以显示出该汉字。根据汉字区位码和该汉字计算汉字在字库ROM位置的转换关系可概括为:起始地址=(区码×94+位码)×32
在应用中,常需要汉字和英文字符混合显示,在软件处理时需要判断显示的内容是汉字的编码还是英文字符的编码,如果是汉字编码则根据其机内码计算区位码,并根据区位码计算出该汉字在字模中的起始地址。图3是混合显示的软件流程图。
图3 汉字和英文字符混合显示软件流程图
3 应用实例
在某检测设备中,需要给用户显示电流、电压、频率值以及一些事件记录等。用户的命令通过设备的8键键盘输入,显示的内容有汉字、数字和英文字符。
以下列出了显示汉字、数字和英文字符串部分软件
/*-----------------------------------------------------------------------------------------
混合显示一串汉字和英文字符
row:行(1-8), column: 列(1-15)
str:字符代码(标准机内码)指针
---------------------------------------------------------------------------------------*/
void DispStr(unsigned char row, unsigned char column, unsigned char *str)
{
while (*str)
{
if (*str > 0xa0) //如果是汉字机内码
{
if (column == 30) //如果是最后一列,则换行
{
row ++;
column = 1;
}
DispHZ(row, column, str); //显示一个汉字
column += 2;
str += 2;
}
else //如果是英文字符
{
DispChar(row * 2, column, str); //显示一个英文字符
column++;
str++;
}
}
/*----------------------------------------------------------------
在指定位置显示一个汉字(16*16点阵)
row:行(1-8), column: 列(1-29)
str:汉字标准机内码指针
LINE_CHAR = 30 一行的字符数
-----------------------------------------------------------------*/
void DispHZ(unsigned char row, unsigned char column, unsigned char *str)
{
unsigned char idata i, hz_buf[32];
unsigned int StartAddr;
//定位起始行
StartAddr = (((row - 1) * 16) * LINE_CHAR + (column-1)) + 0x4000;
GetMatrix(str, hz_buf);
for (i = 0; i < 16; i++)
{
LCDInData( (unsigned char) (StartAddr) );
LCDInData( (unsigned char) (StartAddr>>8) );
LCDInCmd(0x24);
LCDInData(hz_buf[i * 2]);
LCDInCmd(0xc0);
LCDInData(hz_buf[i * 2 + 1]);
LCDInCmd(0xc4);
StartAddr += LINE_CHAR;
}
}
/*-----------------------------------------------------------------------------------
从字库芯片中取汉字字模数据
s: 汉字标准机内码指针
hz_buf: 存放汉字字模数据缓冲区指针
-------------------------------------------------------------------------------------*/
void GetMatrix(unsigned char *s, unsigned char *hz_buf)
{
unsigned char i ,j, k;
unsigned long address;
for (k = 0; k < 31; k++)
{
i = *s - 0xA1; //计算区码
j = *(s + 1) - 0xA1; //计算位码
address = (((unsigned long)i * 94) + j)*32 + k; //计算该汉字在字模芯片中的起始位置
high_addr = 1;
P0 = (unsigned char) (address >> 16); //送高位地址
high_addr = 0;
P0 = 0xff;
zk_cs = 0;
*hz_buf = XBYTE[(unsigned int) address]; //取汉字模数据
hz_buf++;
zk_cs = 1;
}
}