基于STM32平台实现UCGUI外挂中文字库

2014-11-27 08:15马志刚
深圳职业技术学院学报 2014年1期
关键词:字库链表控件

马志刚

(深圳职业技术学院 计算机工程学院,广东 深圳 518055)

UCGUI是一种轻量级的嵌入式图形支持系统,它的设计架构是模块化的,由不同的模块中的不同层组成.UCGUI可以在任何的CPU上运行,因为它是100%的标准C代码编写的.UCGUI提供一个可扩展的2D图形库及占用极少RAM的窗口管理体系,非常适合如 STM32这样的轻量级嵌入式平台的图形界面显示[1],大量应用于各种智能仪器仪表的液晶屏人机界面.UCGUI原生的字符显示机制需要程序员事先把程序中用到的字符点阵信息转化为C语言数组并组成一个链表结构作为字库,然后将该字库与整个工程一起进行编译链接,最终字库是包含在目标文件中.此机制对于英文这样基于字母的文字非常方便,生成内建的字库很方便,也不会大量增加目标文件的体积.然而对于汉字这样包含庞大字符数量的文字[2],采用此方法就存在很大的缺陷.因为在绝大部分应用场合都是无法事先预知有哪些汉字需要显示,而如果把所有常用汉字按照 UCGUI的规则转化为C语言链表结构,则工作量巨大且大大增加目标文件体积,如果应用于 STM32这样程序存储空间并不宽裕的平台,很可能因为空间不足而无法实现程序的烧写.所以对于大量文字的随机显示,更好的方案是将字库与程序代码分开.但是UCGUI本身并没有提供从外部存储器读取字库的接口,如果程序员自行编写代码从外部字库读取字符信息并使用UCGUI提供的上层绘图接口直接在LCD上绘制汉字点阵的话,则显示的汉字不能与 UCGUI的图层机制兼容,无法配合UCGUI中的其他图形控件使用,例如无法在按钮上添加汉字.本文介绍一种通过修改UCGUI底层字符驱动函数的方法,为UCGUI实现将字库独立于目标文件存储,并且充分兼容UCGUI图形库中的各种控件.

1 外部Flash

为了能够存储汉字库中的大量数据,本文在STM32处理器上外接Flash存储芯片来扩大存储空间.例如可采用 SPI接口的 Nand Flash 芯片M25PX16来扩展存储空间,该芯片具有16Mbit容量,具备4K字节子区擦除功能,最高支持75Mhz的SPI接口等特性,将其与主控芯片STM32进行连接如图1所示.

图1 外部Flash硬件连接图

STM32处理器的IO管脚大部分都具有复用功能,为了对 M25PX16进行访问,其 IO管脚PB13~PB15将分别配置为复用功能SPI2_SCK,SPI2_MISO和SPI2_MISI,即作为STM32的SPI2接口.然后对STM32的SPI2口进行配置,这里的配置主要是将SPI2设为全双工主模式,数据位设为8位,另外还有时序模式,波特率因子,数据帧格式以及CRC多项式的相关配置,最后使能SPI2.

经过软硬件的相关工作,现在外部Flash已经可以正常使用了,下一步工作是定义Flash的相关操作函数,如擦除,写入,读取等.然后利用串口或是USB接口等外部接口将汉字库下载到STM32并烧写到外部Flash中.本文使用的是16x16点阵的GBK码汉字库,大小为256 kB左右.

2 修改字符显示驱动

使用 UCGUI提供的自定义字体转换工具可以将指定的字符点阵信息转化到一个由C语言实现的链表中并封装到一个结构体里,以编译到目标文件中供 UCGUI显示时使用.为了最大限度地利用 UCGUI本身的这一显示机制,提高外挂字库的兼容性,本文先使用 UCGUI提供的的字体库转换工具针对16x16点阵字体生成一个含有数字0~9,英文字符a-z以及A-Z的链表式字体库,并将其封装到结构体 GUI_FontHZ_SimSun_16中,该结构体的第一个元素GUI_FONTTYPE_PROP_SJIS是在头文件GUIType.h中定义的用于设定字体属性的宏,此宏定义指明了该字体使用的字符显示驱动函数为GUIPROP_DispChar.我们要做的事情就是要修改这个显示驱动函数.首先,修改 GUI_FONTTYPE_PROP_SJIS的定义,将字符显示驱动函数改为指向我们自定义的函数My_GUIPROP_DispChar,这样,只需要在我们自定义的字符显示驱动函数My_GUIPROP_DispChar中实现读取外部 Flash中的汉字库来显示即可,此函数的源代码如下:

在上面的函数中,首先通过字符的机内码c判断要显示的字符是否为汉字,如果不是汉字,则直接使用 UCGUI原来的显示驱动GUIPROP_DispChar从链表字库中读取字符来显示;如果是汉字,则调用我们自己定义的从外部Flash读取字符的显示驱动函数WriteHZ,该函数从汉字库中读取字符的点阵信息供 UCGUI显示,其主要代码如下:

即先根据汉字内码p算出区位码c1和c2,再根据区位码计算出要显示的汉字在汉字库中的偏移量AddrInTable,然后调用Flash_Read函数从外部Flash中读取汉字的点阵信息来进行显示.其中FontLibStartPage是汉字库烧写入 Flash时的起始页地址(本文使用的 Flash芯片每页为 256字节),数组 pixeldata 是字符点阵信息的显示缓冲区.

经过上面的改动,在需要显示汉字的场合,只需要调用设置字体的函数将字体设置为我们最开始定义的字体 GUI_FontHZ_SimSun_16 即可.例如要在按钮Button0上显示汉字,可调用如下函数:

BUTTON_SetFont( Button0 , &GUI_FontHZ_SimSun_16);

通过对UCGUI原有的字符显示机制进行改造,在充分兼容其控件系统的前提下,实现了将汉字库独立于目标代码文件存储在外部 Flash中,适合需要显示大量不确定性汉字的场合,弥补了UCGUI在汉字显示方面的先天缺陷,使得这一优秀的图形系统有了更大的用武之地.

[1] 王兰英.基于STM32嵌入式系统的uCGUI移植与实现[J].四川理工学院学报(自然科学版),2012,25(1):56-58.

[2] 国家标准总局.GB2312-80信息交换用汉字编码字符集基本集[S].1981.

猜你喜欢
字库链表控件
No.2 喜茶联合汉仪字库推出微型书和书签
基于二进制链表的粗糙集属性约简
跟麦咭学编程
关于.net控件数组的探讨
基于链表多分支路径树的云存储数据完整性验证机制
论计算机字库单字的著作权保护
——以方正诉宝洁案为例
老家的惜字库
ASP.NET服务器端验证控件的使用
链表方式集中器抄表的设计
再议字库知识产权保护