3563.24汉字显示实验汉字显示在很多单片机系统都需要用到,少则几个字,多则整个汉字库的支持,更有甚者还要支持多国字库,那就更麻烦了。在我们的ALIENTEKMiniSTM32上,完全可以显示整个汉字库(GBK汉字库)的,本节将向大家介绍如何在ALIENTEKMiniSTM32开发板上显示汉字。本节分为如下几个部分:3.24.1汉字显示原理简介3.24.2硬件设计3.24.3软件设计3.24.4下载与测试3573.24.1汉字显示原理简介常用的汉字内码系统有GB2312,GB13000,GBK,BIG5(繁体)等几种,其中GB2312支持的汉字仅有几千个,很多时候不够用,而GBK内码不仅完全兼容GB2312,还支持了繁体字,总汉字数有2万多个,完全能满足我们一般应用的要求。本实例我们将制作一个GBK字库,制作好的字库放在SD卡里面,然后通过SD卡,将字库文件复制到W25X16里,这样,W25X16就相当于一款汉字字库芯片了。汉字在液晶上的显示原理与前面显示字符的是一样的。汉字在液晶上的显示其实就是一些点的显示与不显示,这就相当于我们的笔一样,有笔经过的地方就画出来,没经过的地方就不画。所以要显示汉字,我们首先要知道汉字的点阵数据,这些数据可以由专门的软件来生成。只要知道了一个汉字点阵的生成方法,那么我们在程序里面就可以把这个点阵数据解析成一个汉字。知道显示了一个汉字,就可以推及整个汉字库了。汉字在电脑里面存储不是以点阵数据的形式存储的(否则那占用的空间就太大了),而是以内码的形式存储的,就是GB2312/GBK/BIG5等这几种的一种(昀常用的是哪个我也不清楚,但是可以肯定是我们装的简体XP,汉字一般都能用GBK码或GB2312码解析),每个汉字对应着一个内码,在知道了内码之后再去字库里面查找这个汉字的点阵数据,然后在液晶上显示出来。这个过程我们是看不到,但是计算机是要去执行的。单片机要显示汉字也与此类似:汉字内码(GBK/GB2312)-查找点阵库-解析-显示。所以只要我们有了整个汉字库的点阵,就可以把电脑上的文本信息在单片机上显示出来了。这里我们要解决的昀大问题就是制作一个与汉字内码对的上号的汉字点阵库。而且要方便单片机的查找。每个GBK码由2个字节组成,第一个字节为0X81~0XFE,第二个字节分为两部分,一是0X40~0X7E,二是0X80~0XFE。其中与GB2312相同的区域,字完全相同。我们把第一个字节代表的意义称为区,那么GBK里面总共有126个区(0XFE-0X81+1),每个区内有190个汉字(0XFE-0X80+0X7E-0X40+2),总共就有126*190=23940个汉字。我们的点阵库只要按照这个编码规则从0X8140开始,逐一建立,每个区的点阵大小为每个汉字所用的字节数*190。这样,我们就可以得到在这个字库里面定位汉字的方法:当GBKL0X7F时:Hp=((GBKH-0x81)*190+GBKL-0X40)*(size*2);当GBKL0X80时:Hp=((GBKH-0x81)*190+GBKL-0X41)*(size*2);其中GBKH、GBKL分别代表GBK的第一个字节和第二个字节(也就是高位和低位),size代表汉字字体的大小(比如16字体,12字体等),Hp则为对应汉字点阵数据在字库里面的起始地址。这样我们只要得到了汉字的GBK码,就可以显示这个汉字了。从而实现汉字在液晶上的显示。而XP在存储文件名的时候,如果是长文件名,则是按照UNICODE码存放的,而UNICODE码与GBK码并不一致,所以如果要支持UNICODE内码的汉字显示则需要一个UNICODE到GBK码的转换码表,通过先将UNICODE码转换为GBK码,再从GBK码字库里面查找点阵数据,从而显示UNICODE码的汉字。UNICODE码表的制作方法是将UNICODE码从低到高顺序排列,然后在对应的位置存放GBK码的码值就可以了,这样我们就可以通过UNICODE码快速的找到GBK码。UNICODE码中用于存放汉字的字段为0X4E00~0X9FA5,总共20902个汉字。我们将这些对应的汉字的GBK码顺序存入相应的位置,就得到了UNICODE到GBK的转换码表。关于UNICODE转GBK就介绍到这里,我们这里提供的UNICODE转GBK码码表是在网358友波仔制作的UNICODE转GBK码表基础上修改而来的,波仔制作的并不能显示大写的标点符号,我们把这部分加入了进去,把汉字标点符号对应的GBK码按UNICODE的编码先后顺序写入到波仔制作的转换表的后面,这样我们在程序里做一点点小改动,就可以实现对UNICODE码的标点符号的支持了。加入的标点符号总共97个,对应UNICODE码的0XFF01~0XFF61。每个GBK码占用了2个字节,所以整个UNICODE转GBK码码表文件的大小为:2*(20902+97)=41998个字节(42K)。16*16大小的汉字每个汉字点阵需要32个字节,可以得到整个GBK码16字库的大小为:32*(23940)=766080字节(749K)。字库的生成,我们要用到一款软件,由易木雨软件工作室设计的点阵字库生成器V3.8。该软件可以在WINDOWS系统下生成任意点阵大小的ASCII,GB2312(简体中文)、GBK(简体中文)、BIG5(繁体中文)、HANGUL(韩文)、SJIS(日文)、Unicode以及泰文,越南文、俄文、乌克兰文,拉丁文,8859系列等共二十几种编码的字库,不但支持生成二进制文件格式的文件,也可以生成BDF文件,还支持生成图片功能,并支持横向,纵向等多种扫描方式,且扫描方式可以根据用户的需求进行增加。该软件的界面如下:图3.24.1.1点阵字库生成器默认界面比如我们要生成16*16的GBK字库,则选择GBK,字宽和高均选择16,自他大小选择12(比较适合),然后模式选择纵向取模方式二(字节高位在前,低位在后),昀后点击创建,就可以开始生成我们需要的字库了。具体设置如下图所示:359图3.24.1.2生成GBK16*16字库的设置方法这里注意,软件里面的字体大小并不是我们生成点阵的大小,12字体是XP的叫法,我们字体的大小以宽和高的大小来决定!可以简单的这么认为:XP的12字体,基本上就等于16*16大小。该软件还可以生成其他很多字库,字体也可选,详细的介绍请看软件自带的《点阵字库生成器说明书》。本节还需要用到SD卡和FLASH部分,在前面的例子都已经介绍过了。但还有昀重要的FAT文件系统没有介绍,本节将要用到FAT(FAT16/32)文件系统来读取SD卡上的字库和UNICODE到GBK的转换码表。FAT文件系统本身比较复杂,如果要深入估计介绍都可以写本书了。所以这里我们只简单介绍一下,更多的介绍,请参考我们提供的光盘内的FAT资料文件夹,里面有FAT文件系统的详细介绍资料。常用的文件系统有FAT12/16/32等,FAT12是昀古老的文件系统,只能管理8M左右的空间,现在基本淘汰了。FAT16则可以管理2G的空间(通过特殊处理也能管理2G以上的空间),而FAT32则能管理到2TB(2048GB)的空间。FAT32较FAT16的优势还在于FAT32采用了更小的簇,可以更有效的保存信息,而不会造成多的浪费。XP在SD卡里面建立的文件系统昀常用的也就是FAT16和FAT32。这是由XP在格式化SD卡的时候建立的,通常SD卡上的数据信息由MBR、DBR、FAT、FDT和数据区5个部分组成(有的也没有MBR)。我们以FAT32为例做介绍。MBR称为主引导记录区,该区存储了分区表等信息,位于SD卡的扇区0(物理扇区),在其分区信息里面记录了DBR所在的位置,SD卡一般只会有一个分区,所以也就只要找到分区1的DBR所在位置就可以了。DBR称为操作系统引导记录区,如果没有MBR,那么DBR就位于0扇区,如果有则必须通过MBR区得到DBR所在的地址,然后读出DBR信息。在DBR区,我们可以知道每个扇区所占用的字节数、每个簇的扇区数、FAT表的份数、每个FAT表的扇区数、跟目录簇号、FAT表1所在的扇区等一系列非常重要的信息。FAT称为文件分配表(FAT表),一般一个卡上会存在2个FAT表,一个用作备份,一个用作使用。FAT表一般紧随DBR,另一个FAT表则紧随第一个FAT表,这样只要知道了第一个FAT表的位置及大小,那么第二个FAT表的位置也就确定了。FAT表记录了每个文件的位置和区域,是一种链式结构,FAT以“F8FFFF0FFFFFFFFF”这样的8个字节为表头,用以表示FAT表的开始,后面的数据每四个字节为一个簇项(从第2簇开始),用来标记下一个簇所在的位置,这样每个位置都存储了下一个簇,只要按着这个表走,就可以找到文件的所有内容。如果找到下一个簇位置,里面记录的是“FFFFFF0F”,代表这个文件到此就结束了,没有后续簇了,这样一个文件的读取就结束了。FDT称为文件根目录表,这个区域固定为32个扇区,假设每个扇区为512个字节,那么更目录下昀多存放512个文件(假设都用短文件名存储,每个短文件名占32个字节)。文件目录表是另一个重要的部分,FAT文件系统中(仅以短文件名介绍),文件目录项在目录表下以32个字节的方式记录,个字段定义如下:360图3.24.1.3文件目录项各字节定义从上图可只,我们在文件的目录项就可以找到该文件的其实簇,然后在FAT表里面找到该簇开始的下一个簇,依次读取这些簇就可以把整个文件读出来了。FAT文件系统就给大家介绍到这里。3613.24.2硬件设计本节实验功能简介:开机的时候先检测W25X16中是否已经存在字库,如果存在,则按次序显示汉字。如果没有,则检测SD卡和文件系统,并查找SYSTEM文件夹下的FONT文件夹,在该文件夹内查找UNI2GBK.SYS和GBK16.FON(这两个文件是由我们自己生成的UNICODE转GBK码表文件和GBK字库(16*16)文件)。在检测到这些文件之后,就开始更新字库,更新完毕才开始显示汉字。同样我们也是用LED0来指示程序正在运行。所要用到的硬件资源如下:1)STM32F103RBT6。2)DS0(外部LED0)。3)TFTLCD液晶模块。4)按键05)W25X16。6)SD卡这几部分分,在之前的实例中都介绍过了,我们在此就不介绍了。3.24.3软件设计打开上一节的工程,首先在HARDWARE文件夹所在文件夹下新建一个FAT和TEXT的文件夹。在FAT文件夹里面新建fat.c和fat.h两个文件。然后在TEXT文件夹下新建fontupd.c、fontupd.h、text.c、text.h、untogb.c、untogb.h这六个文件。并将这个两个文件夹加入头文件包含路径。打开fat.c,输入如下代码:#includeFAT.h#includeusart.h//MiniSTM32开发板//FAT驱动V1.0//正点原子@ALIENTEK//2010/5/13//全局变量区域DWORDFirstDirClust;//根目录簇号DWORDFirstDataSector;//数据区的第一个扇区WORDBytesPerSector;//每扇区字节数DWORDFATsectors;//FAT表所占扇区数WORDSectorsPerClust;//每簇扇区数DWORDFirstFATSector;//第一个FAT表(FAT1)所在扇区DWORDFirstDirSector;//第一个目录扇区fat32DWORDRootDirSectors;//根目录所占用的扇区数DWORDRootDirCount;//根目录下目录项数BYTEFAT32_Enable;//FAT32文件系统标志362DWORDCur_Dir_Cluster;//当前目录簇号//DWORDFat_Dir_Cluster;//父目录簇号在FAT文件夹里面CopyDirentruyItem函数中修改!FAT_TABLEFAT_TAB;//TINYFAT表