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

本文主要是介绍【第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.6.1        将字库文件转换为C数组格式文件

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

29.6.3 下载配置

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软包安装目录里面:\Keil\STM32H7xx_DFP\2.6.0\CMSIS\Flash(软包版本不同,数值2.6.0不同)。
  •   第2种:MDK的安装目录 \ARM\Flash里面。

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等也是可以的,只要速度满足要求即可,不过还是建议将其存储到无需文件系统的存储介质中,速度比较快。

这篇关于【第3版emWin教程】第29章 emWin6.x的XBF格式全字库生成和使用方法(Unicode编码,SPI Flash方案)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/657839

相关文章

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr