任意汉字显示给你的嵌入式系统(含MCU)装上字库
0引言
还记得通常在MCU驱动LCD,OLED是怎样显示汉字的吗?采用取字模工具,生成字模数组,然后要显示一些字符,直接索引这个字符的数组,然后对这个数组数据进行显示就行了,就像这样:
最近有开发一个物联网项目,将网络端的发过来的汉字显示到屏幕上,但问题来了,我还不知道网络端要发送具体哪些汉字,我是无法对具体的汉字取模,因此,得想办法先对所有汉字进行取模,或使用字库,于是就有了下文。
1字符编码
unicode码和ascii码区别先从字符编码说起:
ASCII码:一共规定了128个字符的编码,这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。
非ASCII码:英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。
GB2312,GBK,Unicode,UTF-8均为非ASCII编码
Unicode码:如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
注意:Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储
UTF-8码:UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式,是Unicode 的实现方式之一
GB2312,GBK:GB2312是常用汉字的专用编码,GBK是所有汉字的专用编码。
注意:GB类的汉字编码与后文的 Unicode 和 UTF-8 是毫无关系的
2液晶屏汉字显示原理
ASCII字符显示,由于ASCII字符仅128个,可以实现对每个字符一一取模,且占用MCU的RAM不会过大,此处不再介绍ASCII字符的显示。
为什么显示英文一般不用字库芯片?英文的单词都是由26个字母构成了,加上大小写的区别和其它一些字符,也不过才95个。假如要显示816像素大小的字符,每一个字符需要16个字节的字库空间,95个字符即是9516=570个字节。即占用570个字节的RAM。对于小型MCU几K字节的RAM来说,绰绰有余了。
为什么显示中文需要字库芯片?显示中文的话,需要每一个字的字模,1616像素大小的中文,每一个中文都要32个字节。GBK收录了中文两万多个,如果要都能显示,需要700多K字节的空间。所以,我们选择了把这些字库放在外部存储器当中,可选择2M的FLASH存储芯片W25Q16做为存储媒介。放个700多K的字库足够了,并且,同时放两种字体的字库都没问题。
常规汉字显示,采用相关的汉字取字模工具(PCtoLCD2002完美版),取出字模,相关参数设置如下所示:
由于我采用的液晶屏是逐行显示的,不同的液晶屏采用不同的显示模式,需根据具体情况选择字模。 取出“你”字模后,将字模数据复制到notepad++,调整成设置好的16列,21行的样式,在将16进制数据转换成2进制数据,然后将0替换成空格,即可出汉字“你”的原型。
对于液晶屏而言,字符,图片的显示都是像素点的点阵显示,因此,只要将上述数组中的数据转换成点阵数据显示到液晶屏中即可,对于二进制位1的位数据,显示出该像素点,对于二进制位0的位数据,不显示该像素点,即可显示出该汉字(暂不考虑颜显示)。
3字符显示的实现
上面讲到了字符显示的原理,接下来将讲解字符显示的实现,相关代码不依赖于底层,具有很好的移植性,且在文章最后放出了Github链接,要实现该代码的功能,需要以下前提条件:
已经在液晶屏上实现了画点功能,该函数将直接调用该功能
液晶屏在显示时,逐行扫描,且需要高位在前(参考上一节相关参数设置,其它类型的屏幕可能有所不同)
注:由于代码过长,为不影响阅读,仅放部分关键代码,如有需求,更多请参考文末的Github
for (j = 0; j < font->Height; j++)
for (i = 0; i < font->Width; i++)
if (ptr & (080 >> (i % 8)))
Paint_SetPiel( + i, y + j, Color_Foreground);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论