单片机作业1_为OLED制作汉字字库_第1部分
想法:使用 EEPROM 或 Flash 来存储 hzk16 字库,使用 OLED12864 显示汉字。
为OLED制作汉字字库
- 1 字符集的含义
- 1.1 定长编码原理
- 1.2 UTF-8变长编码原理
- 1.3 GB2312
- 01~09 乱七八糟字符
- 16~55 一级汉字
- 56~87 一级汉字
- 2 汉字在电脑上存储方式
- 3 新型汉字编码
- 3.1 GBK编码1995
- 3.2 GB18030编码2000
- 3.3 各种汉字标准历史
- 4 点阵编码HZK16
- 4.1 HZK16x16
- 4.2 HZK24x24
- 4.3 HZK32x32
- 测试C代码汉字
- 测试C代码英文字符
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):
offset=[(0xCE−1)×94+(0xD2−1)]×32offset = [(0xCE-1) \times 94 + (0xD2-1)] \times \color{red} 32 offset=[(0xCE−1)×94+(0xD2−1)]×32
offset=内码×32offset = 内码 \times \color{red} 32 offset=内码×32
注意:内码就是单纯的 “区号” + “位号”(不加0xA0的)
4.2 HZK24x24
- HZK24_24 中的绝对偏移量(1个汉字用 72 bytes):
offset=[(0xCE−1)×94+(0xD2−1)]×72offset = [(0xCE-1) \times 94 + (0xD2-1)] \times \color{red} 72 offset=[(0xCE−1)×94+(0xD2−1)]×72
offset=内码×72offset = 内码 \times \color{red} 72 offset=内码×72
4.3 HZK32x32
- HZK32_32 中的绝对偏移量(1个汉字用 128 bytes):
offset=[(0xCE−1)×94+(0xD2−1)]×128offset = [(0xCE-1) \times 94 + (0xD2-1)] \times \color{red} 128 offset=[(0xCE−1)×94+(0xD2−1)]×128
offset=内码×128offset = 内码 \times \color{red} 128 offset=内码×128
测试C代码汉字
// GB2312 Character Set
#include <stdio.h>
#include <assert.h>#define FONT_BYTES 128void show_binary(char ch){for(int i = 0; i < 8; i++){printf("%3c", (ch >> (7 - i)) & 0x01 ? 79 : 32);}
}int main(int argc, char *argv[]){unsigned char word[7] = "我爱你";printf("我 = 0x%x\r\n", '我');printf("爱 = 0x%x\r\n", '爱');printf("你 = 0x%x\r\n", '你');FILE *pf = fopen(".\\HZK32_32", "r");assert(pf != NULL);unsigned char buf[FONT_BYTES] = {0};for(int j = 0; j < 3; j++){int offset = (94 * (word[j * 2] - 0xa0 - 1) + (word[j * 2 + 1] - 0xa0 - 1)) * 128;fseek(pf, offset, 0);fread(buf, 1, 128, pf);for(int i = 0; i < FONT_BYTES; i++){show_binary(buf[i]);// printf("|0x%x", buf[i]);if((i+1) % 4 == 0){printf("\r\n");}}}fclose(pf);return 0;
}
测试C代码英文字符
#include <stdio.h>
#include <assert.h>void show_binary(char ch){for(int i = 0; i < 8; i++){printf("%3c", (ch >> (7 - i)) & 0x01 ? 79 : 32);}
}int main(int argc, char *argv[]){unsigned char str[8] = "abcABC";unsigned char buf[16] = {0};FILE *pf = fopen(".\\ASC8_16", "r");assert(pf != NULL);for(int j = 0; j < 7; j++){int offset = str[j] * 16;fseek(pf, offset, 0);fread(buf, 1, 16, pf);for(int i = 0; i < 16; i++){show_binary(buf[i]);// printf("|0x%x", buf[i]);printf("\r\n");}}fclose(pf);return 0;
}
单片机作业1_为OLED制作汉字字库_第1部分相关推荐
- 单片机作业1_为OLED制作汉字字库_第4部分
本部分2个工作: ① 向 AT25F4096 写入部分 HZK8x16 转化后的 "列行式" 数据 ② 解码 GB2312 字符,根据码值,去 AT25F4096 中寻找对应的点阵 ...
- 单片机作业1_为OLED制作汉字字库_第3部分
OLED12864 显示英文字符 1 PC端生成列行式点阵数据 1.1 控制台仿真显示逐行式8x16字符 1.1.1 打印显示1个字节的位模式 1.1.2 控制台仿真显示"逐行式" ...
- stm32汉字字库显示实验与OLED的使用(开始于2021-09-01)
stm32汉字字库显示实验与OLED的使用 1.字库的使用 GBK字库的简介: GBK库的由两部分组成,如下图: 高位从0x81开始是为了兼容ASII字符,因为未扩展的ASII字符是从0-128,即0 ...
- LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库
LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库 前言: 阅读前,请确保你至少拥有以下条件: 已实现显示API(教程一已实现, 链接:LittleVGL (LVGL)入门教程一之 ...
- 单片机 怎调用显示屏字库_单片机巧用Windows矢量字库
1 引 言本文引用地址:http://www.eepw.com.cn/article/172177.htm 单片机控制的LED.LCD显示屏均涉及到各种字体的汉字显示.建立单片机汉字字库的传统方法有使 ...
- 0.96吋 OLED 12864 汉字 显示 优化
辅助舍友做毕业设计中的显示部分,优化了OLED的汉字显示,简化了函数的调用方式,略有小得,留做记录.程序在最后面. 未经授权,不得转载!_(:з)∠)_ 前言 中景园的给的例程中的汉字显示函数调用方式 ...
- LCD / OLED显示汉字,取模软件PCtoLCD2002完美版
一.LCD显示汉字结果展示: 二.取模软件的使用(PCtoLCD2002完美版) 1. 打开软件,模式为(字符模式) 点击菜单栏[选项],打开字模选项 勾选[阴码点阵].逐列式取模.顺向(高位在前,低 ...
- 0.96寸OLED显示汉字,数字,英文,图片,GIF动画+取模软件使用+代码解析
前言 本次我们学习一下STM32F103关于OLED显示汉字,数字,英文,图片,GIF动画,和介绍各种取模软件的使用,主要教会大家使用和修改OLED驱动的代码,对汉字大小,图片分辨率进行代码修改并显示 ...
- c语言oled p14x16str,OLED显示汉字
OLED显示汉字 工具:OLED 芯片:K60,XS128等 取模软件:PCtoLCD2002完美版 显示汉字需要几个条件: 汉字索引表, const byte F14x16_Idx[] = { &q ...
- .net 数字转汉字_[原创工具] 小熊汉字笔顺学习软件,查笔顺、学拼音、制作汉字英文数字字贴...
点击右上角"设为星标"每日精彩内容,第一时间送达! 前言 今天带来的是原创软件.家里有上一二年级的小朋友有福了!家里有打印机的可以把设置好的字帖打印出来,小朋友即可临摹.赶紧下载使 ...
最新文章
- LeetCode 之 Merge Sorted Array(排序)
- 从零入门 Serverless | 架构的演进
- Apache Flink 零基础入门(十八)Flink Table APISQL
- Aizu - 1407 Parentheses Editor(对顶栈+模拟)
- 局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究
- 蓝桥杯 ALGO-158 算法训练 sign函数
- 《Python语言程序设计》——1.3 程序设计语言
- matlab 信号与系统(一)—— 上采样(Upsampling)和下采样(Downsampling)
- apache poi使用例_使用java Apache poi 根据word模板生成word报表例子
- LeetCode-9.回文数(大括号+双目运算符使用)
- android 命名空间解析,Android Bluetooth、Android AdapterView等命名空间-Android中文API文档...
- tif转双层pdf Java_TIF文件转双层PDF时 内存不足
- 自律不熬夜真的那么难吗?
- TMS320F28374S之X-BAR
- html dreamweaver模板,Dreamweaver如何制作网页模板
- Flutter:实现iOS无证书打包ipa
- python seek(0)_seek() 方法
- 所谓笔法在也其次-《述张长史笔法十二意》
- 为什么模型loss为负
- 计算机玩游戏特别卡怎么办,电脑玩游戏突然变卡怎么办 玩游戏变卡的解决方法...