想法:使用 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. 单片机作业1_为OLED制作汉字字库_第4部分

    本部分2个工作: ① 向 AT25F4096 写入部分 HZK8x16 转化后的 "列行式" 数据 ② 解码 GB2312 字符,根据码值,去 AT25F4096 中寻找对应的点阵 ...

  2. 单片机作业1_为OLED制作汉字字库_第3部分

    OLED12864 显示英文字符 1 PC端生成列行式点阵数据 1.1 控制台仿真显示逐行式8x16字符 1.1.1 打印显示1个字节的位模式 1.1.2 控制台仿真显示"逐行式" ...

  3. stm32汉字字库显示实验与OLED的使用(开始于2021-09-01)

    stm32汉字字库显示实验与OLED的使用 1.字库的使用 GBK字库的简介: GBK库的由两部分组成,如下图: 高位从0x81开始是为了兼容ASII字符,因为未扩展的ASII字符是从0-128,即0 ...

  4. LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库

    LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库 前言: 阅读前,请确保你至少拥有以下条件: 已实现显示API(教程一已实现, 链接:LittleVGL (LVGL)入门教程一之 ...

  5. 单片机 怎调用显示屏字库_单片机巧用Windows矢量字库

    1 引 言本文引用地址:http://www.eepw.com.cn/article/172177.htm 单片机控制的LED.LCD显示屏均涉及到各种字体的汉字显示.建立单片机汉字字库的传统方法有使 ...

  6. 0.96吋 OLED 12864 汉字 显示 优化

    辅助舍友做毕业设计中的显示部分,优化了OLED的汉字显示,简化了函数的调用方式,略有小得,留做记录.程序在最后面. 未经授权,不得转载!_(:з)∠)_ 前言 中景园的给的例程中的汉字显示函数调用方式 ...

  7. LCD / OLED显示汉字,取模软件PCtoLCD2002完美版

    一.LCD显示汉字结果展示: 二.取模软件的使用(PCtoLCD2002完美版) 1. 打开软件,模式为(字符模式) 点击菜单栏[选项],打开字模选项 勾选[阴码点阵].逐列式取模.顺向(高位在前,低 ...

  8. 0.96寸OLED显示汉字,数字,英文,图片,GIF动画+取模软件使用+代码解析

    前言 本次我们学习一下STM32F103关于OLED显示汉字,数字,英文,图片,GIF动画,和介绍各种取模软件的使用,主要教会大家使用和修改OLED驱动的代码,对汉字大小,图片分辨率进行代码修改并显示 ...

  9. c语言oled p14x16str,OLED显示汉字

    OLED显示汉字 工具:OLED 芯片:K60,XS128等 取模软件:PCtoLCD2002完美版 显示汉字需要几个条件: 汉字索引表, const byte F14x16_Idx[] = { &q ...

  10. .net 数字转汉字_[原创工具] 小熊汉字笔顺学习软件,查笔顺、学拼音、制作汉字英文数字字贴...

    点击右上角"设为星标"每日精彩内容,第一时间送达! 前言 今天带来的是原创软件.家里有上一二年级的小朋友有福了!家里有打印机的可以把设置好的字帖打印出来,小朋友即可临摹.赶紧下载使 ...

最新文章

  1. LeetCode 之 Merge Sorted Array(排序)
  2. 从零入门 Serverless | 架构的演进
  3. Apache Flink 零基础入门(十八)Flink Table APISQL
  4. Aizu - 1407 Parentheses Editor(对顶栈+模拟)
  5. 局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究
  6. 蓝桥杯 ALGO-158 算法训练 sign函数
  7. 《Python语言程序设计》——1.3 程序设计语言
  8. matlab 信号与系统(一)—— 上采样(Upsampling)和下采样(Downsampling)
  9. apache poi使用例_使用java Apache poi 根据word模板生成word报表例子
  10. LeetCode-9.回文数(大括号+双目运算符使用)
  11. android 命名空间解析,Android Bluetooth、Android AdapterView等命名空间-Android中文API文档...
  12. tif转双层pdf Java_TIF文件转双层PDF时 内存不足
  13. 自律不熬夜真的那么难吗?
  14. TMS320F28374S之X-BAR
  15. html dreamweaver模板,Dreamweaver如何制作网页模板
  16. Flutter:实现iOS无证书打包ipa
  17. python seek(0)_seek() 方法
  18. 所谓笔法在也其次-《述张长史笔法十二意》
  19. 为什么模型loss为负
  20. 计算机玩游戏特别卡怎么办,电脑玩游戏突然变卡怎么办 玩游戏变卡的解决方法...

热门文章

  1. 非标机械设计该怎么做,老机械工程师告诉你
  2. Windows 如何设置新建文本文档快捷键
  3. Android 9.0 Framwork Wifi源码学习目录
  4. ftp多线程上传、下载以及断点续传
  5. informix——ODBC数据源配置
  6. 图书管理分类统计c语言,C语言实现图书管理系统
  7. python设计模式之工厂模式概述
  8. MFC学习日志(一)
  9. mysql 游标插入数据_mysql游标插入问题
  10. SpringBoot项目启动报错