關鍵詞:內置代碼動態編碼字體
由於漢字的特點,顯示漢字壹直是計算機在中國普及的障礙。起初,為了在PC上顯示和處理漢字,中國人發明了壹種硬件設備“漢卡”。後來,各種純軟件技術的中文DOS逐漸成熟,其中,中西方軟件的運行速度和性能仍有明顯差距。最終在軟件進入支持UNICODE並真正實現國際化的WIN95,硬件進入奔騰時代後,實現了漢字和西文的統壹顯示,但這壹切都建立在硬件資源快速發展的基礎上。以國際通用的GB2312為例,壹、二級漢字庫* *包含6000多個漢字,每個漢字按16×16點陣計算,字體需要占用32字節的存儲空間。整個字庫的大小在200k千字節以上,Windows使用高點陣(24點陣以上)和矢量字庫。單片機因其使用靈活、結構簡單、體積小、成本低而被廣泛應用於工業和生活中。也正是因為如此,它的硬件資源非常有限,尋址和計算能力遠低於PC,漢字的顯示更受限制。人們已經不滿足於單片機系統中LED數碼管的簡單顯示。根據單片機的特點,開發了許多漢字顯示方法。
1單片機顯示漢字的幾種常用方法
(1)使用標準單詞【1】
這種方法模仿中文DOS的方法,在ROM存儲器中裝入壹個標準的漢字庫,然後根據漢字的內碼在字體庫中尋址,找到相應的字體,提取出來送到顯示器上顯示。由於它使用與PC相同的代碼(內置代碼),因此該軟件的開發和維護非常簡單,基本上類似於編寫PC軟件。然而,對單片機系統本身的要求要高得多。16×16點陣的字體需要256千字節,而8位單片機的尋址能力只有64K字節。要擴展內存,除了增加很大壹部分硬件成本外,還會因為內存的分頁管理和地址切換而明顯影響顯示速度,並且只能顯示壹種點陣字體。
(2)直接固化顯示字體【2】
要顯示的句子中所有漢字的字體數據被依次提取並存儲在存儲器中,當顯示時,字體數據被直接提取並發送到顯示器。該方法占用空間少,程序簡單,顯示速度快。然而,字體數據的提取和存儲安排是壹件復雜的事情。幾乎不可能顯示大量漢字或修改程序,軟件的可維護性很差。
(3)建立小字體索引【3】
所有要顯示的漢字統壹為壹個小字體,分為索引和字體表兩部分。索引表由若幹固定長度的記錄組成,記錄的內容為:漢字內碼、地址碼和識別碼。地址碼是漢字字體在字表中的位置,標識碼標識漢字的點陣形式或字體。中文字體根據主要引用存儲在字體表中。顯示漢字時,先根據要顯示的漢字的內置代碼在索引表中進行搜索,找到對應的索引記錄後讀出地址碼和識別碼,再據此從字體表中讀出字體,發送顯示。這種方法可以根據實際使用情況裁剪字體,硬件開銷較小,但如果進行復雜的查詢操作,平均搜索時間會較長,效率會降低。
2漢字動態編碼
綜上所述,我們發現在方法1中,程序員的工作量最少,但單片機密鑰機的軟硬件開銷最多;方法二,單片機成本少,但軟件編寫和維護極其困難;方法3,介於兩者之間。顯然,存儲空間、顯示速度和軟件開發維護之間存在矛盾。受各種PC機模擬軟件的啟發,我們提出了壹種基於PC機預處理的漢字顯示方法——漢字動態編碼,在實際應用中很好地解決了這壹問題。其基本原則如下:建立新的編碼機制,該機制是動態的;壹個代碼並不具體與壹個漢字相關聯,而只代表壹個漢字在字體中的位置(這個位置也是動態的);請改用此代碼。
在程序中,字符串(C語言)或數據段(匯編語言)中漢字的內置代碼可以根據這個新代碼直接在專門建立的動態小字體庫中找到,而無需尋址和搜索等復雜操作,如圖1所示。
實現漢字動態編碼的過程是先識別漢字,再建立編碼字典,提取字體,建立動態字庫,改寫內碼。首先對程序文件進行掃描識別漢字,漢字按照出現的先後順序或內碼的大小進行排序,通過剔除重復出現的漢字建立編碼字典。根據漢字在編碼字典中的位置(序號),漢字可以用區號和位碼編碼,也可以用其他方法編碼。簡而言之,序列號與其動態編碼之間存在壹壹對應關系。根據字典中每個漢字的內置編碼,從PC的漢字點陣字庫中依次提取字體並按順序存儲,建立小規模動態字庫,使字庫中每個漢字字體的位置與其在編碼字典中的序號和動態編碼壹壹對應。最後,再次掃描程序文件,根據編碼字典將每個漢字的內碼改寫成相應的動態碼。因為程序文件中的漢字會隨時增減,編碼也會相應變化,字體的大小也會隨時變化。因此被稱為動態編碼和動態字體。
考慮到壹般應用,大約65,438+0,000個漢字可以滿足要求。根據漢字動態編碼方法,所需的字體大小僅為32k字節,並且只需要1塊27256,幾乎不需要額外的硬件。這樣,字體的大小可以由漢字的數量來控制,編程和維護可以遵循中文系統的習慣,並且PC只需對準備好的單片機程序進行壹次預處理,從而將程序員從復雜的漢字處理工作中解放出來,有效地降低了軟件和硬件開發的成本。
3漢字動態編碼的具體實現
實現漢字動態編碼的關鍵是建立編碼字典和改寫內碼。下面以顯示1行漢字“天上有太陽,水裏有月亮”為例,說明動態編碼的實現過程。
(1)漢字識別
漢字在PC機中的存儲和處理是通過內碼來實現的。每個漢字的內置碼是唯壹的,由兩個字節組成,即區號和位碼。為了區別於西方的ASCII碼,漢字內置碼的區號和位碼的值都大於0A0H。我們要處理的源程序文件都是文本文件,其中存儲了所有西文字符、控制符號的ASCII碼和漢字的內置碼。當掃描文件中的字節內容時,可以判斷該字節為漢字內置碼的1字節,並且必須成對出現。1字節是壹個差,第二個字節是壹個位代碼,兩個字節都大於0‘0h,否則將出錯。
在C語言和匯編語言中有不同的表示字符的方式,但文件中最終字符的存儲格式是相同的。顯示上面的漢字,在C語言中可以表示為:
char OneSent【】=“天上有太陽,水裏有月亮”;
print fhz(OneSent);/*printfh
z(顯示函數*/
使用十六進制編輯器(我們使用UEdit32)查看文件中的C語言字符串定義語句,如下所示:
63 68 61 72 20 20 4F 6E 65 53 65 6E 74 5B 5D 20 3D 20 22 CC歐共體C9 CF D3 D0 B8 F6 CC AB d 1 F4 A3 AC CB AE D6 D0 D3 D0 B8 F6 D4 C2 c 1 c 1 22 20 3B 0A
在匯編語言中,它可以表示為:
ONESENT:DB“天上有太陽,水裏有月亮”,00H
MOV·DPTR
LCALL顯示;DISPLAY是顯示子程序。
使用十六進制編輯器查看用匯編語言定義字符串的語句,如下所示:
4F 4E 45 53 45 4E 54 3A 44 42 20 27 CC歐共體C9 CF D3 D0 B8 F6 CC AB d 1 F4 A3 AC CB AE D6 D0 D3 D0 B8 F6 D4 C2 c 1 c 1 27 2C 30 30 48 0A
由此可以看出,情況確實如上文所述。
2)建立編碼字典
在掃描的同時逐漸建立編碼字典。每次掃描壹個漢字(包括全角符號)時,都會將其與字典中的現有字符進行比較。如果沒有重復,新字符將按順序存儲在字典中,否則,掃描將繼續進行,直到該文件屬於。因為每個字符都是從尾部開始添加的,所以它們的序號也是依次遞增的,可以根據序號進行動態編碼。由於顯示的漢字壹般超過256個,即使進行動態編碼,也需要通過2字節編碼來實現。以MCS51系列單片機和16×16點陣漢字為例進行優化編碼:8051的地址指針DPTR是壹個16位指針,由高、低兩個字節的指針DPH和DPL組成。如果內存以0 ffh(256)字節分布,請修改DPH。壹個16×16點陣漢字的字體大小為32字節,每頁內存剛好可以容納8種漢字字體。可以優化設計動態編碼高字節指向字體的頁面地址(DPH),低字節指向字體位於頁面的第壹個地址(DPL)。考慮到地址空間的有效分配,字體的地址應放在0A000H之後(程序和數據存儲均如此),動態編碼的高字節應加上有效的地址分配,字體的地址應放在0A000H之後(程序和數據存儲均如此),動態編碼的高字節應加上地址的頁面偏移量(大於或等於00h);考慮到漢字和西文字符的差異,動態編碼的低字節也需要添加大於或等於0A0H的偏移量。設編碼字典中漢字的序號為num,則漢字的動態編碼為:
動態編碼高字節=頁面偏移+數字/8
動態編碼的低位字節=偏移量+(Num % 8)×32(1)
失調通常可以設置為0A0H。單片機顯示壹個漢字時,只需將其動態編碼的高字節送到DPH,低字節減少0A0H後送到DPL,即可得到相應字體的地址指針。
(3)提取字體並建立動態字體。
漢字內碼與點陣字體的詳細關系請參閱相關資料。它們的關系如下:
前綴地址=((內部代碼高字節-1)×94+(內部代碼低字節-1))×N(2)
註:n是漢字點陣字體的字節數。
根據編碼字典的內容和字體的起始地址,依次取出中文字體並寫入二進制文件,即建立壹個動態字體庫(其他方法省略)並通過編程設備寫入EPROM,即可使用。
④編碼重寫
PC使用內置代碼來識別和處理漢字。單片機只能處理我們建立的動態碼,需要根據編碼字典將程序中漢字的唯壹機器碼轉換為相應的動態碼。因為妳在源程序的文本編輯器中看到的是系統處理後的字節,妳看不到漢字的內碼,也無法重寫。根據“漢字識別”部分,動態編碼(十六進制數)可以直接更改到磁盤文件的相應位置,而無需經過文本編輯器,但處理後的漢字會在文本編輯器中顯示亂碼。
⑤漢字顯示
在了解動態字體庫中動態編碼與字體的關系後,我們可以根據PC下漢字顯示的原理,完成單片機下的程序設計,並編寫前面函數printhz()或子程序的顯示,以供參考【4】。
4 MCS51漢字顯示程序
根據上述漢字動態編碼方法,我們用Borland C++編寫了壹個PC預處理程序。在用PC對ASM51或C51源程序進行預處理後,我們構建了壹個動態字體並重寫了內置代碼,並用ASM51編寫了壹個針對MCS51優化的子程序DIS_CHAR。它顯示壹個西文或中文字符,實現過程如圖2所示。
西文字符代碼的顯示與流字符的顯示基本相同。只需將西文字庫(只有數字和字符)加載到程序內存中,根據ASCII碼的值計算前綴地址,依次讀出字符字體,然後發送顯示即可。
該方案不僅適用於單片機系統,也適用於任何沒有中文系統支持的嵌入式系統。按照這壹思路,我們還可以設計壹個包含不同字體和點陣的字體庫,支持包含2萬多個字符的新國標編碼,甚至矢量字體在單片機系統中的應用也成為可能。由於技術水平有限,該方案仍存在壹些不足。例如,源程序中的漢字經過重寫和編碼後顯示為亂碼,不知道編碼是否正確,操作復雜。如果能夠利用插件技術實現這種方案,在編輯器中可以正常顯示漢字,並且輸出的已經是代碼修改後的程序文件,就可以很好地解決上述缺點。在此,我們希望感興趣的朋友能壹起合作,實現單片機中文顯示的通用開發平臺。
動態編碼預處理的C語言源程序(在BC++3.1下調試)見網站補充版()。