1 显示图片
1.1 图片取模
1)生成 bmp 点位图
- (1)找到一张图片,在 PS(在线 PS:https://www.photopea.com/) 中打开:
- (2)二值化处理:图像 -> 调整 -> 阈值,调整阈值
- (3)大小调整:图像 -> 图像大小,调整到最大不能超过 64 x 64
- (4)导出 bmp:文件 -> 导出为 -> 更多 -> bmp
- 2)打开 bmp 图像:
- (1)打开 “PCtoLCD2002完美版” 软件
- (2)打开 bmp 图像:如果打开失败,就把图片用 Windows “画图” 软件重新另存一下。
- 3)取模:记得选择 “阳码”,要不太丑了。
2 字符集与编码
2.1 字符编码
- 1)字符集:顾名思义,字符的集合。比如将一副中国象棋随意放置在棋盘上。
- 2)编码:按照一定的规则给字符集排序。这里的规则即为编码方式,同一个汉字可以有 GB2312、GBK、GB18010,还可以有 UTF-8、UTF-16、UTF-32 编码方式。就好像我们人为规定中国象棋上棋子的位置,这样当我们指定一个位置时,就可以取到已知的棋子。
2.2 ASCII
- 1)ASCII:1 个字节,其中 32~127 表示空格、数字、标点、字母等可显示字符
2.3 中文编码
2.3.1 GB2312 标准
1)GB2312 标准:
- (1)小于 0x7F 的编码仍旧为 ASCII
- (2)取消 0x7F 到 255 的扩展字符集
- (3)两个大于 0x7F 的字节连在一起表示一个汉字,其中字节的取值范围为 0xA1 ~ 0xFE,可以表示 7000+ 符号,其中汉字 6763 个
- (4)ASCII 里面原本有的数字、字母等也重新编码成 2 个字节,即 “全角” 字符
2)区位码:GB2312 编码对收录字符进行了 “分区” 处理
- (1)一共 94 个区,每区 94 个位,一共 8836 个码位
- (2)GB2312 编码实现:高字节对应 94 个区,低字节对应 94 个位;则 GB2312 的区位码范围为 0101 ~ 9494。同时为兼容 ASCII,区号和位号分别加上 0xA0 偏移,即 0xA1A1 ~ 0xFEFE。
- (3)汉字的编码范围为 0xB0A1 ~ 0xF7FE。高字节0xB0 ~ 0xF7(区号 16 ~ 87),低字节 0xA1 ~ 0xFE(区号 01 ~ 94)
- (4)“啊” 字位于 16 区的 01 位,则其区位码为 1601,加上 0xA0 偏移后为 0xB0A1
3)码位示意图:
- 当生成字库时,要注意 0xXXA0、0xXXFF 要直接跳过,0xD7FA~0xD7FE 要设置占位数据
- 当生成字库时,要注意 0xXXA0、0xXXFF 要直接跳过,0xD7FA~0xD7FE 要设置占位数据
- 4)GB2312 字符集:https://www.toolhelper.cn/Encoding/GB2312
2.3.2 GBK 编码
- 1)GBK 编码方式:在 GB2312 标准上增加 14240 个新汉字(包括Big5)和符号
2)GBK 编解码:
- 编码:不再要求低字节编码必须大于 0x7F,只要高字节大于 0x7F 即可。这样即可兼容 ASCII 和 GB2312 标准
- 解码:按字节遍历字符串,当遇到一个字符大于 0x7F 时,就再读取它后面的一个字符,两个字符合起来,用 GBK 解码。
- 3)码位示意图:
- 4)GBK 字符集:https://www.toolhelper.cn/Encoding/GBK
2.3.3 GB18030
- 1) GB18030 的编码使用 4 个字节,它利用前面标准中的第 2 个字节未使用的 “0x30-0x39” 编码表示扩充四字节的后缀,兼容 GBK、 GB2312 及 ASCII 标准。
2.4 Unicode 字符集和编码
- 1)Unicode 字符集:国际标准化组织(ISO)舍弃地区性方案,重新给全球所有文化使用的符号进行编号,对每一个字符指定唯一的编号(ASCII 字符编号不变),编号从 0x000000 到 0x10FFFF,称为 Unicode。
- 2)Unicode 字符集只是对字符进行编号,但没有指定对字符的编码,常见的编码方式有 UTF-32、UTF-16、UTF-8。
2.4.1 UTF-32
1)Unicode 字符集每个字符都用 4 个字节来表示。
- 不兼容 ASCII
- 浪费存储空间,大量常用字符只需要 2 个字节就能表示。
- 存储时需要指定字节顺序
2.4.2 UTF-16
1)用 2 个或 4 个字节表示。
- 0 ~ 0xFFFF 使用 2 个字节表示
- 将 0xD800 ~ 0xDBFF 映射到 Unicode 字符集中编号超出 0xFFFF 的字符
- 2)解码:读取两个字节,如果不在 0xD800 ~ 0xDBFF,则以双字节解析,找到对应编号的字符;如果在,则以 4 字节解析
- 3)节约空间。但仍然不兼容 ASCII,仍有大小端格式
2.4.3 UTF-8
- 1)变长:1、2、3、4 字节长度
2)编码方式:
- (1)单字节:最高位为 1,其余位表示 Unicode 编号。即对于 Unicode 编号为 0x0000000 ~ 0x0000007F 的字符,UTF-8 只需要 1 个字节,兼容 ASCII
- (2)N 个字节:最高字节的前 N 位为 1,第 N+1 位为 0;其它字节前两位为 10;剩余的 N 个字节的其余空位填充 Unicode 编号。
Unicode | UTF-8 | ||||
---|---|---|---|---|---|
编号范围 | 第一字节 | 第二字节 | 第三字节 | 第四字节 | 第五字节 |
0000 0000 - 0000 007F | 0xxx xxxx | ||||
0000 0080 - 0000 07FF | 110x xxxx | 10xx xxxx | |||
0000 0800 - 0000 FFFF | 1110 xxxx | 10xx xxxx | 10xx xxxx | ||
0001 0000 - 0010 FFFF | 1111 0xxx | 10xx xxxx | 10xx xxxx | 10xx xxxx | |
0020 0000 - 03FF FFFF | 1111 10xx | 10xx xxxx | 10xx xxxx | 10xx xxxx | 10xx xxxx |
3)解码:
- 如果第一个字节 >> 7 为 0,则以单字节解析
- 如果第一个字节 >> 5 为 0b110,则以双字节解析
- 如果第一个字节 >> 4 为 0b1110,则以三字节解析
- 如果第一个字节 >> 3 为 0b11110,则以四字节解析
3 字库 DIY
参考:
3.1 生成字库
在编写 OLED 驱动时,需要以 “纵向,先上下后左右,低位在前” 的方式制作 Unicode 和 GBK 编码字库,市面上有不少生成字库的软件,没有找到合适的。
1)源码地址:https://gitee.com/luyaocf/oled_font_library.git
基于 Python 开发,可以下载下来定制化运行,也可以下载我打包的发行版。软件界面如下:
原理简要说明:
- (1)字符的编码可以理解成整数,如 “路” 在 GBK 编码中为 0xC2B7。那么我们以指定的编码 GBK、大小端的将该整数转换为汉字即可。遍历 GBK 编码的范围的所有整数即可得到所有的 GBK 编码汉字(记得剔除掉其中未编码的数,如 GBK 中的 0xXX7F, 0xXXFF 等位置。)
(2)以指定的像素大小(如 16x16)生成一张图片,然后将指定汉字显示到上面,再对图片进行二值化处理(有内容的像素点为 1,无内容的像素点为 0),最后生成一个字节数组。
- 显示汉字到图片上时可以指定字体,如宋体、楷体等(我试过,只有宋体能看)
- 图片二值化后生成的 16x16 字节数组如下,看出什么字没有^_-
(3)根据指定的显示方式(先左右还是先上下,高位在前还是低位在前,纵向还是横向等),将上述的字节数组转换成点阵数组。
- 转换时要注意,字节数组每个字节只表示一个像素,而且是横向保存的。如果显示方式是纵向,要注意遍历方式。
3.2 烧录到 W25Qxx
制作的字节在电脑本地,怎么让单片机使用呢?写入到单片机可访问的板上存储器件即可。这里我选择通过 SDCard 写入到板上 W25Q64 中。
1)字库地址分配(8M 的 W25Q64)
- Unicode 的范围,0x4E00 ~ 0x9FFF,约 2 万个汉字
- GB2312 的范围,0xB0A1 ~ 0xF7FE,约 6700 个常用汉字
W25Q64 地址 | 字符 | 点阵大小 |
---|---|---|
0x007FF000 ~ 0x0068D000 | unicode 24 | 1480k(0x00172000) |
0x0068D000 ~ 0x005E8000 | unicode 16 | 660k(0x000A5000) |
0x005E8000 ~ 0x0056B000 | unicode 12 | 500k(0x0007D000) |
0x0056B000 ~ 0x003C4800 | gbk 24 | 1690k(0x001A6800) |
0x003C4800 ~ 0x00309000 | gbk 16 | 750k(0x000BB800) |
0x00309000 ~ 0x0027A800 | gbk 12 | 570k(0x0008E800) |
0x0027A800 ~ 0x001E9800 | gb2312 24 | 580k(0x00091000) |
0x001E9800 ~ 0x001A8800 | gb2312 16 | 260k(0x00041000) |
0x001A8800 ~ 0x00176800 | gb2312 12 | 200k(0x00032000) |
total font_lib_size: 6.53MB(0x00688800)
2)源码地址:https://gitee.com/luyaocf/demo-jlc_stm32f407_fontlib.git
- 该程序基于嘉立创天空星 STM32F407,其它芯片请自行移植。
- 将字库文件放置到 SDCard 的根目录,上电,等待绿色 LED 闪烁即表示字库复制完成,也可连接串口线观察烧录日志。
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。