當前位置:首頁 > 單片機 > 單片機
[導讀]一。漢字顯示原理1. 常用漢字編碼這里我們采用GBK編碼2. 漢字顯示原理假如顯示一個16*8的漢字,高16,寬8,則高需要2個字節(jié),顯示這個漢字需要2*8=16個字節(jié),這16個字節(jié)的數(shù)據(jù)就是漢字的點陣數(shù)據(jù)。3. 字符/漢字顯示方

一。漢字顯示原理

1. 常用漢字編碼


這里我們采用GBK編碼

2. 漢字顯示原理


假如顯示一個16*8的漢字,高16,寬8,則高需要2個字節(jié),顯示這個漢字需要2*8=16個字節(jié),這16個字節(jié)的數(shù)據(jù)就是漢字的點陣數(shù)據(jù)。

3. 字符/漢字顯示方法


利用軟件取模

取模方向設置:

掃描方向:縱向為先顯示第一個字節(jié),然后顯示第二個字節(jié),從低位到高位,然后換到第二列。

數(shù)據(jù)前綴改為“0x”,數(shù)據(jù)后綴改為“,”,行后綴為“;”。

對于漢字顯示采用16*16。

例如:開,為16*16,得到下面的字模數(shù)據(jù)。


得到字模數(shù)據(jù)后,程序中就可以從中取得相應的字節(jié)進行顯示。

4. 漢字顯示的過程

如何顯示字庫中所有的漢字?利用專用的軟件實現(xiàn)。


根據(jù)內(nèi)碼,查找相應的字庫點陣,然后解析,顯示。

對于漢字的內(nèi)碼常用GBK碼。每一個漢字都對應一個GBK的編碼。

認識GBK碼:


GBK碼共有126個區(qū),每個區(qū)里有190個漢字。

如何根據(jù)GBK編碼找到漢字:

1.首先找到GBK編碼的高位,得到這個漢字在哪個區(qū)。(高位-0x81)確定在哪個區(qū)。

(GBKH-0x81)*190表示這個漢字所在區(qū)的前面幾個區(qū)已經(jīng)有這么多個漢字。

當GBKL<0x7F時:漢字所在區(qū)的偏移為GBKL-0x40。

當GBKL>0x7F時:漢字所在區(qū)的偏移為GBKL-0x41,因為前面空掉一個0x7F。

因為每個漢字占用的字節(jié)數(shù)為size*2,比如16*16的漢字,那么每個漢字占用的空間是16*2=32個字節(jié)。

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

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

根據(jù)GBK編碼得到這個漢字所在漢字庫的起始地址。

從以上的方法找到了漢字所在的位置,下面開始制作點陣字庫。

采用字庫制作軟件制作漢字庫。



制作點陣字庫

生成字庫軟件設置:

注意字體大小選12,這個是電腦端字體的大小。


注意電腦端的字體大小與生成點陣的字體大小有區(qū)別

模式選擇縱向取模方式二。

生成點陣字庫后,要用文件系統(tǒng)讀取字庫,然后存到SPI-Flash中。


在SPI FLASH中的某個地方寫個標志0xAA,表示已經(jīng)更新過字庫。


Show_Str函數(shù)既能顯示字符,也能顯示漢字,如果是顯示漢字就調(diào)用Show_Font函數(shù)。

Get_HzMat函數(shù)根據(jù)編碼取得字庫中漢字的字模。然后根據(jù)字模數(shù)據(jù)解析,顯示。

二。實驗講解

生成的字庫文件名為:16.DZK,字庫大小為766,080字節(jié),然后把名字改成:GBK16.FON。

然后把這個文件存進SD卡,程序會從SD卡中把這個文件寫入SPI FLASH。

fontupd.c 更新字庫

text.c 顯示漢字

1. 程序主函數(shù)中開始的時候會檢查字庫,調(diào)用fontinit()函數(shù)。

//初始化字體

//返回值: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結(jié)構(gòu)體數(shù)據(jù)

if(ftinfo.fontok!=0XAA)return 1; //字庫錯誤.

return 0;

}

字體信息保存地址,占25個字節(jié),第1個字節(jié)用于標記字庫是否存在.后續(xù)每8個字節(jié)一組,分別保存起始地址和文件大小。

//字庫信息結(jié)構(gòu)體定義

//用來保存字庫基本信息,地址,大小等

__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是字節(jié)對齊的意思。

比如說int float double char它的總大小是4 + 4 + 8 + 1 = 17
但如果不用__packed的話,系統(tǒng)將以默認的方式對齊(假設是4字節(jié)),那么它占4 + 4 + 8 + 4 = 20;(不足4字節(jié)以4字節(jié)補齊)。

ftinfo 是我們在 fontupd.h 里面定義的一個結(jié)構(gòu)體,用于記錄字庫首地址及字庫大小等信息。

因為我們將W25Q64 的前 6M 字節(jié)給 FATFS 管理(用做本地磁盤),然后又預留了 500K 字節(jié)給用戶自己使用,最后的 1.5M 字節(jié)(W25Q64 總共 8M 字節(jié)),才是 UNIGBK 碼表和字庫的存儲空間。

finfo結(jié)構(gòu)體的存放地址為:

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

GBK字庫存放的首地址為:

ftinfo.ugbkaddr=FONTINFOADDR+25;

2. 主函數(shù)如果沒有檢測到字庫

a. 初始化SD卡

while(SD_Initialize()) //檢測SD卡

沒檢測到SD卡報錯

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

b. 調(diào)用 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)); //清除之前字庫成功的標志.防止更新到一半重啟,導致的字庫部分數(shù)據(jù)丟失.

SPI_Flash_Read((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //重新讀出ftinfo結(jié)構(gòu)體數(shù)據(jù)

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;//無錯誤.

}

調(diào)用updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath,u8 fx);

//更新某一個

//x,y:坐標

//size:字體大小

//fxpath:路徑

//fx:更新的內(nèi)容 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)); //為文件系統(tǒng)分配內(nèi)存

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

tempbuf=mymalloc(SRAMIN,4096); //為數(shù)據(jù)緩存區(qū)分配4096個字節(jié)空間

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

res=f_open(fftemp,(const TCHAR*)fxpath,FA_READ); //根據(jù)文件路徑打開文件

if (res) rval=2; //打開文件失敗

if (rval==0)

{

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

{

ftinfo.ugbkaddr = FONTINFOADDR+sizeof(ftinfo);//信息頭之后,緊跟UNIGBK轉(zhuǎn)換碼表

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) //死循環(huán)執(zhí)行

{

res=f_read(fftemp,tempbuf,4096,(UINT *)&bread); //讀取數(shù)據(jù)

if(res!=FR_OK)break; //執(zhí)行錯誤

SPI_Flash_Write(tempbuf,offx+flashaddr,4096);//從0開始寫入4096個數(shù)據(jù)

offx+=bread;

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

if (bread!=4096) break; //,如果讀出來的數(shù)據(jù)不是4092個,說明數(shù)據(jù)讀完了,跳出死循環(huán).

}

f_close(fftemp); //關閉文件

}

myfree(SRAMIN,fftemp); //釋放內(nèi)存

myfree(SRAMIN,tempbuf); //釋放內(nèi)存

return res;

}

f_open函數(shù)用法:

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

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

//code字符指針開始
//從字庫中查找出字模
//code字符串的開始地址,GBK碼
//mat字模數(shù)據(jù)存放地址size*2bytes大小
voidGet_HzMat(unsignedchar*code,unsignedchar*mat,u8size)//漢字取模
{
unsignedcharqh,ql;
unsignedchari;
unsignedlongf

本站聲明: 本文章由作者或相關機構(gòu)授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉