• GD32(6)中文字库


    字符显示

           在OLEDLCD这两篇文章中,我们介绍了通过不同屏幕显示的方法,简单来说都是控制像素点的亮灭或颜色值,通过排列来显示相应的内容。其中显示字符所使用的像素点排列,被称为字模,也可以称为点阵数据。

           在OLED一文的最后,我们介绍了字模的获取工具PCtoLCD,通过该软件可以获得对应字符(包括汉字)的字模,当然英文字符、数字以及特殊字符,一般都将其字模存储在.h文件中,即保存在微控制器内部存储器中,通过ASCII的顺序进行调用,但是,通过这种方法显示中文字符比较困难。

           首先中文字符数量较多,仅常用字就已多达6000个左右,此外,还有众多生僻字和繁体字。其次,因为数量多,因此通过ASCII方式进行顺序排列并检索十分不方便。因此对中文字符的显示,一般通过GBK编码进行排列,下面介绍GB2312编码和GBK编码的使用。

    关于GB2312编码和GBK编码的区别可参考彻底搞明白 GB2312、GBK 和 GB18030

    中文字符编码

    GB2312

           GB2312简体中文编码表

           GB2312编码方式使用区位码来查找字符,通过将字符分为94个区,每个区含有94个字符,总共8836个编码,表达8836个字符(当然,实际上只有6763 个常用的汉字和字符对应的编码可用)。在使用过程中,字符编码的第一字节(高字节)为区号,第二字节(低字节)为位号,根据对应的区号和位号即可查找到对应的字符。区位码定位图如下图所示,其中16代表的是区号。以“啊”字为例,“啊”字对应的位为01,因此“啊”字对应的区位码为“1601”。由于GB2312编码向下兼容ASCII码,因此,在实际的GB2312编码中,将区号和位号同时加上“0xA0”来区别ASCII编码段。最终“啊”字的GB2312编码为0xB0A1。

    在这里插入图片描述

    GBK

           GBK编码是从GB2312基础上产生的,可以保存20000多个汉字,包括生僻字和繁体字,并同时兼容GB2312和ASCII编码方式。

           GBK编码使用1字节或2字节空间来保存字符,使用1字节时,保存的字符与ASCII码对应;使用2字节时,保存的字符为中文及其他字符,在其编码区中,第一字节(区号)范围为0x81~0xFE。由于0x7F不被使用,因此第二字节(位号)分为两部分,分别为0x40~0x7E和0x80~0xFE(以0x7F为界)。并且其中与GB2312编码区重合的部分,字符相同,因此可以说GB2312码是GBK码的子集。

    0x7F不使用的原因:0x7F在ASCII中表示DEL,向后删除一个字符。
    并且不止0x7F,0x08等控制字符同样需要避免使用。

    中文字库

           与显示英文需要提供所有的英文字符一样,显示中文时同样需要提供所有的中文字符,由于中文字符太多,因此其字模一般被统一存储在一个文件中,该文件被称为字库文件,当需要显示某个中文字符时,根据上述的区位码从该字库中取出相应字符并绘制即可。

    注意,字库的大小不是固定的(这句话听起来很奇怪,但我是指同一种编码都不一样),字库的大小不仅由编码方式决定(如GBK一般都要大于GB2312),还有字体大小决定。若每个字通过100个像素点决定(也就是10 * 10),那么GB2312的6737个字符,需要 6737 * 100 / 8 / 1024 = 82 KB,这对大部分微控制器来说,都是难以承受的。

    字库生成

           中文字库的生成和英文字模的生成相同,可以通过软件快捷生成,当然这里的软件不再是PCtoLCD那样单个字符生成,而是直接生成整个字库。

           字库的生成可以使用“高通字库”,免费,打开后如下图所示。

    在这里插入图片描述

           点击左边的第二项并根据要求设置字模格式即可,参考设置如下:

    在这里插入图片描述

    注意:左上角字号的大小需要与预览下面,点阵样式中的点阵宽度和高度相匹配,计算公式为:

    字号大小 = 点阵大小 * 6/8

    当然,如果不相匹配也不是不可以,但显示出来会奇怪一点,可以在上面的预览界面查看。

           设置结束后点击右下角即可生成字库,生成.c文件的话大小约为8.31MB的数组,一般建议生成Bin文件后将其后缀修改为FON,形成字库文件。除了生成对应文件外,还会生成一个txt文件,里面存放着提示信息。

    这里生成的FON文件大约是1.51MB,同样是微控制器难以存储的,因此需要将其存储在外部存储器中。

    字模获取

           这里的字模获取是指如何从代码中获取对应中文字符的字模,参考txt文件中的提示信息可得,字库被分为 6 段,以其中第一段“0xA1A1 - 0xA9FE”为例,该段中的某个字符的地址addr计算方法如下,其中94是由于每个区都有94个字符,72是区内每个字符字模的字节数。(24 * 24 / 8 = 72Bytes)

    addr = ((gbkH - 0xA1) * 94 + (gbkL - 0xA1)) * 72

           代码参考如下,其中,通过GD25Q16Read是由于字库被存储在GD25Q16芯片中。

    void GetCNFont24x24(u32 code, u8* buf)
    {
      u8  gbkH, gbkL; //GBK码高位、低位
      u32 addr;       //点阵数据在SPI Flash中的地址
      u32 i;          //循环变量
    
      //拆分GBK码高位、低位
      gbkH = code >> 8;
      gbkL = code & 0xFF;
    
      //校验高位
      if((gbkH < 0x81) || (gbkH > 0xFE))
      {
        for(i = 0; i < 72; i++)
        {
          buf[i] = 0;
        }
        return;
      }
    
      //低位处在0x40~0x7E范围
      if((gbkL >= 0x40) && (gbkL <= 0x7E))
      {
        addr = ((gbkH - 0x81) * 190 + (gbkL - 0x40)) * 72;
        GD25Q16Read(buf, 72, addr);
      }
    
      //低位处在0x80~0xFE范围
      else if((gbkL >= 0x80) && (gbkL <= 0xFE))
      {
        addr = ((gbkH - 0x81) * 190 + (gbkL - 0x41)) * 72;
        GD25Q16Read(buf, 72, addr);
      }
    
      //出错
      else
      {
        for(i = 0; i < 72; i++)
        {
          buf[i] = 0;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    至于这里的code是从哪里来的,GBK编码的文件,对应字符存储的就是code。

  • 相关阅读:
    知网CN期刊《新阅读》简介及投稿邮箱
    【文献翻译】Concealed Object Detection(伪装目标检测)
    AtCoder Beginner Contest 266 A-G
    使用Signposts分析App性能
    【附源码】计算机毕业设计java中国朝鲜族民族特色服务系统设计与实现
    计算机毕业论文java毕业设计选题源代码javaweb企业门户网站官网
    今天学习了excel的公式和函数,常用的还没学完,先做好笔记,都是比较常用的东西,对未来分析数据很有用,明天继续加油
    【Android取证篇】华为设备跳出“允许USB调试“界面方法的不同方法
    【Java开发】 Spring 05 :Project Reactor 响应式流框架(以Reactive方式访问Redis为例)
    docker安装jenkins以及Permission denied错误的解决方法!
  • 原文地址:https://blog.csdn.net/weixin_47447179/article/details/126556712