4204浏览
查看: 4204|回复: 5

[讨论] 写了一个SD卡软字库的类库

[复制链接]
你如果在一个月前问我Arduino,我会问你啥是Arduino?

从来没有接触过单片机,对于电子器件的知识也只是停留在初中物理阶段,只知道电阻、发光二极管,其他的就一概不知了。直到一个星期前,一个朋友带着一块电路板来找我。

他问我,怎么样才能在屏幕上直接显示中文。我告诉他,拖个控件,然后Text = “中文”就可以了。然后他从裤兜里掏出一块电路板,另外又从上衣口袋里掏出一块屏幕放在桌上,然后默默的看着我,我也默默的看着他,气氛非常的诡异。

为了打破僵局,我不得不开口问他。兄弟,我只是一个普通的程序员,我不是神仙。他说,我知道。我接着问,兄弟,吃了没?然后我们去了楼下的拉面店,用一碗面的工夫,他给我普及了Arduino的基本知识,吃完他就走了,我付的面钱。

回到楼上,我呆呆地看着桌上这堆象是被压路机碾压过的支离破碎的零件,我忍着眼泪,打开浏览器,开始为期3天的封闭式自我培训。3天后,我红着两只眼睛出关了,顺便把屋子里满地的垃圾清理了一下,感觉终于回到了人间。

通过这3天的恶补,感觉没我想象中那么困难,硬件电路部分几乎可以忽略,因为都是成品的模块和通用的接口,同时也有很多现成的类库可以调用。我的重点大部分都是软件方面的,如何打开SD卡中的字库文件,如何根据编码去找到文字的点阵信息,如何把点阵信息显示到屏幕上等等。确定好思路后,说干就干。

第一步,先搞定基本的数据传输。把这些个支离破碎的零件,一个个用线连起来,然后跑几个例程熟悉一下,单独的测试每个模块,比如怎么读SD卡,怎么在屏幕上画点等等。在选择IDE的时候,本着兼容性以及网上搜索资料的便捷性,一开始我选择的是低版本的1.0.6。但是用下来发现这是我这辈子用过的最差的IDE了,从来没见过这么难用的IDE,还不如直接用记事本写程序算了。最终不得不选择了目前最高的版本1.8.12,才勉强可以写程序。不过和其他常规的IDE比起来,这简直就是个渣渣啊,严重影响写程序的心情。

第二步,搞定字库的读取。网上搜索了一下关于各种字库的格式,最终确定使用bin格式的字库。用GuiTool转换出了宋体16*16的Unicode编码、GBK编码、GB2312编码、普通Ascii编码的几个字库文件,同时网上又下载了一个HZK16的字库文件。不过这个HZK16字库文件不能直接用,要修改一下,因为这个文件只有点阵信息,而没有字库信息。不过这个也不难,直接把GuiTool转换出来的GB2312编码的字库文件的前16个字节(也就是字库信息)复制到HZK16的字库文件最前面就可以了。我用的是试用版的GuiTool,根据这个工具的介绍,试用版会故意缺字,不过在我测试期间也没发现缺哪些字。

第三步,搞定编码转换。因为牵涉到UTF8、Unicode、GBK几种编码之间的转换,UTF8和Unicode之间没问题,毕竟两者都是Unicode编码,只是表现形式不同。GBK就不一样了,这个必须要依靠代码页文件才能转换。Windows、Mac、Linux下,系统自带了代码页文件,你可以直接调用API函数进行转换,非常的简单。但是单片机里面没有这个代码页文件,需要自己从网上去找。我用的是libiconv提供的代码页文件,然后自己重新加工了一下,以便可以在Arduino中迅速的索引这个文件。

第四步,搞定文字排版。比如强制换行、自动换行、换行后的对齐方式,还有就是旋转方向、反色显示等等,其实就是坐标的转换、以及颜色的转换。

最后一步,把所有的程序模块合并在一起,联调一下,修改一些小的BUG,就OK了。

一个星期后,我朋友准时出现在楼下的拉面店,然后用一碗面的工夫,他给我普及了这段时间他在外踏青的事情,吃完他就走了,还是我付的面钱。

回到楼上,我呆呆地看着桌上这堆开发板和零件,想起吃面的时候,他说这些零件就送给你了,我谢谢还没说出口,他唆了根面条就接着说,以后有问题,就不用再跑过来送开发板和零件了,我的眼眶禁不住又开始湿润了。

我写的这个类库有2个文件,SDFont.cpp和SDFont.h。使用的时候,把这两个文件复制到你的目录中,然后#include "SDFont.h"。

类库支持U8g、U8g2、Adafruit_ST7789,在SDFont.h中,有如下代码,选择自己使用的类库就可以了。
[mw_shl_code=cpp,false]#include <U8g2lib.h>
//#include <U8glib.h>
//#include <Adafruit_ST7789.h>[/mw_shl_code]

如果你使用的是其他屏幕驱动类库,那么只需要修改构造函数、以及GetDisplayWidth、GetDisplayHeight、DrawPixel函数,分别是用于返回屏幕的宽度、屏幕的高度、画点。

这个是1.14寸ST7789的显示效果,SPI接口
写了一个SD卡软字库的类库图1

这个是1.3寸SH1106的显示效果,I2C接口
写了一个SD卡软字库的类库图2

SDFont类库使用起来很简单,首先在你自己的程序中,先初始化SD卡和屏幕的类库,然后调用如下代码,用于初始化SDFont类库。
TSDFont SDFont(&SD, &Screen);

其次使用如下代码,来初始化字库。
[mw_shl_code=cpp,false]SDFont.SetFont("/Unicode.bin");
SDFont.SetFont("/GBK.bin", 936, "GBK", "/Ascii.bin");[/mw_shl_code]

初始化字库函数一共有4个参数:
(1)const String strFontFilename:字体文件名
(2)const int nCodePage = -1:代码页,比如936(简体中文),Unicode编码的字库是不需要代码页的
(3)const String strEncodeType = "":字库编码,目前支持GBK、GB2312、GB2312-16(简化版的GB2312字库,不含1-15区(符号、数字区),直接从第16区(汉字区)开始),Unicode编码的字库是不需要再次设置字库编码的
(4)const String strAsciiFontFilename = "":补充字库。GBK、GB2312字库中只有汉字、全角符号等点阵信息,并没有普通的英文、数字、半角符号的点阵信息,所以中英文混合时会造成无法全部显示的问题,这时候就需要一个含有普通Ascii字符点阵信息的补充字库。这个补充字库必须是MBCS非等宽编码,并且和字体文件具有相同的像素高度

最后使用SDFont.DrawText来显示文字,函数一共有11个参数:
(1)int16_t nXpos:文字左上角的X坐标
(2)int16_t nYpos:文字左上角的Y坐标
(3)const char *pcText:文字的内容
(4)const boolean boolAutoWordWrap = true:是否需要自动换行
自动换行
写了一个SD卡软字库的类库图3

不换行
写了一个SD卡软字库的类库图4

(5)const uint8_t nWordWrapAlign = 0:换行后的对齐方式,0:和屏幕边缘对齐;1:和上一排文字对齐
和屏幕边缘对齐
写了一个SD卡软字库的类库图5

和上一排文字对齐
写了一个SD卡软字库的类库图6

(6)const boolean boolReverse = false:是否需要反色显示
正常显示
写了一个SD卡软字库的类库图7

反色显示(当中黑色的斜线是拍照时候的频闪造成的)
写了一个SD卡软字库的类库图8

(7)const boolean boolTransparent = false:背景是否需要透明
不透明
写了一个SD卡软字库的类库图9

透明
写了一个SD卡软字库的类库图10

(8)const uint8_t nDirection = 0:文字旋转方向,0:0度;1:90度;2:180度;3:270度
0度
写了一个SD卡软字库的类库图11

90度
写了一个SD卡软字库的类库图12

180度
写了一个SD卡软字库的类库图13

270度
写了一个SD卡软字库的类库图14

(9)const boolean boolPosBottom = false:是否以文字的左下角为原点坐标
相同起始坐标的情况下,以左上角为原点坐标
写了一个SD卡软字库的类库图15

相同起始坐标的情况下,以左下角为原点坐标
写了一个SD卡软字库的类库图16

(10)const uint8_t nWidthScale = 1:文字的横向放大倍率
(11)const uint8_t nHeightScale = 1:文字的纵向放大倍率
横向倍率1,纵向倍率1
写了一个SD卡软字库的类库图17

横向倍率2,纵向倍率1
写了一个SD卡软字库的类库图18

横向倍率1,纵向倍率2
写了一个SD卡软字库的类库图19

横向倍率2,纵向倍率2
写了一个SD卡软字库的类库图20


类库
下载附件example.zip

字库
Unicode:下载附件Unicode.zip
GBK:下载附件GBK.zip
GB2312:下载附件GB2312.zip
HZK16:下载附件HZK16.zip
Ascii:下载附件Ascii.zip

代码页:
950(繁体中文):下载附件CP950.zip
936(简体中文):下载附件CP936.zip
932(日语):下载附件CP932.zip
949(韩语):下载附件CP949.zip



编译环境
系统:MacOS 10.11
IDE:Arduino IDE 1.8.12
U8g:1.19.1
U8g2:2.27.6
Adafruit ST7789:1.5.15

rzyzzxw  版主

发表于 2020-6-16 12:17:19

喜欢开头的故事
回复

使用道具 举报

hnyzcj  版主

发表于 2020-6-16 17:24:46

rzyzzxw 发表于 2020-6-16 12:17
喜欢开头的故事

结尾的你不喜欢吗
回复

使用道具 举报

铁熊  初级技神

发表于 2020-6-16 17:26:59

好玩的故事,硬核的技术!好文章要点赞支持
回复

使用道具 举报

rzyzzxw  版主

发表于 2020-6-16 18:10:59

hnyzcj 发表于 2020-6-16 17:24
结尾的你不喜欢吗

太硬核,咬不动
回复

使用道具 举报

20060606  高级技匠

发表于 2020-8-1 05:17:29

wow,您的进步够快的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail