字库原理 GB2312-80
这篇文章介绍的是 在嵌入式开发中 常常会遇见的 中文字体点阵字库(如汉字库) 的核心编码原理:区位码 + 偏移计算 + 内存映射。我们将会介绍 GB2312-80 字库的工作机制。
📘什么是 GB2312-80?
GB2312-80 是中国国家标准定义的一套简体汉字编码表,它包含:
项目 | 数量 |
---|---|
汉字区数 | 94 区(01H~5FH ) |
每区位数 | 94 位(01H~5FH ) |
编码总数 | 94 × 94 = 8836 个位置(包含 6763 个汉字 + 其它符号) |
🧩区位码原理
每个汉字都有一个对应的 区号 和 位号(统称区位码):
示例:汉字 “中” 的区位码是: 54 区 48 位
📌 在计算机中的存储方式:
- 汉字编码占两个字节
- 高字节 存储区号 + 偏移(
0xA0
) - 低字节 存储位号 + 偏移(
0xA0
)
那么,为什么是加 0xA0
(即十进制 160)?
为了避开 ASCII 的控制字符(
0x00~0x1F
),并使高位始终为 1,避免与 ASCII 字符混淆。
字模文件的存储结构(点阵数据)
- 每个汉字对应 一个点阵图
- 比如 16×16 点阵:每个汉字占用 32 字节(16 行 × 每行 2 字节)
- 汉字按区位码顺序排列
偏移 = ((区号 - 0xA1) × 94 + (位号 - 0xA1)) × 每字节数
🧮 偏移量计算公式详解
在图中我写了计算公式:
offset = ((区号 - 0xA1) * 94 + (位号 - 0xA1)) * 每个汉字所占字节数
✅ 示例:汉字“中”
“中”的编码是 0xD6D0
,即:
- 高字节:D6 → 区号 = D6H = 214
- 低字节:D0 → 位号 = D0H = 208
offset = ((0xD6 - 0xA1) * 94 + (0xD0 - 0xA1)) * 32= ((0x35) * 94 + 0x2F) * 32= (53 * 94 + 47) * 32= 5029 * 32= 160928
所以,“中”
对应的点阵字模在字库文件中的偏移地址是 160928 字节
处起始的 32 字节数据
。
🧾 位图数据的存储方式
以 16x16 点阵为例:
每行 16 个像素,2 字节(16 位)
一共 16 行,共 32 字节
每个 bit 表示一个像素点(0=背景,1=前景)
读取点阵流程(示意):
uint8_t buf[32];
FILE* f = fopen("HZK16", "rb");
fseek(f, offset, SEEK_SET);
fread(buf, 1, 32, f);
fclose(f);
然后将 buf
中的每个 bit
按行绘制在 LCD/LED
屏上,即可显示汉字。
点阵显示效果(示意):
0x00 0x7E → 00000000 01111110↑↑↑↑↑↑↑↑ 行10x18 0x18 → 00011000 00011000↑↑↑↑↑↑↑↑ 行2... 以此类推,共16行
综上。汉字字库通过 区位码映射 + 偏移计算 + 点阵数据读取,实现了在嵌入式系统(如 STM32)中汉字的快速显示,是图形化界面和字符屏的基础。
以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!