这个问题以为很简单,但最后花很多功夫才能完成,所以总结一下分享给大家。
UTF-8->Unicode->GB2312->点阵编码,其中Unicode转GB2312要转码表,GB2312转点阵编码要HZK16字库。
代码:https://github.com/lyaohe/UTF-8toGB2312
经多番研究,OLED显示屏显示中文最简单还是用HZK16字库转点阵编码,这里有一个算法:
《UCDOS下点阵字库在嵌入式OLED应用中的移植》
http://www.cqvip.com/read/read.aspx?id=25100512#
想要完整的算法,自行搜索。
当时使用这个算法,在Linux下测试,不对,在Windows测试,转换编码正确。
那就奇怪了,经具体了解发现HZK16字库是符合GB2312标准的16×16点阵字库
在Linux下使用UTF-8编码,肯定不对啦,于是找UTF-8的点阵字库,没有找到,只好用UTF-8转GB2312。
在Fedora,有系统函数转换字符编码,iconv轻松把UTF-8转GB2312,可是编译到板子上始终没有转换成功。
又陷入难题,研究发现,使用uclibc库有iconv函数,但不支持GB2312,气馁。
网上有同学编译libiconv库,可是编译出来有1M+,有点大,占太空间了。
又要重新思考如何解决,连同事也叫我先放弃这个,先完成其他工作。
我还是不放弃,感觉快要完成,就卡那里,很不服气。
想尝试自己动手写函数实现UTF-8转GB2312,找资料发现可以实现的。
思路是UTF-8转Unicode,Unicode转GB2312,Unicode转GB2312需要转换表
测试UTF-8转Unicode函数,转换成功。
再到Unicode转GB2312,可是网上只有GB2312转Unicode转换表,要自己动手改成Unicode转GB2312编码表,也顺便要排个顺利,可以二分查找,更快转换成GB2312。
Unicode转GB2312其实就是查找,使用二分查找,拿到GB2312的编码,但不会使用这个编码,与直接打印出来编码不同。
经研究GB2312编码才发现,弄懂几个知识点,原始编码,通行编码,机内码。
//机内码与通行码的关系
unsigned char* str="啊";
printf("0x%X%X\n",str[0],str[1]); //机内码
printf("0x%X%X\n",str[0] & 0xff,str[1] & 0xff ); //通行编码
也终于解决Unicode转GB2312的转换。
最后把代码都整合起来就行了,我也把代码分享出来,托管到Github,自行参考。
https://github.com/lyaohe/UTF-8toGB2312