完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嵌入式汉字显示原理及GBK编码详解
(1)显示原理 屏幕都是有一个一个像素点组成的,不管是中文还是英文显示,其实都是把字符通过字模软件或者字库制作软件转换成了一个点阵,一个像素点就代表一个比特,例如字体为8X16像素点大小,那么点阵大小也是8X16,然后在LCD上打点显示,这样就能显示出字符来了。 如果只显示ASCII,也就是只显示英文和符号,那么就只有下面这96个可显示字符,将这96个字符进行点阵取模,就组成了ASCII字库。 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ 对于只显示英文的使用情况下,倘若字体大小为8X16像素, 那么以8X16点阵大小来对这96个ASCII字符取模, 一个字符的点阵所占用的空间就是8x16/8=16字节,总占用空间就是96x16=1536字节, 这么算下来的话也就不到2K的空间,对于单片机FLASH来说能够存下。 但是如果是想要能够显示全部中文,那中文汉字的个数就多了去了,GBK汉字库收录了21886个汉字,由于中文汉字是正方形的,所有取模的话就得是1:1的点阵,要不然不好看,字是扁的! 还是以16X16点阵大小来算,16X16/8X21886=700352字节!不到684K的大小,这对于单片机的FLASH来说无比巨大了,根本存不下! 所以常见的解决办法是存到SPI接口的FLASH中,例如W25QXX系列。 (2)字符寻址 问题:使用字模软件制作好点阵字库之后,如何使用字库? 对于这个问题,中文显示和英文显示要分开来讲。 2.1 英文(ASCII)字符寻址 对于ASCII字符显示,将8X16大小的ASCII字库生成一个大的数组之后,由于每个字符占用16字节大小,所以空格【 】的偏移地址就是0,叹号【!】的偏移地址就是16,以此类推; 由于ASCII字符顺序固定,那么就可以用要显示的字符减去空格就能得到偏移地址索引,然后偏移地址索引在乘该字符的点阵大小就能得到在字库中的实际偏移地址。 例如:要显示字符【A】这个字符,那么A字符的点阵数据的偏移地址就是: int offset = 'A' - ' '; 从offset地址开始往后的16个字节,就是字符A的点阵数据,然后将这16字节在屏幕上打点就显示出来了。 2.1 中文(GBK)字符寻址 注:GBK是GB2312的扩展。 对于中文GBK汉字显示,要找到显示的汉字点阵数据在字库中的位置,就无法直接用减法了,那么是怎么找的呢? 介绍怎么找偏移之前,需要先了解一下GBK编码。 GBK 和GB2312一样亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。 上面介绍了GBK的编码及个数,猛一看可能会有点蒙,下面我用一个实例来解释一下。 首先记住下面几点:
这里还有一个需要注意的问题,有的中文字库制作软件它不会将每个区0X7F这个没有用到的位置算进去,这个时候每个区的大小就是190,那么这种方式制作的字库计算偏移位置方式就是: // // 参数说明: // gbkl :GBK低字节 // gbkh :GBK高字节 // width:字体宽度 // hight:字体高度 // 返回值:偏移地址 // uint32_t getoff(uint8_t gbkl, uint8_t gbkh, uint32_t width, uint32_t hight) { if(gbkl < 0X7F) gbkl -= 0X40; else gbkl -= 0X41; return ((gbkh - 0X81) * 190 + gbkl) * (width * hight / 8); } 而有的字库制作软件他就会将0X7F也算进去,所以每个区的大小就是191,那么计算偏移地址就是: uint32_t getoff(uint8_t gbkl, uint8_t gbkh, uint32_t width, uint32_t hight) { return ((gbkh - 0X81) * 191 + (gbkl - 0X40)) * (width * hight / 8); } 他制作的这个字库生成软件就是把0X7F也算进去的。 我个人很推荐他开发的这个软件,因为生成字库非常快! 附上0.96寸OLED字库取模设置: ends… |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:01 , Processed in 1.089091 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号