馬志剛
(深圳職業(yè)技術學院 計算機工程學院,廣東 深圳 518055)
UCGUI是一種輕量級的嵌入式圖形支持系統(tǒng),它的設計架構是模塊化的,由不同的模塊中的不同層組成.UCGUI可以在任何的CPU上運行,因為它是100%的標準C代碼編寫的.UCGUI提供一個可擴展的2D圖形庫及占用極少RAM的窗口管理體系,非常適合如 STM32這樣的輕量級嵌入式平臺的圖形界面顯示[1],大量應用于各種智能儀器儀表的液晶屏人機界面.UCGUI原生的字符顯示機制需要程序員事先把程序中用到的字符點陣信息轉化為C語言數(shù)組并組成一個鏈表結構作為字庫,然后將該字庫與整個工程一起進行編譯鏈接,最終字庫是包含在目標文件中.此機制對于英文這樣基于字母的文字非常方便,生成內建的字庫很方便,也不會大量增加目標文件的體積.然而對于漢字這樣包含龐大字符數(shù)量的文字[2],采用此方法就存在很大的缺陷.因為在絕大部分應用場合都是無法事先預知有哪些漢字需要顯示,而如果把所有常用漢字按照 UCGUI的規(guī)則轉化為C語言鏈表結構,則工作量巨大且大大增加目標文件體積,如果應用于 STM32這樣程序存儲空間并不寬裕的平臺,很可能因為空間不足而無法實現(xiàn)程序的燒寫.所以對于大量文字的隨機顯示,更好的方案是將字庫與程序代碼分開.但是UCGUI本身并沒有提供從外部存儲器讀取字庫的接口,如果程序員自行編寫代碼從外部字庫讀取字符信息并使用UCGUI提供的上層繪圖接口直接在LCD上繪制漢字點陣的話,則顯示的漢字不能與 UCGUI的圖層機制兼容,無法配合UCGUI中的其他圖形控件使用,例如無法在按鈕上添加漢字.本文介紹一種通過修改UCGUI底層字符驅動函數(shù)的方法,為UCGUI實現(xiàn)將字庫獨立于目標文件存儲,并且充分兼容UCGUI圖形庫中的各種控件.
為了能夠存儲漢字庫中的大量數(shù)據(jù),本文在STM32處理器上外接Flash存儲芯片來擴大存儲空間.例如可采用 SPI接口的 Nand Flash 芯片M25PX16來擴展存儲空間,該芯片具有16Mbit容量,具備4K字節(jié)子區(qū)擦除功能,最高支持75Mhz的SPI接口等特性,將其與主控芯片STM32進行連接如圖1所示.
圖1 外部Flash硬件連接圖
STM32處理器的IO管腳大部分都具有復用功能,為了對 M25PX16進行訪問,其 IO管腳PB13~PB15將分別配置為復用功能SPI2_SCK,SPI2_MISO和SPI2_MISI,即作為STM32的SPI2接口.然后對STM32的SPI2口進行配置,這里的配置主要是將SPI2設為全雙工主模式,數(shù)據(jù)位設為8位,另外還有時序模式,波特率因子,數(shù)據(jù)幀格式以及CRC多項式的相關配置,最后使能SPI2.
經過軟硬件的相關工作,現(xiàn)在外部Flash已經可以正常使用了,下一步工作是定義Flash的相關操作函數(shù),如擦除,寫入,讀取等.然后利用串口或是USB接口等外部接口將漢字庫下載到STM32并燒寫到外部Flash中.本文使用的是16x16點陣的GBK碼漢字庫,大小為256 kB左右.
使用 UCGUI提供的自定義字體轉換工具可以將指定的字符點陣信息轉化到一個由C語言實現(xiàn)的鏈表中并封裝到一個結構體里,以編譯到目標文件中供 UCGUI顯示時使用.為了最大限度地利用 UCGUI本身的這一顯示機制,提高外掛字庫的兼容性,本文先使用 UCGUI提供的的字體庫轉換工具針對16x16點陣字體生成一個含有數(shù)字0~9,英文字符a-z以及A-Z的鏈表式字體庫,并將其封裝到結構體 GUI_FontHZ_SimSun_16中,該結構體的第一個元素GUI_FONTTYPE_PROP_SJIS是在頭文件GUIType.h中定義的用于設定字體屬性的宏,此宏定義指明了該字體使用的字符顯示驅動函數(shù)為GUIPROP_DispChar.我們要做的事情就是要修改這個顯示驅動函數(shù).首先,修改 GUI_FONTTYPE_PROP_SJIS的定義,將字符顯示驅動函數(shù)改為指向我們自定義的函數(shù)My_GUIPROP_DispChar,這樣,只需要在我們自定義的字符顯示驅動函數(shù)My_GUIPROP_DispChar中實現(xiàn)讀取外部 Flash中的漢字庫來顯示即可,此函數(shù)的源代碼如下:
在上面的函數(shù)中,首先通過字符的機內碼c判斷要顯示的字符是否為漢字,如果不是漢字,則直接使用 UCGUI原來的顯示驅動GUIPROP_DispChar從鏈表字庫中讀取字符來顯示;如果是漢字,則調用我們自己定義的從外部Flash讀取字符的顯示驅動函數(shù)WriteHZ,該函數(shù)從漢字庫中讀取字符的點陣信息供 UCGUI顯示,其主要代碼如下:
即先根據(jù)漢字內碼p算出區(qū)位碼c1和c2,再根據(jù)區(qū)位碼計算出要顯示的漢字在漢字庫中的偏移量AddrInTable,然后調用Flash_Read函數(shù)從外部Flash中讀取漢字的點陣信息來進行顯示.其中FontLibStartPage是漢字庫燒寫入 Flash時的起始頁地址(本文使用的 Flash芯片每頁為 256字節(jié)),數(shù)組 pixeldata 是字符點陣信息的顯示緩沖區(qū).
經過上面的改動,在需要顯示漢字的場合,只需要調用設置字體的函數(shù)將字體設置為我們最開始定義的字體 GUI_FontHZ_SimSun_16 即可.例如要在按鈕Button0上顯示漢字,可調用如下函數(shù):
BUTTON_SetFont( Button0 , &GUI_FontHZ_SimSun_16);
通過對UCGUI原有的字符顯示機制進行改造,在充分兼容其控件系統(tǒng)的前提下,實現(xiàn)了將漢字庫獨立于目標代碼文件存儲在外部 Flash中,適合需要顯示大量不確定性漢字的場合,彌補了UCGUI在漢字顯示方面的先天缺陷,使得這一優(yōu)秀的圖形系統(tǒng)有了更大的用武之地.
[1] 王蘭英.基于STM32嵌入式系統(tǒng)的uCGUI移植與實現(xiàn)[J].四川理工學院學報(自然科學版),2012,25(1):56-58.
[2] 國家標準總局.GB2312-80信息交換用漢字編碼字符集基本集[S].1981.