1、引言
以往的LED 異步控制器只能把一個屏幕作為一個完整的區域來進行顯示, 或者簡單的加上時間區域或游走字幕區域,這樣對于用戶來講往往缺乏足夠的靈活性, 尤其在屏幕較大的時候。針對以上情況, 本文提出了一款基于32 位高性能ARM處理器和uc/OS- II 的設計方案。它充分利用了uc/OS-II 高效的多任務管理功能和ARM處理器強大的運算能力, 實現了單屏幕多窗口的任意位置顯示, 使得顯示內容變得更加豐富, 顯示方式變得更加靈活。
2、LED控制系統的工作原理
典型的LED 異步控制系統主要由PC 應用軟件、通信模塊、數據處理模塊、掃描控制模塊、驅動模塊和LED 屏幾部分組成,如圖1 所示。
?
首先, PC 應用軟件將文本或圖片轉化為具有特定格式的點陣信息。然后, 通過通信模塊將此點陣信息發送給數據處理模塊。數據處理模塊對這些點陣信息進行各種特技處理, 最后通過掃描控制模塊和驅動模塊將畫面在LED 屏上進行正確顯示。
本文所指的LED 異步控制器包括通信模塊、數據處理模塊和掃描控制模塊三部分。
3、控制器軟件部分的設計
本控制器的硬件結構如圖2 所示。數據處理模塊由MCU,一片SRAM和一片FLASH 存儲器組成。MCU 選用PHILIPS 的基于32 位ARM內核的LPC2214 處理器, 它有著豐富的外圍接口資源和強大的運算能力, 是整個控制器的核心。SRAM作為MCU 進行特技處理時的緩存使用。FLASH 存儲器用于存儲點陣信息和一些必要的參數。
?
掃描控制模塊由CPLD 和顯存組成。顯存為一片SRAM, 它用于保存當前顯示的一幀點陣信息。CPLD 通過地址總線和16位數據總線與MCU 相連, 它把從MCU 接收到的16 位數據按指定地址寫入顯存, 然后再按一定的尋址方式從顯存中讀出點陣信息進行掃描。MCU 只能通過CPLD 對顯存進行以字(2byte)為單位的寫操作。通信模塊包括以太網模塊和串口通信模塊, 用于實現PC 與控制器之間的RS232、RS485 以及工業以太網通信。
4、控制器軟件部分的設計
為了實現單屏幕、多窗口任意位置的顯示, 軟件部分我們基于uc/OS- II 進行設計, 這樣可以充分利用操作系統高效的任務調度算法, 將每個窗口的顯示都交由單個任務來完成, 從而極大地提高系統的運行速度和可靠性, 并且使得程序的開發和擴展變得更加方便。
在進行具體的程序設計之前, 首先要確定數據的組織方案。
因為好的數據組織方案, 對于程序編寫來說往往可以達到事半功倍的效果。
4.1 顯存的數據組織方案:
對于雙色屏, 一個像素點需要紅、綠兩位數據來描述。為了便于處理, 我們將橫向連續的8 個像素點組成一個字(2byte)來進行存儲, 其中一個字節為紅數據, 一個字節為綠數據。數據存儲順序為從左到右, 從上到下。如圖3 所示, 假如屏幕寬度為160 個像素點, 顯存起始地址為0x83000000, 則屏幕第一行的前8 個像素點映射到顯存中地址為0x83000000 和0x83000001 的兩個字節, 第二行的前8 個像素點映射到顯存中地址為0x83000028 和0x83000029 的兩個字節, 依此類推。
?
4.2 點陣信息轉化規則:
由于窗口大小可以任意設置, 窗口的位置可以任意擺放。
所以對于單個窗口而言, 它在顯存中的映射可能并非是字(2byte)對齊的。以圖4 為例, 在一個大小為160(寬)×96(高)的屏幕上開設一個左上角坐標為(20,16), 大小為86×47 的窗口, 則此窗口第一行的前4 個像素點在顯存中的映射為地址是0x83000282 和0x83000283 的兩個字節的低4 位, 所以這個窗口在顯存中的映射并不是字對齊的。由于MCU 只能以字(2byte)為單位對顯存進行操作, 所以PC 軟件在對該窗口進行點陣信息轉換時, 如果直接對區域1 (窗口的實際大小)進行轉換存儲,則在對該窗口進行特技處理時會存在大量的位運算, 這樣會大大降低運算效率, 從而影響特技效果的顯示, 這樣就很難滿足用戶對特技顯示效果的要求。
?
為了解決上述問題, 可以將區域1 橫向擴展成起點坐標為(16,16), 大小為96×47 的區域2。易知, 區域2 在顯存中的映射是字對齊的。為了避免運算時的位操作, PC 軟件在對區域1 進行點陣信息轉換時, 可按區域2 來進行, 只是需將區域1 的擴展部分的數據全填為1。這樣處理會犧牲掉一小部分FLASH 存儲器空間, 但卻可避免特技處理時大量的位運算, 從而大大提高運算效率, 因此這樣做是值得的。
4.3 緩存數據的組織方案:
由于MCU 只能對顯存進行寫操作, 而在進行特技運算時,往往需要前一幀信息才能得到下一幀的信息。所以, 首先, 需要在緩存中劃分出一塊和顯存大小相等, 地址一一對應的區域screen 用于保存整屏幕的前一幀信息。
?
又由于MCU 對顯存只能進行字操作, 并且多個窗口之間可能會出現區域重疊, 所以如果各窗口的特技運算都直接在screen 區域上進行, 則窗口重疊部分信息可能會發生混亂。因此如圖5 所示, 也需要在緩存中為每個窗口劃分出一塊存儲器空間(area 1, area 2, ..., area n), 用于保存本窗口顯示的前一幀信息。這樣在特技運算時, 首先要在area 區域中對各窗口數據進行運算得到各窗口的下一幀信息, 然后將area 區域中數據寫入該窗口在screen 區域中的相應地址以保存整屏幕最新一幀信息, 最后把screen 中相應數據寫入顯存從而完成顯示。
4.4 軟件設計:
基于上述方案, MCU 程序的設計變得非常簡潔。程序結構如圖6 所示, 控制器上電后, 首先進行系統初始化, 然后從FLASH 中讀取屏參數, 進行參數初始化。接著建立任務TaskCONtrol, TaskControl 擁有比各窗口顯示任務都要高的優先級, 它主要用于對各窗口顯示任務進行實時管理。每隔一段時間TaskControl 就要對reset 標志進行一次查詢, 如果reset=1, 它會刪除原先建立的各窗口顯示任務, 然后從FLASH 中讀取新的窗口個數, 依此建立新任務, 將每個窗口的顯示交由單個窗口顯示任務來控制。
?
下面是任務TaskControl 的程序演示:
void TaskControl(void *pdata){
uint8 taskNum;
pdata=pdata;
RESET:
reset=0; //reset 標志清零
for(taskNum=3;taskNum<18;taskNum++){ // 刪除原先建立的窗口任務
OSTaskDEL(taskNum); // 窗口顯示任務優先級從3 開始}// 最多允許設置16 個窗口
taskNum=flashReadWord(AREA_NUM_ADDR);// 從FLASH中讀取屏幕窗口個數
if(taskNum>0) // 根據窗口數建立窗口顯示任務
OSTaskCreate(task0,(void*)0,&task0Stk[TaskStkLength- 1],3);
if(taskNum>1)
OSTaskCreate(task1,(void*)0,&task1Stk[TaskStkLength- 1],4);
...
while(1){if(reset) goto RESET; //reset 標志為1, 程序復位
OSTimeDlyHMSM(0,0,1,0);}
}
窗口顯示任務用于實現各窗口內容的顯示。它根據各窗口顯示方式的不同在其相應area 區域中進行下一幀數據的運算,然后調用areaToScreen()和screenToCpld()進行顯示。在完成一幀數據的顯示后, 調用一次OSTimeDlyHMSM()使當前任務進入等待狀態同時進行一次任務調度, 將系統控制權交給處于就緒狀態的窗口顯示任務中優先級最高的那個, 由此完成窗口顯示任務之間的切換。我們也可以通過調整OSTimeDlyHMSM()的參數來改變各窗口相臨兩幀顯示信息之間的時間間隔, 從而可調整各窗口特技顯示的效果, 比如移動顯示的移動速度。下面是其中一個窗口顯示任務的程序演示:
void Task0(void *pdata){
pdata=pdata;窗口參數初始化;while(1){uint16 i;
for(i=0;i< 總幀數;i++){下一幀數據的運算; // 在area 區域中進行
areaToScreen(); // 將數據從area 讀出寫入screen
screenToCpld(); // 將screen 中相應數據寫入顯存完成一幀數據的顯示OSTimeDlyHMSM(0,0,0,displaySpeed*20); // 任務調度
}
}
}
5 結束語
實現了單屏幕多窗口的任意位置顯示。使得屏幕顯示變得更加豐富靈活, 也使得很多以往只能使用同步控制器或者多個異步控制器的場合可用單塊異步控制器來替代, 從而降低了系統的成本。