zoukankan      html  css  js  c++  java
  • 【第3版emWin教程】第29章 emWin6.x的XBF格式全字库生成和使用方法(Unicode编码,SPI Flash方案)

    教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

    第29章       emWin6.x的XBF格式全字库生成和使用方法(Unicode编码,SPI Flash方案)

    本章节为大家讲解XBF格式全字库的生成和使用方法。XBF格式字库可以存储到任何外部存储介质中,带不带文件系统都没有关系,且XBF格式字体支持抗锯齿效果,显示大字体的时候效果非常棒。XBF格式字体也是用FontCvt生成的,编码为Unicode。本章节以SPI Flash为例给大家进行讲解(SPI Flash就是SPI接口的Flash存储芯片)。

    29.1  初学者重要提示

    29.2 下载算法存放位置(操作前必看)

    29.3  XBF格式字体生成方法

    29.4 不同XBF格式字体的合并方法

    29.5  XBF格式字体使用方法

    29.6  内部Flash和SPI Flash程序调试下载配置(重要必看)

    29.7 实验例程说明(RTOS)

    29.8 实验例程说明(裸机)

    29.9 总结

    29.1 初学者重要提示

    1、  字体小工具需要使用此贴提供的,其它大部分是Demo版本:

    http://www.armbbs.cn/forum.php?mod=viewthread&tid=107218

    2、  STM32H7驱动SPI Flash的MDK下载算法制作方法已经发布,详见第84章。

    http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

    3、  下载本章节相关例子前,务必先添加好SPI Flash的下载算法。本章使用的方法支持内部Flash和外部SPI Flash可以同时下载。如此以来,大家可以方便的将字库,图库和主题存到外部SPI Flash,简单易用,大大方便大家项目实战。

    4、  本章节配套的例子是将XBF格式字库烧写到不带文件系统的SPI Flash里面进行测试,效果比较好,也比较流畅。实际项目切不可给SPI Flash加上文件系统后使用XBF格式字体,否则会比较卡顿。

    5、  emWin官方提供的字体生成软件FontCvt不支持GB编码,所以只能使用FontCvt支持的Unicode编码。

    6、  教程中让大家将要显示汉字的C文件转换为UTF-8编码,指的是将这个汉字所在的C文件转换为UTF-8编码,这点要切记,详情请看28.4小节的说明。

    另外特别注意MDK5编译错误missing closing quote,解决办法看本章教程28章的第28.6.2小节。

    7、  XBF格式所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数的位置

     

    下图是英文版手册里面API函数的位置:

     

    29.2 下载算法存放位置(操作前必看)

    (注:例子下载地址 http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

    编译例子:V7-065_SPI Flash的MDK下载算法制作,生成的算法文件位于此路径下:

     

    生成算法文件后,需要大家将其存到到MDK安装目录,有两个位置可以存放,任选其一,推荐第2种:

    •   第1种:存放到MDK的STM32H7软包安装目录里面:KeilSTM32H7xx_DFP2.6.0CMSISFlash(软包版本不同,数值2.6.0不同)。
    •   第2种:MDK的安装目录 ARMFlash里面。

     

    29.3 XBF格式字体生成方法

    下面以生成16点阵,宋体为例来说明使用FontCvt生成XBF格式字体的方法。

    1、  第1步:打开字体生成软件FontCvt,选择字体类型Standard,编码选择16bit Unicode。

     

    点击OK后,弹出如下窗口:

     

    再点击确定后弹出FontCvt界面变成如下效果:

     

    2、  第2步:点击File->Save As

     

    弹出如下窗口:

     

    生成字体的过程中,左下角会有一个Unicode编码值从0x0000开始递增的过程,转换结束后显示Ready。

     

    此时桌面就会生成XBF字库了。如果要生成的点阵字体比较大,此过程比较慢。本次转换生成的文件如下:

     

    同样的方法再生成24点阵和32点阵的字体:

     

    本章节配套的例子把这三种生成的字体都进行了测试。

    29.4 不同XBF格式字体文件的合并方法

    本小节讲解如何将上面小节生成的三种点阵字体合并成一个bin文件。合并成一个文件比较有实际意义,本章节配套的例子是将三种点阵字体都加载到SPI Flash里面,合并成一个bin文件后,加载一次就可以了。

    1、  第1步:登陆网址http://www.armbbs.cn/forum.php?mod=viewthread&tid=8627 下载小软件--->文件合并助手。

    2、  第2步:打开文件合并助手,加载本章29.2小节生成的三种字体

     

    添加字库后,效果如下:

     

    输出窗口已经自动生成了对应字体的首地址。这个地址要保存好,后面要用到。

    3、  第3步:点击右下角的合并,会弹出一个窗口

     

    点击保存后,桌面后生成一个font.bin的文件:

     

    注意,合并后的这个文件不要超过8MB,因为本教程配套板子的SPI Flash大小是8MB。这个文件的实际大小大约是7.89MB,没有超过8MB。

    29.5 XBF格式字体使用方法

    XBF格式字体的使用通过下面五步就可以实现:

    1、  第1步:定义16点阵,24点阵和32点阵的XBF格式字体

    /* 宋体16点阵定义 */
    #define   XBF_Font16BaseAdd    0x00000000
    GUI_XBF_DATA XBF_Data16;
    GUI_FONT     XBF_Font16;
    void         *Fontfile16;
    
    /* 宋体24点阵定义 */
    #define   XBF_Font24BaseAdd    0x0015B7B6
    GUI_XBF_DATA XBF_Data24;
    GUI_FONT     XBF_Font24;
    void         *Fontfile24;
    
    /* 宋体32点阵定义 */
    #define   XBF_Font32BaseAdd    0x003CEF64
    GUI_XBF_DATA XBF_Data32;
    GUI_FONT     XBF_Font32;
    void         *Fontfile32;

    每个字体都是三个变量和一个宏定义,宏定义用来设置字体的首地址,也就是29.3小节时给大家强调的。

     

    另外三个变量的定义是创建XBF格式字体必须的,变量名可以任意定义,但是这三个变量不能少。其中指针类型变量 void *Fontfile16,void *Fontfile24和void *Fontfile32都没有用到,如果使用了文件系统就用到了,这三个变量是用来定义文件系统变量的,比如使用FatFS文件系统,这三个变量就应该修改为FIL Fontfile16,FIL Fontfile24和FIL Fontfile32。

    2、 第2步:创建16点阵,24点阵和32点阵的XBF格式字体

    /*
    *********************************************************************************************************
    *    函 数 名: _cbGetData16
    *    功能说明: XBF字体的回调函数, 16点阵
    *    形    参: Off      - 地址偏移 
    *             NumBytes - 需要读出的字节数
    *             pVoid    - 指针变量,一般用于带文件系统时的FIL类型变量
    *             pBuffer  - 获取字体的点阵数据
    *    返 回 值: 0 表示成功 1 表示失败
    *********************************************************************************************************
    */
    static int _cbGetData16(U32 Off, U16 NumBytes, void * pVoid, void * pBuffer)
    {    
        /* 读取点阵数据 */
        sf_ReadBuffer(pBuffer, XBF_Font16BaseAdd + Off, NumBytes);
        return 0;
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: _cbGetData24
    *    功能说明: XBF字体的回调函数, 24点阵
    *    形    参: Off      - 地址偏移 
    *             NumBytes - 需要读出的字节数
    *             pVoid    - 指针变量,一般用于带文件系统时的FIL类型变量
    *             pBuffer  - 获取字体的点阵数据
    *    返 回 值: 0 表示成功 1 表示失败
    *********************************************************************************************************
    */
    static int _cbGetData24(U32 Off, U16 NumBytes, void * pVoid, void * pBuffer)
    {    
        /* 读取点阵数据 */
        sf_ReadBuffer(pBuffer, XBF_Font24BaseAdd + Off, NumBytes);
        return 0;
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: _cbGetData32
    *    功能说明: XBF字体的回调函数, 32点阵
    *    形    参: Off      - 地址偏移 
    *             NumBytes - 需要读出的字节数
    *             pVoid    - 指针变量,一般用于带文件系统时的FIL类型变量
    *             pBuffer  - 获取字体的点阵数据
    *    返 回 值: 0 表示成功 1 表示失败
    *********************************************************************************************************
    */
    static int _cbGetData32(U32 Off, U16 NumBytes, void * pVoid, void * pBuffer)
    {    
        /* 读取点阵数据 */
        sf_ReadBuffer(pBuffer, XBF_Font32BaseAdd + Off, NumBytes);
        return 0;
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: GUI_SetXBF
    *    功能说明: 创建XBF字体
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void GUI_SetXBF(void) 
    {
    
        /* 创建16点阵字体 */
        GUI_XBF_CreateFont(&XBF_Font16,           /* GUI_FONT类型变量     */
                         &XBF_Data16,          /* GUI_XBF_DATA类型变量 */
                         GUI_XBF_TYPE_PROP,    /* 字体类型             */
                         _cbGetData16,         /* 回调函数             */
                         &Fontfile16);         /* 回调函数参数         */
        
        /* 创建24点阵字体 */
        GUI_XBF_CreateFont(&XBF_Font24,           /* GUI_FONT类型变量     */
                         &XBF_Data24,          /* GUI_XBF_DATA类型变量 */
                         GUI_XBF_TYPE_PROP,    /* 字体类型             */
                         _cbGetData24,         /* 回调函数             */
                         &Fontfile24);         /* 回调函数参数         */
        
        /* 创建32点阵字体 */
        GUI_XBF_CreateFont(&XBF_Font32,           /* GUI_FONT类型变量     */
                         &XBF_Data32,          /* GUI_XBF_DATA类型变量 */
                         GUI_XBF_TYPE_PROP,    /* 字体类型             */
                         _cbGetData32,         /* 回调函数             */
                         &Fontfile32);         /* 回调函数参数         */
    }

    创建XBF字体要用到函数:GUI_XBF_CreateFont,关于这个函数有必要说说,函数的原型如下:

    int GUI_XBF_CreateFont(GUI_FONT * pFont,
                           GUI_XBF_DATA * pXBF_Data,
                           const GUI_XBF_TYPE * pFontType,
                           GUI_XBF_GET_DATA_FUNC * pfGetData,
                           void * pVoid);
    •   第1参数和第2个参数比较好理解,填写我们前面定义的变量就行。
    •   第3个参数要特别注意,参数类型一定要跟FontCvt创建时的字体类型对应。此参数有以下五种类型。

    GUI_XBF_TYPE_PROP

    GUI_XBF_TYPE_PROP_EXT

    GUI_XBF_TYPE_PROP_FRM

    GUI_XBF_TYPE_PROP_AA2_EXT

    GUI_XBF_TYPE_PROP_AA4_EXT

    而FontCvt创建的时候有以下七种类型:

     

    对应关系是

    GUI_XBF_TYPE_PROP = Standard

    GUI_XBF_TYPE_PROP_EXT = Extended

    GUI_XBF_TYPE_PROP_FRM = Extended,framed

    GUI_XBF_TYPE_PROP_AA2_EXT = Extended,antialiased,2bpp

    GUI_XBF_TYPE_PROP_AA4_EXT = Extended,antialiased,4bpp

    初学者使用的时候,一定要注意这个问题。另外要注意,字体类型antialiased,2bpp和antialiased,4bpp是不支持XBF格式字体的。

    •   第4步是回调函数,用户要在这个回调函数里面实现XBF字体点阵数据的读取,这里是从SPI Flash中读取点阵数据的。
    •   第5个参数是回调函数的一个形参,如果XBF文件是存储到不带文件系统的的存储介质中,这个参数是用不到的,如果带文件系统的话,这个参数是要用到的。实际项目中,不推荐将XBF字体存储到带文件系统的存储介质中,实际测试发现,稍大点的字体都会使得界面效果比较卡顿,不实用。如果进一步了解的话,参考emWin教程V1.0版本里面的第20章配套的例子,那个例子是将XBF字体存到SD卡中并使用文件系统Fatfs进行访问的,地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=2932

    3、  第3步:加载到SPI Flash后,使用就比较简单了。

    用户只需调用函数GUI_UC_SetEncodeUTF8()使能UTF-8编码就可以使用XBF格式的字体了,比如设置按钮的字体,调用如下设置函数即可。

    BUTTON_SetFont(hWin,  &XBF_Font32);  /* hWin是按钮的句柄 */

    4、  第4步:最后一步切不可忘记设置汉字显示所在源文件的编码类型,具体MDK和IAR的设置方法请看第28章的28.4小节(本章节配套的例子也是设置的MainTask,c文件),这一步绝对不可以省略。

    通过这五步就实现XBF格式字体的显示了。另外还要注意一点,默认情况下,创建XB格式字体,每个字符的点阵数据最大值限制为200字节,可以满足大部分要求。如果加载使用更多字节的字符,通过在文件GUIConf.h添加以下宏定义可修改默认值:

    #define GUI_MAX_XBF_BYTES  500   /* 重新设置支持的最大字节数 */

    默认的定义在文件GUI_ConfDefaults.h文件里面:

    #ifndef   GUI_MAX_XBF_BYTES

      #define GUI_MAX_XBF_BYTES 200

    #endif

    29.6 内部Flash和SPI Flash程序调试下载配置(重要必看)

    将下面两个地方配置后,就可以像使用内部Flash一样使用SPI Flash进行调试了。并且这种方式可以方便的调试程序,内部Flash和外部Flash都做调试。

    29.6.1        将字库文件转换为C数组格式文件

    为了方便将bin文件添加到MDK工程中,我们这里使用小软件B2C.exe将其转换为C格式文件(此软件已经放到本章配套例子V7-534_emWin6.x实验_XBF格式全字库生成和使用方法,Unicode编码(SPI Flash RTOS)的Doc文件里面。

     

    转换后生成的文件为font.c :

    const unsigned char _acfont[8277280UL + 1] = {
      0x47, 0x55, 0x49, 0x58, 0x10, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x20, 0x00, 0xFF, 0xFF, 0x52, 0xFF, 0x05, 0x00, 0x14, 0x00, 0x66, 0xFF, 0x05, 0x00, 0x14, 0x00, 0x7A, 0xFF, 0x05, 0x00, 0x14, 0x00, 0x8E, 0xFF, 0x05, 0x00, 0x14, 0x00, 0xA2, 0xFF, 0x05, 0x00, 0x14, 0x0 
      省略未写
    
    }

    29.6.2        设置字库文件到外部SPI Flash。

    下面将流位图文件下载到SPI Flash,需要大家先在这里添加SPI Flash地址范围:

     

    然后设置资源文件到外部SPI Flash:鼠标右击文件分组GUI/Font,选择Options。

     

    29.6.3 下载配置

    注意这里一定要够大,否则会提示算法文件无法加载:

     

    我们这里是将其加到DTCM中,即首地址为0x20000000,大家也可以存储到任意其它RAM地址,只要空间还够加载算法文件即可。推荐使用AXI SRAM(地址0x24000000),因为这块RAM空间足够大。

    如果要下载程序到内部Flash和外部SPI Flash里面,需要做如下配置,两个下载算法都要添加进来:

     

    29.7 实验例程说明(RTOS)

    配套例子:

    V7-534_emWin6.x实验_XBF格式全字库生成和使用方法,Unicode编码(SPI Flash RTOS)

    实验目的:

    1. 学习emWin的的XBF格式全字库的生成和使用方法,Unicode编码。
    2. emWin功能的实现在MainTask.c文件里面。

    实验内容:

    1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。

    2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

        (2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

    3、默认上电是通过串口打印信息,如果使用RTT打印信息:

    MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

    #define Enable_RTTViewer  1

    4、各个任务实现的功能如下:

    App Task Start   任务 :启动任务,这里用作BSP驱动包处理。

    App Task MspPro任务 :消息处理,这里用作LED闪烁。

    App Task UserIF  任务 :按键消息处理。

    App Task COM   任务 :暂未使用。

    App Task GUI    任务 :GUI任务。

    μCOS-III任务调试信息(按K1按键,串口打印):

     

    RTT 打印信息方式:

     

    程序设计:

      任务栈大小分配:

    μCOS-III任务栈大小在app_cfg.h文件中配置:

    #define  APP_CFG_TASK_START_STK_SIZE                      512u

    #define  APP_CFG_TASK_MsgPro_STK_SIZE                     2048u

    #define  APP_CFG_TASK_COM_STK_SIZE                        512u

    #define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u

    #define  APP_CFG_TASK_GUI_STK_SIZE                        2048u

    任务栈大小的单位是4字节,那么每个任务的栈大小如下:

    App Task Start   任务 :2048字节。

    App Task MspPro任务 :8192字节。

    App Task UserIF  任务 :2048字节。

    App Task COM   任务 :2048字节。

    App Task GUI    任务 :8192字节。

      系统栈大小分配:

    μCOS-III的系统栈大小在os_cfg_app.h文件中配置:

    #define  OS_CFG_ISR_STK_SIZE                      512u     

    系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB

    emWin动态内存配置:

    GUIConf.c文件中的配置如下:

    #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
    
    #if EX_SRAM
    #define GUI_NUMBYTES  (1024*1024*24)
    #else
    #define GUI_NUMBYTES  (100*1024)
    #endif

    通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

    #define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

    #define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

    默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

    emWin界面显示效果:

    800*480分辨率界面效果。

     

    29.8 实验例程说明(裸机)

    配套例子:

    V7-533_emWin6.x实验_XBF格式全字库生成和使用方法,Unicode编码(SPI Flash 裸机)

    实验目的:

    1. 学习emWin的的XBF格式全字库的生成和使用方法,Unicode编码。
    2. emWin功能的实现在MainTask.c文件里面。

    emWin界面显示效果:

    800*480分辨率界面效果。

     

    emWin动态内存配置:

    GUIConf.c文件中的配置如下:

    #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
    
    #if EX_SRAM
    #define GUI_NUMBYTES  (1024*1024*24)
    #else
    #define GUI_NUMBYTES  (100*1024)
    #endif

    通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

    #define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

    #define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

    默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

    29.9 总结

    本章节为大家讲解的XBF格式字体是可以用于项目实战的,望初学者务必掌握。项目中不限制将XBF格式字体存储到SPI Flash里面,存储到NOR Flash,SD卡,NAND Flash等也是可以的,只要速度满足要求即可,不过还是建议将其存储到无需文件系统的存储介质中,速度比较快。

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    Ubuntu下基于u-boot搭建qemu的vexpress环境
    linux从head.s到start_kernelstart_kernel之---内核重定位后分析
    linux从head.s到start_kernelstart_kernel之---内核解压到重定位分析
    Jupyter Notebook介绍、安装及使用教程
    python基于SMTP发送邮件(qq邮箱)
    python正则表达式多次提取数据(一个规则提取多组数据)
    python正则表达式提取中文
    找到任务栏图标广告的源头
    1. Visio Web 形状
    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
  • 原文地址:https://www.cnblogs.com/armfly/p/15194282.html
Copyright © 2011-2022 走看看