单片机上常用-GB2312GBK汉字取模与字库偏移地址的计算与汉字描点
Posted DS小龙哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机上常用-GB2312GBK汉字取模与字库偏移地址的计算与汉字描点相关的知识,希望对你有一定的参考价值。
使用单片机开发程序时,经常需要使用LCD显示屏显示一些文字、数字。单片机因为配置不高,很多场合也不需要显示很多文字或者说只是显示一种大小、或者固定几种大小的文字,或者显示一些固定的文字或者一些英文字母、数字。如果只是显示固定文字,这时可以直接将要显示的文字提前取模存放到程序中,在通过LCD屏画点函数将数据画在LCD屏幕上去。如果显示固定大小的文字,可以制作点阵字库。这篇文章就介绍常用的里GB2312,GBK编码区别,制作字库寻址的方式。
一、 GB2312编码
GB2312 码是中华人民共和国汉字信息交换用编码,全称《信息交换用汉字编码字符集--基本集》, 由国家标准总局发布, 1981 年 5 月 1 日 实施,通行于大陆。新加坡等地也使用此编码。GB2312 收录简化汉字及符号、字母、 日文假名等共 7445 个图形字符,其中汉字占 6763 个。GB2312 规定<对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示>,习惯上称第一个字节为<高字节>, 第二个字节为<低字节>。GB2312-80 包含了大部分常用的一、二级汉字, 和 9 区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位 0xa1- 0xfe, 低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe。GB2312 将代码表分为 94 个区,对应第一字节( 0xa1 -0xfe);每个区 94 个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加 32(20H), 因此也称为区位码。01-09 区为符号、数字区, 16-87 区为汉字区(0xb0-0xf7),10-15 区、88-94 区是有待进一步标准化的空白区。 GB2312 将收录的汉字分成两级: 第一级是常用汉字计 3755 个,置于 1 6-55 区, 按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计 3008 个,置于 56-87 区,按部首/笔画顺序排列。
故而 GB2312 最多能表示 6763 个汉字。
二、GBK编码
全国信息技术化技术委员会于 1995 年 12 月 1 日《汉字内码扩展规范》。GBK 向下与 GB2312 完全兼容,向上支持 ISO 10646 国际标准,在前者向后者过渡过程中起到的承上启下的作用。GBK 亦采用双字节表示,总体编码范围为 8140-FEFE 之间,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 XX7F 一条线。
GBK 共收入 21886 个汉字和图形符号,包括:
GB2312 中的全部汉字、非汉字符号。
BIG5 中的全部汉字。
与 ISO 10646 相应的国家标准 GB13000 中的其它 CJK 汉字,以上合计 20902 个汉字。
其它汉字、部首、符号,共计 984 个。
GBK 编码区分三部分:
1) 汉字区,包括:
GBK/2:OXBOA1-F7FE, 收录 GB2312 汉字 6763 个,按原序排列;
GBK/3:OX8140-AOFE,收录 CJK 汉字 6080 个;
GBK/4:OXAA40-FEAO,收录 CJK 汉字和增补的汉字 8160 个。
2) 图形符号区,包括:
GBK/1:OXA1A1-A9FE,除 GB2312 的符号外,还增补了其它符号
GBK/5:OXA840-A9AO,扩除非汉字区。
3) 用户自定义区:
即 GBK 区域中的空白区,用户可以自己定义字符
每个 GBK 码由 2 个字节组成:
第一个字节为 0X81~0XFE
第二个字节分为两部分:
- 0X40~0X7E
2.0X80~0XFE。
其中与 GB2312 相同的区域,字完全相同。
我们把第一个字节代表的意义称为区,那么 GBK 里面总共有 126 个区( 0XFE-0X81+1),
每个区内有 190 个汉字( 0XFE-0X80+0X7E-0X40+2),总共就有 126*190=23940 个汉字。我们的点阵库只要按照这个编码规则从 0X8140 开始,逐一建立, 每个区的点阵大小为每个汉字所用的字节数*190。这样,我们就可以得到在这个字库里面定位汉字的方法:
当 GBKL<0X7F 时: Hp=((GBKH-0x81)*190+GBKL-0X40)*(size*2);
当 GBKL>0X80 时: Hp=((GBKH-0x81)*190+GBKL-0X41)*(size*2);
其中 GBKH、 GBKL 分别代表 GBK 的第一个字节和第二个字节(也就是高位和低位), size
代表汉字字体的大小(比如 16 字体, 12 字体等), Hp 则为对应汉字点阵数据在字库里面的起始地址(假设是从 0 开始存放)。
这样我们只要得到了汉字的 GBK 码,就可以显示这个汉字了。从而实现汉字在液晶上的显示。
简化公式:
if(L<0x7f)L=L-0x40;
else L=L-0x41;
H=H-0x81;
Addr=(190*H+L)*size;
L 是汉字的低字节,H是汉字的高字节。
Addr 是该汉字在字库里的偏移量。
Size 是该汉字的应点阵集所占的字节数量。
汉字的高字节大于0x80 ,才是汉字。高字节小于0X80就是英文字符。
字库在FLASH寻址过程:
首先得到该汉字点阵码在FLASH里的存储偏移量,然后在加上该汉字库在FLASH里的存放起始地址,就得到了该汉字的点阵数据位置。
得到绝对位置之后,就可以读出点阵码,进行打点显示。
BIG5 编码
BIG5 是通行于台、香港地区的一个繁体字编码方案。虽然存在一些瑕疵,但广泛应用于电脑行业,尤其是互联网中,从而成为一种事实上的行业标准。
1983 年 10 月,台国家科学委员会、教育部国语推行委员会、中央标准局、行政院共同制定了《通用汉字标准交换码》,后经修订于 1992 年 5 月公布,更名为《中文标准交换码》,BIG5 是台资讯工业策进会根据以上标准制定的编码方案。
BIG5 码是双字节编码方案,其中第一个字节的值在 OXAO-OXFE 之间,第二个字节在 OX40-OX7E 和
OXA1-OXFE 之间。
BIG5 收录 13461 个汉字和符号,包括:
- 符号 408 个,编码位置 A140-A3BE
- 常用字 5401 个,编码位置 A440-C67E,包括台教育部颁布的《常用国字标准字体表》的全部汉字 4808 个,台教科书常用字 587 个,异体字 6 个。
- 次常用字 7652 个,编码位置 C940-F9D5,包括台育部颁布的《次常用国字标准字体表》的全部汉字 6341 个,《罕用国字标准字体表》中使用频率较高的字 1311 个。
GB13000 编码
GB13000 等同于国际标准的《通用多八位编码字符集 (UCS)》 ISO10646.1,就是等同于 Unicode 的标准,代码页等等的都使用 UTF 的一套标准。
从 ASCII、GB2312、GBK 到 GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方
法是高字节的最高位不为 0。按照程序员的称呼,GB2312、GBK 到 GB18030 都属于双字节字符集 (DBCS)。
三、偏移量计算
GB2312收录简化汉字及符号、字母、日文假名等共7445 个图形字符,其中汉字占6763 个。GB2312 规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,即所谓的区码。第二个字节为“低字节”,即所谓的位码。GB2312―80包含了大部分常用的一、二级汉字,和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1~0xfe,低位也是0xa1~0xfe;汉字从0xb0a1开始,结束于0xf7fe。GB2312将代码表分为94个区,对应第一字节(0xa1~0xfe);每个区94 个位(0xa1~0xfe),对应第二字节。两个字节的值分别为区号值和位号值加32(20H),因此也称为区位码。01~09区为符号、数字区,16~87区为汉字区(0xb0~0xf7),10~15区、88~94区是有待进一步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16~55区,按汉语拼音字母/笔形顺序排列:第二级汉字是次常用汉字计3008 个,置于56~87 区,按部首/笔画顺序排列。故而GB2312 最多能表示6763 个汉字。
而GBK内码完全兼容GB2312,同时支持繁体字,总汉字数有2万多个,编码格式如下,每个GBK 码由2 个字节组成,第一个字节为0X81~0XFE,第二个字节分为两部分,一是0X40~0X7E,二是0X80~0XFE。其中与GB2312相同的区域,字完全相同。把第一个字节代表的意义称为区,那么GBK里面总共有126个区(0XFE~0X81+1),每个区内有190 个汉字(0XFE~0X80+0X7E~0X40+2),总共就有126x190=23940 个汉字。点阵库只要按照这个编码规则从0X8140开始,逐一建立,每个区的点阵大小为每个汉字所用的字节数乘以190。这样,就可以得到在这个字库里面定位汉字的方法:
当GBKL<0X7F 时:Hp=((GBKH-0x81)×190+GBKL-0X40)×(sizex2);
当GBKL>0X80 时:Hp=((GBKH-0x81)×190+GBKL-0X41)×(sizex2);
其中GBKH、GBKLL 分别代表GBK 的第一个字节和第二个字节(也就是高位和低位),size 代表汉字字体的大小(比如16 字体,12 字体等),Hp 则为对应汉字点阵数据在字库里面的起始地址。
对于GBK 字库和GB2312 字库,他们的解码部分部分略有不同,这个区别主要是由于他们的编码方式不同引起的,对于GBK 字库,解码的方式如下:
qh=*code;
ql=*(++code);
if(ql<0x7f)
ql -= 0x40;
else
ql -= 0x41;
qh -= 0x81;
foffset = ((unsigned long)190*qh + ql)*(size * 2);
对于GB2312 字库,解码的方式如下:
qh=*code;
ql=*(++code);
ql -= 0xa1;
qh -= 0xa1;
foffset = ((unsigned long)94*qh + ql)*(size * 2);
其中qh、ql 分别代表GBK 的第一个字节和第二个字节(也就是高位和低位),size代表汉字字体的大小(比如16字体,12字体等),foffset 则为对应汉字点阵数据在字库里面的起始地址。
四、ASCII字符集取模方式
- 需要使用的工具软件:
PCtoLCD2002.exe
- ASCII字符集:
!"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz|~
注意:前面第一个字符是空格。
每个字符点阵码所占用的字节数为:(size/8+((size%8)?1:0))*(size/2),其中size:是字库生成时的点阵大小(12/16/24...)
- PC2LCD2002取模方式设置:阴码+逐列式+顺向+C51格式
- 以下是16*16的字模示例
将取出的ASCII字模使用二维数组保存,方便访问。
//16*16 ASCII字符集点阵
const unsigned char asc2_1608[95][16]=
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,/*"!",1*/
0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00,/*""",2*/
0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00,/*"#",3*/
0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00,/*"$",4*/
0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00,/*"%",5*/
0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08,/*"&",6*/
0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"",7*/
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00,/*"(",8*/
0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,/*")",9*/
0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,MicroPython ESP32ssd1306模块基于GB2312字库驱动0.96“I2C屏幕汉字显示示例PHP中当前文件为GBK或GB2312编码,怎么用正则表达式取汉字