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