汉字显示原理_led显示汉字的原理
汉字显示原理
来源: ChinaUnix博客 日期: 2008.09.29 16:13 (共有0条评论) 我要评论
国家标准汉字字符集GB2312-80共收集了共7445个汉字和图形符号,其中汉字6763个,分为二级, 一级汉字3755个,二级汉字3008个。汉字图形符号根据其位置将其分为94个“区”,
每个区包含94个汉字字符,每个汉字字符又称为一个“位”。区的序号和位的序号都是从01到94, UCDOS 软件中的文件HZK16和文件ASC16分别为16×16的国标汉字点阵文件和8×16的ASCII 码点阵文件,
以二进制格式存储。在文件HZK16中,按汉字区位码从小到大依次存有国标区位码表中的所有汉字, 每个汉字占用32个字节,每个区为94个汉字。在文件ASC16中按ASCII 码从小到大依次存有 8×16的ASCII 码点阵,每个ASCII 码占用16个字节。
国家标准汉字字符集GB2312-80共收集了共7445个汉字和图形符号,其中汉字6763个,分为二级, 一级汉字3755个,二级汉字3008个。汉字图形符号根据其位置将其分为94个“区”,
每个区包含94个汉字字符,每个汉字字符又称为一个“位”。区的序号和位的序号都是从01到94, UCDOS 软件中的文件HZK16和文件ASC16分别为16×16的国标汉字点阵文件和8×16的ASCII 码点阵文件,
以二进制格式存储。在文件HZK16中,按汉字区位码从小到大依次存有国标区位码表中的所有汉字, 每个汉字占用32个字节,每个区为94个汉字。在文件ASC16中按ASCII 码从小到大依次存有 8×16的ASCII 码点阵,每个ASCII 码占用16个字节。
在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个字节为“房”的显示点阵。
ASCII 码的显示与汉字的显示原理相同,在ASC16文件中不存在机内码的问题,
其显示点阵直接按ASCII 码从小到大依次排列,不过每个ASCII 码在文本中只占1个字节并且小于80h, 每个ASCII 码为8X16点阵,即在ASCII16文件中,每个ASCII 码的点阵也只占16个字节。
以下是读取hzk16的C 部分语言代码(仅供参考) :
void dis_cc(unsigned int x,unsigned int y,unsigned int color,unsigned int codeh,
unsigned int codel,unsigned int circle,unsigned int kind,unsigned int mode)
{
char word[32];
int area,bit;
long count,offset;
unsigned long count,offset;
unsigned int i,j;
area = (codeh&0x00ff)-0xa0-1; //根据机内码取得区码
bit = (codel&0x00ff)-0xa0-1; //根据机内码取得位码
offset = area*94+bit; //取得偏移量
count = 32l*(long)offset;
lseek(HZK16,count,SEEK_SET);//在HZK16文件中找到点阵起始位置
j=_read(HZK16,&word[0],32);//读取32字节的点阵信息
在电脑中,所有的数据都是以0和1保存的,按不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)
即可。而对于中文,常用却有6000以上,于是我们的DOS 前辈想了一个办法,就是将
ASCII 表的高128个很少用到的数值以两个为一组来表示汉字,即汉字的内码。而剩下的低128位则留
给英文字符使用,即英文的内码。 汉字字模
得到了汉字的内码后,还仅是一组数字,那又如何在屏幕上去显示呢?这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的"A" 在字模中是这样记载的:
汉字内码
在电脑中,所有的数据都是以0和1保存的,按不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即
可。而对于中文,常用却有6000以上,于是我们的DOS 前辈想了一个办法,就是将
ASCII 表的高128个很少用到的数值以两个为一组来表示汉字,即汉字的内码。而剩下的低128位则留给英文字符使用,即英文的内码。 汉字字模
得到了汉字的内码后,还仅是一组数字,那又如何在屏幕上去显示呢?这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的"A" 在字模中是这样记载的:
而中文的“你”在字模中却是这样记载的:
在硬件系统内,英文的字模信息一般固化在ROM 里,中文的字模信息一般记录在汉字库文件HZK16里。
采用如何在点阵LED 或LCD 中显示汉字?
假设你采用16x16点阵汉字,水平扫描。
显示汉字为“模”,用产生如下字模
unsigned char mo[]={
0x00,0x00, 0x10,0x90, 0x10,0x94, 0x13,0xFE,
0x7C,0x90, 0x11,0xFC, 0x19,0x04, 0x35,0xFC,
0x35,0x04, 0x51,0xFC, 0x50,0x40, 0x17,0xFE,
0x10,0x90, 0x11,0x08, 0x16,0x06, 0x00,0x00
};
代码如下:
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};
void FontDisplay(int x, int y, unsigned char * FontModule)
{
for(int row=0;rowmain(){
FontDisplay(5,10,mo);
}
24x24点阵代码示例(水平扫描):
unsigned char mo[]={
0x00,0x00,0x00, 0x00,0x00,0x00, 0x07,0x0C,0xC0, 0x06,0x0C,0xC0,
0x06,0x0C,0xDC, 0x06,0x7F,0xF0, 0x06,0xCC,0xC0, 0x1F,0xF0,0x70,
0x06,0x3F,0xF0, 0x07,0x30,0x70, 0x0F,0xBF,0xF0, 0x0E,0xF0,0x70,
0x1E,0xF0,0x70, 0x1E,0x3F,0xF0, 0x36,0x06,0x18, 0x06,0xFF,0xFC,
0x06,0x07,0x00, 0x06,0x0F,0x80, 0x06,0x0C,0xE0, 0x06,0x38,0x7C,
0x06,0xE0,0x18, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
};
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};
void FontDisplay(int x, int y, unsigned char * FontModule)
{
for(int row=0;rowmain(){
FontDisplay(5,10,mo);
}
putpixel 函数:
putpixel(int x,int y,int color)
x,y 为坐标,color 为颜色值. 该函数在(x,y)点设定象素的颜色. 由于硬件的不同, 也许提供的函数不同, 用户可把此函数作为参考, 必要时用硬件提供的函数取而代之.
点阵字库
一般我们使用16*16的点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点的区域内显示的。 不过后来又有了HZK12、HZK24,HZK32和HZK48字库及黑体、楷体和隶书字库。
虽然汉字库种类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。
每一个区记录94个汉字,位号则为该字在该区中的位置。
因此,汉字在汉字库中的具体位置计算公式为:94*(区号-1)+位号-1。
减1是因为数组是以0为开始而区号位号是以1为开始的。
这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?
只需乘上一个汉字字模占用的字节数即可,
即:(94*(区号-1)+位号-1)*一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果。
以16*16点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32。
汉字库文该从该位置起的32字节信息即记录了该字的字模信息。
了解点阵汉字及汉字库的构成原理后,显示汉字就变得简单。以16*16点阵字库为例,
通常的方法是:将文件工作指针移到需要的汉字字模处、将汉字库文件读入一2*16数组再用for 循环一位位地显示。
#include "graphics.h"
#include "stdio.h"
main()
{ int i=VGA,j=VGAHI,k;
unsigned char mat[16][2],chinease[3]="我";
FILE *HZK;
if((HZK=fopen("hzk16","rb"))==NULL)exit(0);
initgraph(&i,&j,"");
i=chinease[0]-0xa0;j=chinease[1]-0xa0; /*获得区码与位码*/
fseek(HZK,(94*(i-1)+(j-1))*32l,SEEK_SET);
fread(mat,32,1,HZK);
for(j=0;j>k)) /*测试为1的位则显示*/
putpixel(i*8+k,j,WHITE);
getch();
closegraph();
fclose(HZK); (转)
标准字库汉字显示原理
作者:佚名 来源:不详 录入:jdzj868 更新时间:2009-7-9 16:55:59 点击数:0
【字体:
汉字显示原理
国家标准信息交换用汉字字符集GB 2312-80共收录了汉字、图形符号等共7445个,其中汉字6763个,按照汉字使用的频度分为两级,其中一级汉字3755个,二级汉字3008个。汉字、图形符号根据其】
位置将其分为94个“区”,每个区包含94个汉字字符,每个汉字字符又称为“位”。其中“区”的序号由01区至94区,“位”的序号也由01位至94位。若以横向表示“位”号,纵向表示“区” 号,则“区”和“位”构成一个二维坐标。给定一个“区”值和“位”值就可以确定一个惟一的汉字或图形符号。即4位阿拉伯数字就可以惟一地确定一个汉字或符号。如“北”字的区位码是“1717”,而京字的区位码是“3009”。前两位是“区”号,后两位是“位”号。其中1至15区是各种图形符号、制表符和一些主要国家的语言字母,16区至87区是汉字,其中16区至55区是一级汉字,56至87区是二级汉字。
UCDOS 软件中的文件HZK16和文件ASC16分别为16×16的国际汉字点阵文件和8×16的ASCII 码
HZK16中按汉字区位码从小到大依次存放国标区位码表中的所有汉字,点阵文件,每个汉字占用32字节,每个区为94个汉字。而asc16文件中按ascii 码从小到大依次存有8×16的ASCII 码点阵,每个ASCII 码占用16字节。
PC 的文本文件中,汉字是用机内码的形式存储的,每个汉字占2字节,其中第一个字节为机内码的区码,汉字机内码的区码范围是从0A1H (十六进制)开始,对应区位码中区码的第一区;而机内码的第二个字节为机内码的位码,范围也是从0A1H (十六进制)开始,对应某区中的第一个位码。就是说将汉字机内码减去0A0AH 就得到该汉字的区位码。例如汉字“北”的机内码是十六进制的“B1B1”,其中前两位“B1”表示机内码的区码,后两位“B1”表示机内码的位码。所以“北”的区位码为0B1B1H -0A0A0H=1111H,将区码和位码分别转换为十进制,得汉字“北”的区位码为“1717”。即“北”的点阵位于第17区的第17个字的位置,在文件HZK16中的位置为第32×[(17-1)×94+(17-1)]=48640D以后的32个字节为“北”的显示点阵。用RF-1800编程器读入二进制文件hzk16j.bin 后利用其编辑功能中的缓冲区编辑查找到BE00 H (48640D 是十进制,将其转变为十六进制后得BE00 H)开始的32个字节:04 80 04 80 04 88 04 98 04 A0 7C C0 04 80 04 80 04 80 04 80 04 80 04 80 1C 82 E4 82 44 7E 00 00(以上全为下十六进制),将其写在16×16点阵方格纸上,即得图2。由此可以理解其相互逻辑关系。
在单片机系统中,连续取32个字节送到LCD 的相应位置,就能正确显示汉字后的图形符号。从HS-12232-1使用的SED1520的控制原理得知,字模送显示前要旋转90°,例如“逢”的区位码是3778,在HZK16中的位置为第32*[(37-1)*94+(78-1)]=110752D以后的32个字节:04 44 FF FE 05 40 41 F8 33 10 14 E0 01 18 F6 46 1B F8 10 40 13 F8 10 40 17 FC 10 40 28 46 47 FC , 旋转90°后上16个字节:82 8A 92 B2 02 A7 92 5E 2A AF 2A 5A 4A 83 82 00,下16个字节;00 80 40 3F 04 90 95 95 95 FF 95 95 95 D0 40
00。
2.4 ASCII码的显示原理
ASCII 码的显示与汉字的显示基本原理相同,在ASC16文件中不存在机内码的问题,其显示点阵直接按ASCII 码从小到大依次排列,不过每个ASCII 码在文本文件中只占1个字节并且小于80 H, 每个ASCII 码为8×16点阵,即在ASCII16文件中,每个ASCII 码的点阵也只占16个字节。