【第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

相关文章

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法