当前位置:首页 > 单片机 > 单片机
[导读]一。汉字显示原理1. 常用汉字编码这里我们采用GBK编码2. 汉字显示原理假如显示一个16*8的汉字,高16,宽8,则高需要2个字节,显示这个汉字需要2*8=16个字节,这16个字节的数据就是汉字的点阵数据。3. 字符/汉字显示方

一。汉字显示原理

1. 常用汉字编码


这里我们采用GBK编码

2. 汉字显示原理


假如显示一个16*8的汉字,高16,宽8,则高需要2个字节,显示这个汉字需要2*8=16个字节,这16个字节的数据就是汉字的点阵数据。

3. 字符/汉字显示方法


利用软件取模

取模方向设置:

扫描方向:纵向为先显示第一个字节,然后显示第二个字节,从低位到高位,然后换到第二列。

数据前缀改为“0x”,数据后缀改为“,”,行后缀为“;”。

对于汉字显示采用16*16。

例如:开,为16*16,得到下面的字模数据。


得到字模数据后,程序中就可以从中取得相应的字节进行显示。

4. 汉字显示的过程

如何显示字库中所有的汉字?利用专用的软件实现。


根据内码,查找相应的字库点阵,然后解析,显示。

对于汉字的内码常用GBK码。每一个汉字都对应一个GBK的编码。

认识GBK码:


GBK码共有126个区,每个区里有190个汉字。

如何根据GBK编码找到汉字:

1.首先找到GBK编码的高位,得到这个汉字在哪个区。(高位-0x81)确定在哪个区。

(GBKH-0x81)*190表示这个汉字所在区的前面几个区已经有这么多个汉字。

当GBKL<0x7F时:汉字所在区的偏移为GBKL-0x40。

当GBKL>0x7F时:汉字所在区的偏移为GBKL-0x41,因为前面空掉一个0x7F。

因为每个汉字占用的字节数为size*2,比如16*16的汉字,那么每个汉字占用的空间是16*2=32个字节。

当 GBKL<0X7F 时:Hp=((GBKH-0x81)*190+GBKL-0X40)*(size*2);

当 GBKL>0X80 时:Hp=((GBKH-0x81)*190+GBKL-0X41)*(size*2);

根据GBK编码得到这个汉字所在汉字库的起始地址。

从以上的方法找到了汉字所在的位置,下面开始制作点阵字库。

采用字库制作软件制作汉字库。



制作点阵字库

生成字库软件设置:

注意字体大小选12,这个是电脑端字体的大小。


注意电脑端的字体大小与生成点阵的字体大小有区别

模式选择纵向取模方式二。

生成点阵字库后,要用文件系统读取字库,然后存到SPI-Flash中。


在SPI FLASH中的某个地方写个标志0xAA,表示已经更新过字库。


Show_Str函数既能显示字符,也能显示汉字,如果是显示汉字就调用Show_Font函数。

Get_HzMat函数根据编码取得字库中汉字的字模。然后根据字模数据解析,显示。

二。实验讲解

生成的字库文件名为:16.DZK,字库大小为766,080字节,然后把名字改成:GBK16.FON。

然后把这个文件存进SD卡,程序会从SD卡中把这个文件写入SPI FLASH。

fontupd.c 更新字库

text.c 显示汉字

1. 程序主函数中开始的时候会检查字库,调用fontinit()函数。

//初始化字体

//返回值:0,字库完好.

//其他,字库丢失

u8 font_init(void)

{

SPI_Flash_Init(); //初始化25Q**系列。

FONTINFOADDR=(1024*6+500)*1024; //W25Q64,6M以后

ftinfo.ugbkaddr=FONTINFOADDR+25; //UNICODEGBK 表存放首地址固定地址

SPI_Flash_Read((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo));//读出ftinfo结构体数据

if(ftinfo.fontok!=0XAA)return 1; //字库错误.

return 0;

}

字体信息保存地址,占25个字节,第1个字节用于标记字库是否存在.后续每8个字节一组,分别保存起始地址和文件大小。

//字库信息结构体定义

//用来保存字库基本信息,地址,大小等

__packed typedef struct

{

u8 fontok; //字库存在标志,0XAA,字库正常;其他,字库不存在

u32 ugbkaddr; //unigbk的地址

u32 ugbksize; //unigbk的大小

u32 f12addr; //gbk12地址

u32 gbk12size; //gbk12的大小

u32 f16addr; //gbk16地址

u32 gkb16size; //gbk16的大小

}_font_info;

__packed是字节对齐的意思。

比如说int float double char它的总大小是4 + 4 + 8 + 1 = 17
但如果不用__packed的话,系统将以默认的方式对齐(假设是4字节),那么它占4 + 4 + 8 + 4 = 20;(不足4字节以4字节补齐)。

ftinfo 是我们在 fontupd.h 里面定义的一个结构体,用于记录字库首地址及字库大小等信息。

因为我们将W25Q64 的前 6M 字节给 FATFS 管理(用做本地磁盘),然后又预留了 500K 字节给用户自己使用,最后的 1.5M 字节(W25Q64 总共 8M 字节),才是 UNIGBK 码表和字库的存储空间。

finfo结构体的存放地址为:

FONTINFOADDR=(1024*6+500)*1024;

GBK字库存放的首地址为:

ftinfo.ugbkaddr=FONTINFOADDR+25;

2. 主函数如果没有检测到字库

a. 初始化SD卡

while(SD_Initialize()) //检测SD卡

没检测到SD卡报错

LCD_ShowString(60,70,200,16,16,"SD Card Failed!");

b. 调用 update_font(20,110,16,0); 从SD卡更新字库

自己做的字库要放在SD卡SYSTEM/FONT目录下

文件名为GBK16.FON或GBK24.FON

//更新字体文件,UNIGBK,GBK12,GBK16一起更新

//x,y:提示信息的显示地址

//size:字体大小

//提示信息字体大小

//src: 0, 从SD卡更新.

//src:1, 从25QXX更新

//返回值:0,更新成功;

//其他,错误代码.

u8 update_font(u16 x,u16 y,u8 size,u8 src)

{

u8 *gbk16_path;

u8 *gbk12_path;

u8 *unigbk_path;

u8 res;

if(src)//从25qxx更新

{

unigbk_path=(u8*)UNIGBK_25QPATH;

gbk12_path=(u8*)GBK12_25QPATH;

gbk16_path=(u8*)GBK16_25QPATH;

}else//从sd卡更新

{

unigbk_path=(u8*)UNIGBK_SDPATH;

gbk12_path=(u8*)GBK12_SDPATH;

gbk16_path=(u8*)GBK16_SDPATH;

}

res=0XFF;

ftinfo.fontok=0XFF;

SPI_Flash_Write((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //清除之前字库成功的标志.防止更新到一半重启,导致的字库部分数据丢失.

SPI_Flash_Read((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //重新读出ftinfo结构体数据

LCD_ShowString(x,y,240,320,size,"Updating UNIGBK.BIN");

res=updata_fontx(x+20*size/2,y,size,unigbk_path,0); //更新UNIGBK.BIN

if(res)return 1;

LCD_ShowString(x,y,240,320,size,"Updating GBK12.BIN ");

res=updata_fontx(x+20*size/2,y,size,gbk12_path,1); //更新GBK12.FON

if(res)return 2;

LCD_ShowString(x,y,240,320,size,"Updating GBK16.BIN ");

res=updata_fontx(x+20*size/2,y,size,gbk16_path,2); //更新GBK16.FON

if(res)return 3;

//全部更新好了,写入标志位0xAA。

ftinfo.fontok=0XAA;

SPI_Flash_Write((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //保存字库信息

return 0;//无错误.

}

调用updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath,u8 fx);

//更新某一个

//x,y:坐标

//size:字体大小

//fxpath:路径

//fx:更新的内容 0,ungbk;1,gbk12;2,gbk16;

//返回值:0,成功;其他,失败.

u8 updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath,u8 fx)

{

u32 flashaddr=0;

FIL * fftemp;

u8 *tempbuf;

u8 res;

u16 bread;

u32 offx=0;

u8 rval=0;

fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //为文件系统分配内存

if (fftemp==NULL) rval=1; //分配失败,rval = 1;

tempbuf=mymalloc(SRAMIN,4096); //为数据缓存区分配4096个字节空间

if (tempbuf==NULL) rval=1; //分配失败,rval = 1;

res=f_open(fftemp,(const TCHAR*)fxpath,FA_READ); //根据文件路径打开文件

if (res) rval=2; //打开文件失败

if (rval==0)

{

if(fx==0) //更新UNIGBK.BIN

{

ftinfo.ugbkaddr = FONTINFOADDR+sizeof(ftinfo);//信息头之后,紧跟UNIGBK转换码表

ftinfo.ugbksize = fftemp->fsize; //UNIGBK大小

flashaddr = ftinfo.ugbkaddr; //UNIGBK字库的地址

}else if (fx==1) //更新GBK12

{

ftinfo.f12addr=ftinfo.ugbkaddr+ftinfo.ugbksize; //UNIGBK之后,紧跟GBK12字库

ftinfo.gbk12size=fftemp->fsize; //GBK12字库大小

flashaddr=ftinfo.f12addr; //GBK12的起始地址

}else //更新GBK16

{

ftinfo.f16addr=ftinfo.f12addr+ftinfo.gbk12size; //GBK12之后,紧跟GBK16字库

ftinfo.gkb16size=fftemp->fsize; //GBK16字库大小

flashaddr=ftinfo.f16addr; //GBK16的起始地址

}

while (res==FR_OK) //死循环执行

{

res=f_read(fftemp,tempbuf,4096,(UINT *)&bread); //读取数据

if(res!=FR_OK)break; //执行错误

SPI_Flash_Write(tempbuf,offx+flashaddr,4096);//从0开始写入4096个数据

offx+=bread;

fupd_prog(x,y,size,fftemp->fsize,offx); //进度显示

if (bread!=4096) break; //,如果读出来的数据不是4092个,说明数据读完了,跳出死循环.

}

f_close(fftemp); //关闭文件

}

myfree(SRAMIN,fftemp); //释放内存

myfree(SRAMIN,tempbuf); //释放内存

return res;

}

f_open函数用法:

The f_open function creates afile objectto be used to access the file.

FRESULTf_open(
FIL*fp,
constTCHAR*path,
BYTEmode
);
f_read函数的用法:
Thef_readfunctionreadsdatafromafile.
FRESULTf_read(
FIL*fp,
void*buff,
UINTbtr,
UINT*br
);
text.c中的函数:
1.根据GBK码找到字模函数Get_HzMat(unsignedchar*code,unsignedchar*mat,u8size)

//code字符指针开始
//从字库中查找出字模
//code字符串的开始地址,GBK码
//mat字模数据存放地址size*2bytes大小
voidGet_HzMat(unsignedchar*code,unsignedchar*mat,u8size)//汉字取模
{
unsignedcharqh,ql;
unsignedchari;
unsignedlongf

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭