利用MPC860嵌入式系统的快速性,可将显示应用程序分为两层,其中底层为硬件接口层,上层为应用层。硬件接口层主要是显示液晶模块自带的ASCII函数和显示汉字代码函数。由于硬件各不相同,在此不作具体介绍。而上层应用层的主要功能是提供友善的菜单,同时实现汉字和图形显示,并提供英文、数字输入和汉字输入功能。由于硬件接口层的隔离作用,不同的系统具有一定的通用性,以下重点介绍应用层编程中的汉字代码编码方法和显示编程的实现这两部分。
一般西文为8×8点阵,因而显示一个西文字需要8个字节而每个汉字占4个西文字体,因此显示一个汉字需要32个字节。汉字字库表为一张数据表 每个汉字在数据表中,通常由32个字节组成一个点阵图形。由于ASCII码编码是由0X00-0X7F表示,因此每个汉字可由两个字节0Xxx和0Xyy来表示,每个字节为0X80~0XFF(区别于ASCII代码)。第一汉字定义为0X80 0X80,依此类推直至0X80 0XFF ,0X81 0X80,……,……,0XFF 0XFF ,总计可以定义128×128=16384个汉字。
在设计中,所有的页可组成一个环形队列结构,页中的行也可组成一个环形队列结构,其关系如图2所示。图3所示是该系统的显示流程。
下面给出一个行结构:
typedef struct lcdLine
{
struct lcdLine *previous //前一行
struct lcdLine *next //后一行
unsigned short lineId //行特征字
unsigned char showflag //是否显示汉字
unsigned char start //显示行号 ,汉字一
定是奇数行如 1,3,5,7
unsigned char lcdseg16
//显示的代码如是ASCII码,0X10显示0,
0X3C显示\ 汉字为0X80 0X81 显示汉字“据”
void *flcdLinestruct lcdLine * plcdLine
//处理行函数
};
由于页是由行组成的,所以页结构的定义如下:
typedef struct lcdPage
{
struct lcdLine *firstLine //该页中的第一行
struct lcdPage *previous //前一页
struct lcdPage *next //后一页
unsigned short pageId //页特征字
} lcdPage
下面给出的是一个环行队列函数的程序代码:
VOID CSC Place On ListCS NODE **head CS NODE *new node
{
/* Determine if the list in non-empty. */
if *head
{
/* The list is not empty. Add the new
node to the end of the list. */
new node->cs previous=*head
->cs previous
(new node ->cs previous)->cs
next=new node
new node-> cs next =*head
(new node->cs next)->cs previous
=new node;
}
else
{
/* The list is empty setup the head and
the new node. */
*head = new node
new node -> cs previous = new node
new node -> cs next = new node
}
}
在建立了上述结构后,便可以得出行队列和页队列的组成方法:
lcdLine lcdLine30
lcdPage lcdPage10; //初始化列
lcdLine0..lcdseg0=0x80
lcdLine0..lcdseg1=0x80
lcdLine0..lcdseg2=0x80
lcdLine0..lcdseg3=0xBC
lcdLine0..lcdseg4=0x80
lcdLine0..lcdseg5=0x97
lcdLine0..lcdseg6=0x80
lcdLine0..lcdseg7=0x98
lcdLine0..lcdseg8=0x80
lcdLine0..lcdseg9=0x99
lcdLine0..lcdseg10=0x00
lcdLine0..lcdseg11=0x00
lcdLine0..lcdseg12=0x00
lcdLine0..lcdseg13=0x00
lcdLine0..lcdseg14=0x00
lcdLine0..lcdseg15=0x00
lcdLine0..start =1 //第二行起
lcdLine0..showflag =1 //汉字
lcdLine0.lineId =1001; //行标识
firstlcdLine 1=NULL
CSC Place On List &firstlcdLine 1 &lcdLine0 //第一页中的第一行
CSC Place On List&firstlcdLine 1&lcdLine1
CSC Place On List &firstlcdLine 1 &lcdLine2
CSC Place On List &firstlcdLine 1 &lcdLine3由于四行即可组成一个循环队列,其中lcdLine0指定为第一页的第一个入口行,FirstlcdLine 1与lcdLine为同一行,lcdPage0页的入口行为firstlcd-Line;lcdPage0.firstLine=firstlcdLine 1lcdPage0.pageID =1001,这样,依据该方法便可以生成任意多的页。具体方法如下:
lcdpage 1=NULL
lcdPage Place On List&lcdpage 1 &lcdpage0
lcdPage Place On List&lcdpage 1 &lcdpage1
lcdPage Place On List&lcdpage 1 &lcdpage2
lcdPage Place On List&lcdpage 1 &lcdpage3
lcdPage Place On List&lcdpage 1 &lcdpage4
lcdPage Place On List&lcdpage 1 &lcdpage5
这样,用五页即可组成一个循环队列,其中lcd-page_1与lcdpage0为同一页。
对于行的显示,最基础的行显示方法如下:
void disp lcd LinelcdMenu *lcdmunsigned char start //START为行号
{
unsigned char iloop
unsigned char ztzt1
unsigned char sign
unsigned char offset
unsigned char offlen
unsigned char *phz
unsigned char z0
phz=unsigned char *&hz code table
/汉字代码初地址
offset=start*16 //显示的位置 行号 *列号
offlen =0
loop=0
z0=0x00
sign=lcdm->showflag //是否为汉字
whileloop<16 //在同一行中从0列到15列
{
zt=lcdm->lcdsegloop //取第一个代码
ifzt<=0x7F /小于0X80为ASCII代码
{
disp self ascii&zt1offset
//在本行,显示自有的ASCII代码
ifsign==1
{
disp self ascii&z01offset 16
//在上一行,同一列的位置,不显示任何代码
}
offset=offset +1
offlen=offlen +1
loop++
}
else
{
loop++
zt1=lcdm->lcdsegloop
//取第二个代码
disp chinesephz+zt-0x80 *4096 +zt1-0x80 *321offset //显示汉字
offset=offset + 2
offlen=offlen +2
loop++
}
}
}
3 结束语
由于本系统在显示时采用了环形结构算法,因此,可以达到快速、简单的汉字显示效果。