基于單片機(jī)的智能終端中漢字顯示的處理
引言
近年來,以單片機(jī)以及嵌入式系統(tǒng)平臺(tái)為基礎(chǔ)的各種智能終端廣泛應(yīng)用于各行各業(yè)的專用設(shè)備和產(chǎn)品中,也將逐漸滲透到家用電器和各種消費(fèi)類電子產(chǎn)品中。
單片機(jī)以其價(jià)格低廉、技術(shù)成熟而廣泛應(yīng)用于各種低端產(chǎn)品之中,但是由于單片機(jī)的尋址能力有限,限定了其最大的存儲(chǔ)空間。比如最常用的MCS-51單片機(jī),其直接尋址的數(shù)據(jù)存儲(chǔ)空間為64k字節(jié),如果通過擴(kuò)展來得到更大的存儲(chǔ)空間,既增加了系統(tǒng)成本,也為數(shù)據(jù)讀取操作帶來了不便(對(duì)擴(kuò)展區(qū)間的訪問要通過端口操作實(shí)現(xiàn))。所以在單片機(jī)系統(tǒng)的設(shè)計(jì)中,存儲(chǔ)空間的大小是一個(gè)很重要的因素。
在PC機(jī)上的漢字顯示,是來自存儲(chǔ)在PC機(jī)上的漢字庫(kù)。漢字庫(kù)中的漢字以點(diǎn)陣形式組成。如果以一個(gè)16x16點(diǎn)陣的漢字庫(kù)作為基本字模庫(kù),每個(gè)漢字占32 個(gè)字節(jié)。GB2312中規(guī)定了6763個(gè)二級(jí)漢字,則需要的存儲(chǔ)空間大體為6763×32字節(jié),約200多K字節(jié)。顯然,如果要在單片機(jī)終端上顯示漢字,不可能把以上所有的“漢字庫(kù)”信息都放在單片機(jī)系統(tǒng)的存儲(chǔ)空間中。
本文以我實(shí)驗(yàn)室獨(dú)立開發(fā)的智能餐飲信息系統(tǒng)為例,首先介紹關(guān)于漢字顯示的基礎(chǔ)知識(shí),然后說明在實(shí)際應(yīng)用中如何對(duì)系統(tǒng)漢字庫(kù)進(jìn)行裁減,只保留需要在終端上顯示的“漢字庫(kù)”信息,最后介紹在實(shí)際應(yīng)用中會(huì)涉及到的有關(guān)字模提取和字模轉(zhuǎn)化的處理方法。
1:關(guān)于漢字顯示的基礎(chǔ)知識(shí)
在中文WIN9X下,我們輸入一個(gè)雙八位字節(jié),就得到一個(gè)漢字,就會(huì)認(rèn)為這雙八位字節(jié)就是對(duì)應(yīng)這樣的字形,這是錯(cuò)誤的。這個(gè)雙八位字節(jié)被稱為漢字的內(nèi)碼(詳見下文),內(nèi)碼對(duì)于字庫(kù)來說,只是查找字形的索引。通過這個(gè)雙八位字節(jié)可以唯一的從漢字庫(kù)中查詢得到其對(duì)應(yīng)的漢字字形數(shù)據(jù)(字模)。對(duì)應(yīng)不同編碼標(biāo)準(zhǔn)的字體,內(nèi)碼對(duì)應(yīng)了不同的字形。我們常用的是國(guó)標(biāo)GB2312<<信息交換用漢字編碼字符集>>,包含了最常用的簡(jiǎn)體中文文字。
如果系統(tǒng)所使用的“漢字庫(kù)”中每個(gè)漢字按16x16點(diǎn)陣模式存放,則每個(gè)漢字由16x16=256個(gè)點(diǎn)組成,占用16x2=32個(gè)字節(jié)的連續(xù)內(nèi)存單元。每個(gè)字節(jié)有8位,每一位都有兩種狀態(tài),即亮或暗,分別用1或0來表示。在16x16點(diǎn)陣中,用各個(gè)位的亮暗來表示一個(gè)字,凡是筆畫經(jīng)過的地方都為1(亮), 沒有筆畫的地方都為0(暗),這樣就可以表示不同的漢字。
圖1 是“大”字16x16點(diǎn)陣模式排列放大后的結(jié)果。
在PC機(jī)中,組成字模的32個(gè)字節(jié)默認(rèn)的排列順序如圖2所示:每行兩個(gè)字節(jié),低字節(jié)為DB0~DB7,高字節(jié)為DB8~DB15,每字節(jié)8比特,共16行32個(gè)字節(jié)。圖中標(biāo)出了第1、第2個(gè)字節(jié)和第31、第32個(gè)字節(jié)的存放位置。
于是,我們可以得到“大”字的漢字字模(32個(gè)字節(jié),10進(jìn)制表示):(1,0,1,0,1,0,1,0,1,4,255,254,1,0,2,128,2,128,2,64,4,64,4,32,8,16,16,14,96,4,0,0)
2.字模提取及數(shù)據(jù)文件下載
2.1 在實(shí)際應(yīng)用中,需要進(jìn)行字模提取來適應(yīng)有限的存儲(chǔ)空間
我實(shí)驗(yàn)室獨(dú)立開發(fā)的餐飲業(yè)信息系統(tǒng)中就是應(yīng)用單片機(jī)來實(shí)現(xiàn)智能點(diǎn)菜終端。系統(tǒng)構(gòu)成如圖3所示:
在以上系統(tǒng)中,終端中存儲(chǔ)著所有的菜譜信息,操作員通過點(diǎn)菜終端可以瀏覽菜譜。簡(jiǎn)單的操作流程為:當(dāng)操作員通過終端點(diǎn)好了菜以后,終端以無(wú)線方式將菜肴信息發(fā)送到基站,基站通過串口將數(shù)據(jù)發(fā)送給服務(wù)器,服務(wù)器對(duì)數(shù)據(jù)進(jìn)行處理之后要進(jìn)行入庫(kù)、打印和向終端返回等操作。
在本系統(tǒng)中所采用的單片機(jī)為MSC-51,帶32K的外部RAM和128K的FLASH存儲(chǔ)器。其中,128K字節(jié)的FLASH存儲(chǔ)空間用作數(shù)據(jù)存儲(chǔ)器,記錄了菜譜、桌位等和業(yè)務(wù)相關(guān)的信息,另外有64K字節(jié)用作存儲(chǔ)漢字庫(kù)(字模)。
GB2312中規(guī)定常用的兩級(jí)漢字6763個(gè)(每個(gè)漢字有32字節(jié)),占用200多K字節(jié)的存儲(chǔ)空間。顯然,不能把漢字庫(kù)中的所有漢字字模都下載到終端上,只能是選擇終端需要顯示的漢字的字模進(jìn)行提取和下載。終端的64K存儲(chǔ)空間可以存儲(chǔ)大約2000個(gè)漢字。在實(shí)際應(yīng)用中一般酒店的菜肴數(shù)量在 200~600之間,要用到的漢字?jǐn)?shù)在400~1800之間,所以64K的存儲(chǔ)空間足夠本系統(tǒng)的應(yīng)用。
2.2 如何進(jìn)行字模提取和下載處理
在本系統(tǒng)中,終端數(shù)據(jù)存儲(chǔ)區(qū)中的字庫(kù)信息、菜譜、桌位等業(yè)務(wù)信息是從服務(wù)器上下載得到的。首先,服務(wù)器中的處理程序提取相關(guān)數(shù)據(jù)并生成各個(gè)下載信息文件,然后處理程序?qū)⑦@些下載文件下載到終端上。系統(tǒng)和終端通過串口線相連,以串口通信方式將數(shù)據(jù)下傳到終端的數(shù)據(jù)存儲(chǔ)區(qū)。
字模裁減及填充終端字庫(kù)下載文件流程如圖4 所示:
首先,運(yùn)行在服務(wù)器上的處理程序遍歷數(shù)據(jù)庫(kù)中的菜譜表、桌位表等所有包含下載信息的、帶有漢字的表記錄。從中找到需要下載的漢字,根據(jù)這些漢字的內(nèi)碼,從系統(tǒng)字庫(kù)中得到漢字的字模,經(jīng)過字模轉(zhuǎn)化(在后面介紹),然后保存在字庫(kù)下載文件中。
為了保證下傳的漢字字模不會(huì)重復(fù),在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)“漢字表”來存儲(chǔ)每個(gè)經(jīng)過篩選的漢字的信息。表中有兩個(gè)字段,一個(gè)用來存儲(chǔ)漢字的內(nèi)碼,另一個(gè)用來存儲(chǔ)該漢字字模在字庫(kù)下載文件中的偏移地址(終端程序可以通過某個(gè)漢字在字庫(kù)下載文件中的偏移地址來唯一確定該漢字的字模存放位置)。每得到一個(gè)漢字的內(nèi)碼時(shí),先到漢字表中查詢表中是否已經(jīng)包含了該漢字,再?zèng)Q定是否進(jìn)行提取和下載處理。
然后,處理程序逐個(gè)遍歷菜譜表、桌位表等數(shù)據(jù)表項(xiàng)來生成菜譜下載文件、桌位下載文件等。這些下載文件中涉及到的漢字,以該漢字的字模在終端下載字庫(kù)文件中的偏移地址來標(biāo)識(shí)。這樣每個(gè)漢字可以用兩個(gè)字節(jié)唯一標(biāo)識(shí)。
最后,處理程序?qū)⒁陨线@些下載文件通過串口下傳給終端,終端將下載文件的內(nèi)容保存在數(shù)據(jù)存儲(chǔ)區(qū)中,并記錄存放字庫(kù)下載文件數(shù)據(jù)區(qū)的起始地址,記為A。當(dāng)需要顯示漢字時(shí),終端程序先得到該漢字在下載文件中的偏移地址,記為B,然后計(jì)算出該漢字字模的存放位置(A+B),從此位置開始連續(xù)讀取32字節(jié),就得到了該漢字字模數(shù)據(jù),之后通過驅(qū)動(dòng)液晶屏將漢字顯示出來。
3.需要注意的關(guān)鍵技術(shù)
3.1 漢字字模的提取
先說明一下在中文信息交換標(biāo)準(zhǔn)GB2312中涉及到的三個(gè)概念:區(qū)位碼、國(guó)標(biāo)碼、內(nèi)碼。
中文國(guó)標(biāo)字符集是一個(gè)94×94的矩陣,其中每一個(gè)漢字(包括數(shù)字、英文字母和標(biāo)點(diǎn)符號(hào))都是二維矩陣中的某個(gè)元素。這樣,每一個(gè)漢字都可以用一個(gè)二元組來表示(x,y)。其中,x是該字所在的行號(hào),y為列號(hào)。
GB2312在此基礎(chǔ)上對(duì)矩陣進(jìn)行劃分,分為94個(gè)區(qū),每區(qū)94位,x定義了該字所在的行號(hào),y表示該字所在的位號(hào),x和y均以二進(jìn)制或十六進(jìn)制表示。這就是“區(qū)位碼”,例如:“啊”字的區(qū)位碼為(0x10,0x01),表示位于16區(qū)第一位。于是漢字庫(kù)中的字模存放位置(相對(duì)于字庫(kù)文件頭的偏移地址)可以由區(qū)位碼計(jì)算得到:偏移地址=區(qū)碼×94+位碼。那么“啊”字的字模相對(duì)于字庫(kù)文件頭的偏移地址等于16×94+1=1505(十進(jìn)制表示)。
但是許多低位數(shù)字已被其它領(lǐng)域所占用,比如:0x06表示通信確認(rèn)回答標(biāo)志。為了不與已經(jīng)存在的信碼相混淆,GB2312在每個(gè)區(qū)位碼上加上0x20,這樣形成的碼叫國(guó)標(biāo)碼。例如:“啊”字的國(guó)標(biāo)碼為(0x30,0x21)。
由于通用的ASCII字符的最高位為0,為了在計(jì)算機(jī)內(nèi)部和之間傳輸漢字時(shí)可以和ASCII碼區(qū)別開來,將表示漢字的兩個(gè)字節(jié)的最高位都置1。這樣,相當(dāng)于在國(guó)標(biāo)碼基礎(chǔ)上高低字節(jié)同時(shí)加了0x80,這就是上面提到的內(nèi)碼。比如:“啊”字的內(nèi)碼為(0xB0,0xA1)。在計(jì)算機(jī)內(nèi)部,用內(nèi)碼來唯一標(biāo)識(shí)一個(gè)漢字。在程序中,通過調(diào)用系統(tǒng)函數(shù)取得某個(gè)漢字的ASCII字符表示,也就得到了這個(gè)漢字的內(nèi)碼。
在明白了內(nèi)碼和區(qū)位碼之間的關(guān)系后,我們可以根據(jù)某個(gè)漢字的內(nèi)碼計(jì)算得到該漢字的區(qū)位碼;再通過區(qū)位碼計(jì)算得到該漢字的字模在漢字庫(kù)表中的偏移地址;從此地址開始的連續(xù)32個(gè)字節(jié)就是該漢字的字模信息。
3.2 字模轉(zhuǎn)換
圖1中所示的漢字顯示與字模存放的關(guān)系是PC機(jī)中的字模存儲(chǔ)格式。而在單片機(jī)系統(tǒng)中,選擇不同的液晶驅(qū)動(dòng)器要求有不同的字模存儲(chǔ)方式。比如我們?cè)趯?shí)際應(yīng)用中,使用的是清華蓬遠(yuǎn)科貿(mào)公司的HD61202液晶驅(qū)動(dòng)器。圖5 指示了HD61202液晶驅(qū)動(dòng)器所要求的字模存放與漢字顯示的關(guān)系。圖中標(biāo)明了標(biāo)出了第1、第2個(gè)字節(jié)和第31、第32個(gè)字節(jié)的存放位置。
造成漢字顯示與字模存放有這樣關(guān)系是因?yàn)椴煌囊壕?qū)動(dòng)器有不同的掃描顯示方式。所以,為了能夠?qū)h字正確的顯示出來,針對(duì)不同的液晶驅(qū)動(dòng)要做相應(yīng)的字模轉(zhuǎn)化。字模轉(zhuǎn)化可以自編一個(gè)轉(zhuǎn)化函數(shù)來實(shí)現(xiàn),在寫入終端字庫(kù)下載文件前將32個(gè)字節(jié)的字模按位轉(zhuǎn)化為需要的格式,再按字節(jié)順序存入下載文件。
經(jīng)過轉(zhuǎn)化之后,“大”字的字模(32個(gè)字節(jié))變成:(32,32,32,32,32,32,160,127,0,64,64,32,16,12,3,0,160,32,32,32,32,48,32,0,1,6,8,16,32,96,32,0), 這就是存放在終端下載字庫(kù)中的字模格式。
參考資料:
1:《單片機(jī)應(yīng)用系統(tǒng)設(shè)計(jì)》 何立民 北京航空航天大學(xué)出版社 1994
2:《漢字編碼標(biāo)準(zhǔn)與識(shí)別》