由于窗口大小可以任意設置, 窗口的位置可以任意擺放。
所以對于單個窗口而言, 它在顯存中的映射可能并非是字(2byte)對齊的。以圖4 為例, 在一個大小為160(寬)×96(高)的屏幕上開設一個左上角坐標為(20,16), 大小為86×47 的窗口, 則此窗口第一行的前4 個像素點在顯存中的映射為地址是0x83000282 和0x83000283 的兩個字節(jié)的低4 位, 所以這個窗口在顯存中的映射并不是字對齊的。由于MCU 只能以字(2byte)為單位對顯存進行操作, 所以PC 軟件在對該窗口進行點陣信息轉(zhuǎn)換時, 如果直接對區(qū)域1 (窗口的實際大小)進行轉(zhuǎn)換存儲,則在對該窗口進行特技處理時會存在大量的位運算, 這樣會大大降低運算效率, 從而影響特技效果的顯示, 這樣就很難滿足用戶對特技顯示效果的要求。
?
為了解決上述問題, 可以將區(qū)域1 橫向擴展成起點坐標為(16,16), 大小為96×47 的區(qū)域2。易知, 區(qū)域2 在顯存中的映射是字對齊的。為了避免運算時的位操作, PC 軟件在對區(qū)域1 進行點陣信息轉(zhuǎn)換時, 可按區(qū)域2 來進行, 只是需將區(qū)域1 的擴展部分的數(shù)據(jù)全填為1。這樣處理會犧牲掉一小部分FLASH 存儲器空間, 但卻可避免特技處理時大量的位運算, 從而大大提高運算效率, 因此這樣做是值得的。
4.3 緩存數(shù)據(jù)的組織方案:
由于MCU 只能對顯存進行寫操作, 而在進行特技運算時,往往需要前一幀信息才能得到下一幀的信息。所以, 首先, 需要在緩存中劃分出一塊和顯存大小相等, 地址一一對應的區(qū)域screen 用于保存整屏幕的前一幀信息。
?
又由于MCU 對顯存只能進行字操作, 并且多個窗口之間可能會出現(xiàn)區(qū)域重疊, 所以如果各窗口的特技運算都直接在screen 區(qū)域上進行, 則窗口重疊部分信息可能會發(fā)生混亂。因此如圖5 所示, 也需要在緩存中為每個窗口劃分出一塊存儲器空間(area 1, area 2, ..., area n), 用于保存本窗口顯示的前一幀信息。這樣在特技運算時, 首先要在area 區(qū)域中對各窗口數(shù)據(jù)進行運算得到各窗口的下一幀信息, 然后將area 區(qū)域中數(shù)據(jù)寫入該窗口在screen 區(qū)域中的相應地址以保存整屏幕最新一幀信息, 最后把screen 中相應數(shù)據(jù)寫入顯存從而完成顯示。
4.4 軟件設計:
基于上述方案, MCU 程序的設計變得非常簡潔。程序結(jié)構如圖6 所示, 控制器上電后, 首先進行系統(tǒng)初始化, 然后從FLASH 中讀取屏參數(shù), 進行參數(shù)初始化。接著建立任務TaskCONtrol, TaskControl 擁有比各窗口顯示任務都要高的優(yōu)先級, 它主要用于對各窗口顯示任務進行實時管理。每隔一段時間TaskControl 就要對reset 標志進行一次查詢, 如果reset=1, 它會刪除原先建立的各窗口顯示任務, 然后從FLASH 中讀取新的窗口個數(shù), 依此建立新任務, 將每個窗口的顯示交由單個窗口顯示任務來控制。
?