想法:使用 EEPROM 或 Flash 来存储 hzk16 字库,使用 OLED12864 显示汉字。
为OLED制作汉字字库
1 字符集的含义
C语言有种数据类型叫做 “char” 型,这种类型的数据使用 8-bit 二进制数(0~127)来为数字、英文字母、标点符号和常用符号编码,编出来的一个码表叫做 “ASC-Ⅱ”码表,也就是“美国信息交换标准代码”,一共128个字符。
上面这个表表,也可以算是一种 “字符集”。所谓的“字符集”,就是对 “英文、汉语、日语等各国语言文字和符号” 以二进制编码表示的“码”的集合。
我国使用的是 GB2312 来对汉字进行编码,后来扩展到了GBK字符集,能表示更多的字符啦!GB2312字符集中有汉字 6763 个,符号 682 个;其中,一级汉字有 3755 个,按拼音升序排列,二级汉字有 3008 个,按偏旁部首排列。
国际上通用的一个集成世界各国语言的标准叫做“Unicode”,使用**4 bytes(32 bits)**编码,这个标准超级大,超级大,超级大!!!通常情况下,根据你所使用的语言,截取标准 Unicode 里面某一部分来使用即可!那用什么方式,怎么从 Unicode 字符集里面取出需要的字符呢?这就有好多种方式啦,其中有一种是“UTF-8”!
1.1 定长编码原理
Unicode 的编号肯定超级大,直接用定长的方式取出来,是不是有点浪费空间呢???如果你所用的语言字符编码在 Unicode 字符集中比较低的位置,高位的那些个 0 根本没有用啊!!!
1.2 UTF-8变长编码原理
每次传送8位,可变字长编码。
第1个 | 第2个 | 第3个 | 第4个 | |
---|---|---|---|---|
0x0000 0000 ~ 0x0000 007F | 0xxx xxxx | |||
0x0000 0080 ~ 0x0000 07FF | 110xxxxx | 10xxxxxx | ||
0x0000 0800 ~ 0x0000 FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |
0x0001 0000 ~ 0x0010 FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
1.3 GB2312
我们汉字那么多,究竟如何编码的呢?
我们使用分区管理,共94个区,每个区94个位,共8836个码位!(想想矩阵键盘,如果按键特别多,可以用矩阵方式排列,用“行列扫描”或者“线反转”方法识别)
分区 | 说明 |
---|---|
01~09 | 汉字外的 682 字符 |
10~15 | 空白区 |
16~55 | 3755个常用汉字,按拼音升序排列 |
56~87 | 3008个二级汉字,按部首/笔画排列 |
88~94 | 空白区 |
01~09 乱七八糟字符
16~55 一级汉字
56~87 一级汉字
2 汉字在电脑上存储方式
#include <stdio.h>
int main(int argc, char *argv[]){
printf("0x%x", '侃');
return 0;
}
问题:为啥高低位都要+0xA0?
0xA0换算成十进制是160,而ASCⅡ是从0~127,可以兼容ASCⅡ码?是这个原因吗???那为啥不加0x80,非要+0xA0?
3 新型汉字编码
3.1 GBK编码1995
我国的汉字太多了,需要进一步对GB2312字符集进行扩充,因此出现了GBK字符集:
- ① 高位不再+0xA0
- ② 空白区都用上!
扩展了将近20000个汉字和符号!
3.2 GB18030编码2000
把“少数民族”的字符也加进来!这个就叫GB18030字符集!
3.3 各种汉字标准历史
国家标准全文公开系统:
http://openstd.samr.gov.cn/bzgk/gb/
标准 | 时间 | 汉字数量 | 编码方式 | 说明 |
---|---|---|---|---|
GB2312 | 1980 | 6763 | 双字节 | |
GB12345 | 1990 | 6866 | 双字节 | |
GBK | 1995 | 21,003 | 双字节 | 过渡产物,兼容GB2312,已被GB18030替代 |
BIG5 | 2003 | 13,060 | 双字节 | 繁体字编码方案,CNS11643中文标准交换码的附录 |
GB18030 | 2005 | 70,244 | 单字节、双字节、四字节分段 | 加入各种少数民族的语言 |
4 点阵编码HZK16
显示屏其实就是一个很大的LED点阵!!!
GB2312 字符集的“点阵字模”数据就是HZK16(16x16点阵)。
GB2312编码如下:注意,索引从 “1” 开始
区号 | GB2312编码 | 说明 |
---|---|---|
01~09 | +0xA0 = 0xA1~0xA9 | 汉字外的 682 字符 |
10~15 | - | 空白区 |
16~55 | +0xA0 = 0xB0 ~ 0xD7 | 3755个常用汉字,按拼音升序排列 |
56~87 | +0xA0 = 0xD8 ~ 0xF7 | 3008个二级汉字,按部首/笔画排列 |
88~94 | - | 空白区 |
GB2312 每个区 94 个汉字;HZK每个汉字对应 32 个字节数据;
当我们得到一个汉字,比如“我”的GB2312码(0xCED2)
索引从0开始 | 每区94字 | ||
---|---|---|---|
区号 | 0xCE | 0xCE-1 | (0xCE-1)*94 |
位号 | 0xD2 | 0xD2-1 | (0xD2-1) |
4.1 HZK16x16
- HZK16_16 中的绝对偏移量(1个汉字用 32 bytes):
o f f s e t = [ ( 0 x C E − 1 ) × 94 + ( 0 x