分类:
2007-06-23 01:20:07
UCDOS软件中的文件HZK16为16×16的国标汉字点阵文件,以二进制格式存储。在文件HZK16中,按汉字区位码从小到大依次存有国标区位码表中的所有汉字,每个汉字占用32个字节,每个区为94个汉字。
在PC机的文本文件中,汉字是以机内码的形式存储的,每个汉字占用两个字节:第一个字节为区码,为了与ASCII码区别,范围从十六进制的0A1H开始(小于80H的为ASCII码字符),对应区位码中区码的第一区;第二个字节为位码,范围也是从0A1H开始,对应某区中的第一个位码。这样,将汉字机内码减去0A0AH就得该汉字的区位码。
例如汉字“房”的机内码为十六进制的“B7BF”,其中“B7”表示区码,“BF”表示位码。所以“房”的区位码为0B7BFH-0A0A0H=171FH。将区码和位码分别转换为十进制得汉字“房”的区位码为“2331”,即“房”的点阵位于第23区的第31个字的位置,相当于在文件HZK16中的位置为第32×[(23-1) ×94+(31-1)]=67136B以后的32个字节为“房”的显示点阵。
下面给出一个根据汉字机内码(两字节)在汉字库中查找汉字的字模的程序。字库文件分成四部分,分别存在四片27512(并行EPROM)中。读出的字模存入hz_buffer[32]数组中。
int8 hz_buffer[32];//定义32字节数组,用于存储点阵字模,该字模为横排字模。
#define int8 unsigned char
#define int16 unsigned int
#define int32 unsigned long
/*
函数void read_hz(int16 hz)的参数hz为两字节的机内码,调用方法:read_hz(‘汉’);
对ASCII字符,则read_hz('A'+0xa380);读取
*/
void read_hz(int16 hz){
void *void_p;//定义一个空类型指针
int8 *int8_p;//定义一个unsigned char 指针
int8 i; //定义一个循环变量
int16 area_l,area_h;//定义两个整型变量,用于存储区码和位码
int32 pos; //定义一个long型变量,用于存储计算所得字模在字库的位置,
int8 chip; //字模所在的芯片,可用74HC138之类的芯片译码。
int16 addr; //在某一芯片64K字节空间内的地址
void_p=&hz; //空指针指向机内码的低字节
int8_p=void_p; //char类型指针指向空指针,即机内码的低字节
area_l=*int8_p-0xa0; //机内码低字节减去0xa0得到区码
area_h=*(int8_p+1)-0xa0; //机内码高字节减去0xa0得到位码
pos=32*((int32)((area_h-1)*94)+area_l-1); //计算在一个完整的字库中的位置(256K)
//pos=116672; //这是“请”字在HZK16文件中的位置,单位为字节。用于测试
if(pos<64*1024) //在第一片27512芯片
{
chip=0;addr=(int16)pos;
}
else if((pos>=64*1024)&&(pos<128*1024)) //在第二片27512芯片
{
chip=1;
addr=(int16)pos;
}
else if((pos>=128*1024)&&(pos<192*1024)) //在第三片27512芯片
{
chip=2;
addr=(int16)pos;
}
else if((pos>=192*1024)&&(pos<256*1024)) //在第四片27512芯片
{
chip=3;
addr=(int16)pos;
}
select_chip(chip); //选择第chip片27512芯片
for(i=0;i<32;i++)
{
hz_buffer[i]=read_data(addr+i); //读取一字节的数据
}
}
在实际中,由于现很少采用EPROM芯片,可以用并口、SPI,I2C接口的大容量Flash、EEPROM芯片。但I2C接口速度较慢,显示汉字的速度将会很慢,可以在一些比较少字场合使用;而SPI接口的存储芯片速度较快,接口简单,对于一般的应用场合还是可以满足的;对于大量使用的场合,可以使用并行接口,它具储存空间大,读取速度快的特点,如使用AT29系列的Flash存储器,单片容量可以达到256K以上,就不需要分开存储,但其需要较多的IO口,接口复杂。所以应根据实际来选择存储器。