介紹一種應(yīng)用廣泛的LED 大屏幕異步控制器的設(shè)計(jì)方案,。該系統(tǒng)采用高性能32 位ARM 微處理器為其控制核心,, 并且基于uc/OS- II 進(jìn)行軟件設(shè)計(jì)??蓪?shí)現(xiàn)單屏幕多窗口任意位置的顯示,, 使得屏幕顯示變得豐富靈活。
1,、引言
以往的LED 異步控制器只能把一個(gè)屏幕作為一個(gè)完整的區(qū)域來(lái)進(jìn)行顯示,, 或者簡(jiǎn)單的加上時(shí)間區(qū)域或游走字幕區(qū)域,這樣對(duì)于用戶(hù)來(lái)講往往缺乏足夠的靈活性,, 尤其在屏幕較大的時(shí)候,。針對(duì)以上情況, 本文提出了一款基于32 位高性能ARM處理器和uc/OS- II 的設(shè)計(jì)方案,。它充分利用了uc/OS-II 高效的多任務(wù)管理功能和ARM處理器強(qiáng)大的運(yùn)算能力,, 實(shí)現(xiàn)了單屏幕多窗口的任意位置顯示, 使得顯示內(nèi)容變得更加豐富,, 顯示方式變得更加靈活,。
2、LED 控制系統(tǒng)的工作原理
典型的LED 異步控制系統(tǒng)主要由PC 應(yīng)用軟件,、通信模塊,、數(shù)據(jù)處理模塊、掃描控制模塊,、驅(qū)動(dòng)模塊和LED 屏幾部分組成,,如圖1 所示,。
首先, PC 應(yīng)用軟件將文本或圖片轉(zhuǎn)化為具有特定格式的點(diǎn)陣信息,。然后,, 通過(guò)通信模塊將此點(diǎn)陣信息發(fā)送給數(shù)據(jù)處理模塊。數(shù)據(jù)處理模塊對(duì)這些點(diǎn)陣信息進(jìn)行各種特技處理,, 最后通過(guò)掃描控制模塊和驅(qū)動(dòng)模塊將畫(huà)面在LED 屏上進(jìn)行正確顯示,。
本文所指的LED 異步控制器包括通信模塊、數(shù)據(jù)處理模塊和掃描控制模塊三部分,。
3,、控制器軟件部分的設(shè)計(jì)
本控制器的硬件結(jié)構(gòu)如圖2 所示。數(shù)據(jù)處理模塊由MCU,,一片SRAM和一片F(xiàn)LASH 存儲(chǔ)器組成,。MCU 選用PHILIPS 的基于32 位ARM內(nèi)核的LPC2214 處理器, 它有著豐富的外圍接口資源和強(qiáng)大的運(yùn)算能力,, 是整個(gè)控制器的核心,。SRAM作為MCU 進(jìn)行特技處理時(shí)的緩存使用。FLASH 存儲(chǔ)器用于存儲(chǔ)點(diǎn)陣信息和一些必要的參數(shù),。
掃描控制模塊由CPLD 和顯存組成。顯存為一片SRAM,, 它用于保存當(dāng)前顯示的一幀點(diǎn)陣信息,。CPLD 通過(guò)地址總線和16位數(shù)據(jù)總線與MCU 相連, 它把從MCU 接收到的16 位數(shù)據(jù)按指定地址寫(xiě)入顯存,, 然后再按一定的尋址方式從顯存中讀出點(diǎn)陣信息進(jìn)行掃描,。MCU 只能通過(guò)CPLD 對(duì)顯存進(jìn)行以字(2byte)為單位的寫(xiě)操作。通信模塊包括以太網(wǎng)模塊和串口通信模塊,, 用于實(shí)現(xiàn)PC 與控制器之間的RS232,、RS485 以及工業(yè)以太網(wǎng)通信。
4,、控制器軟件部分的設(shè)計(jì)
為了實(shí)現(xiàn)單屏幕,、多窗口任意位置的顯示, 軟件部分我們基于uc/OS- II 進(jìn)行設(shè)計(jì),, 這樣可以充分利用操作系統(tǒng)高效的任務(wù)調(diào)度算法,, 將每個(gè)窗口的顯示都交由單個(gè)任務(wù)來(lái)完成, 從而極大地提高系統(tǒng)的運(yùn)行速度和可靠性,, 并且使得程序的開(kāi)發(fā)和擴(kuò)展變得更加方便,。
在進(jìn)行具體的程序設(shè)計(jì)之前, 首先要確定數(shù)據(jù)的組織方案,。
因?yàn)楹玫臄?shù)據(jù)組織方案,, 對(duì)于程序編寫(xiě)來(lái)說(shuō)往往可以達(dá)到事半功倍的效果,。
4.1 顯存的數(shù)據(jù)組織方案:
對(duì)于雙色屏, 一個(gè)像素點(diǎn)需要紅,、綠兩位數(shù)據(jù)來(lái)描述,。為了便于處理, 我們將橫向連續(xù)的8 個(gè)像素點(diǎn)組成一個(gè)字(2byte)來(lái)進(jìn)行存儲(chǔ),, 其中一個(gè)字節(jié)為紅數(shù)據(jù),, 一個(gè)字節(jié)為綠數(shù)據(jù)。數(shù)據(jù)存儲(chǔ)順序?yàn)閺淖蟮接遥?從上到下,。如圖3 所示,, 假如屏幕寬度為160 個(gè)像素點(diǎn), 顯存起始地址為0x83000000,, 則屏幕第一行的前8 個(gè)像素點(diǎn)映射到顯存中地址為0x83000000 和0x83000001 的兩個(gè)字節(jié),, 第二行的前8 個(gè)像素點(diǎn)映射到顯存中地址為0x83000028 和0x83000029 的兩個(gè)字節(jié), 依此類(lèi)推,。
4.2 點(diǎn)陣信息轉(zhuǎn)化規(guī)則:
由于窗口大小可以任意設(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)算效率,, 從而影響特技效果的顯示,, 這樣就很難滿足用戶(hù)對(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)行一次查詢(xún),, 如果reset=1,, 它會(huì)刪除原先建立的各窗口顯示任務(wù),, 然后從FLASH 中讀取新的窗口個(gè)數(shù), 依此建立新任務(wù),, 將每個(gè)窗口的顯示交由單個(gè)窗口顯示任務(wù)來(lái)控制,。
下面是任務(wù)TaskControl 的程序演示:
void TaskControl(void *pdata){
uint8 taskNum;
pdata=pdata;
RESET:
reset=0; //reset 標(biāo)志清零
for(taskNum=3;taskNum<18;taskNum++){ // 刪除原先建立的窗口任務(wù)
OSTaskDel(taskNum); // 窗口顯示任務(wù)優(yōu)先級(jí)從3 開(kāi)始}// 最多允許設(shè)置16 個(gè)窗口
taskNum=flashReadWord(AREA_NUM_ADDR);// 從FLASH中讀取屏幕窗口個(gè)數(shù)
if(taskNum>0) // 根據(jù)窗口數(shù)建立窗口顯示任務(wù)
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 標(biāo)志為1, 程序復(fù)位
OSTimeDlyHMSM(0,,0,,1,0);}
}
窗口顯示任務(wù)用于實(shí)現(xiàn)各窗口內(nèi)容的顯示,。它根據(jù)各窗口顯示方式的不同在其相應(yīng)area 區(qū)域中進(jìn)行下一幀數(shù)據(jù)的運(yùn)算,,然后調(diào)用areaToScreen()和screenToCpld()進(jìn)行顯示。在完成一幀數(shù)據(jù)的顯示后,, 調(diào)用一次OSTimeDlyHMSM()使當(dāng)前任務(wù)進(jìn)入等待狀態(tài)同時(shí)進(jìn)行一次任務(wù)調(diào)度,, 將系統(tǒng)控制權(quán)交給處于就緒狀態(tài)的窗口顯示任務(wù)中優(yōu)先級(jí)最高的那個(gè), 由此完成窗口顯示任務(wù)之間的切換,。我們也可以通過(guò)調(diào)整OSTimeDlyHMSM()的參數(shù)來(lái)改變各窗口相臨兩幀顯示信息之間的時(shí)間間隔,, 從而可調(diào)整各窗口特技顯示的效果, 比如移動(dòng)顯示的移動(dòng)速度,。下面是其中一個(gè)窗口顯示任務(wù)的程序演示:
void Task0(void *pdata){
pdata=pdata;窗口參數(shù)初始化;while(1){uint16 i;
for(i=0;i< 總幀數(shù);i++){下一幀數(shù)據(jù)的運(yùn)算; // 在area 區(qū)域中進(jìn)行
areaToScreen(); // 將數(shù)據(jù)從area 讀出寫(xiě)入screen
screenToCpld(); // 將screen 中相應(yīng)數(shù)據(jù)寫(xiě)入顯存完成一幀數(shù)據(jù)的顯示OSTimeDlyHMSM(0,,0,0,,displaySpeed*20); // 任務(wù)調(diào)度
}
}
}
5 結(jié)束語(yǔ)
充分利用32位微處理器的高性能和實(shí)時(shí)操作系統(tǒng)高效的任務(wù)調(diào)度算法,, 實(shí)現(xiàn)了單屏幕多窗口的任意位置顯示。使得屏幕顯示變得更加豐富靈活,, 也使得很多以往只能使用同步控制器或者多個(gè)異步控制器的場(chǎng)合可用單塊異步控制器來(lái)替代,, 從而降低了系統(tǒng)的成本。
本文作者創(chuàng)新點(diǎn):實(shí)現(xiàn)了LED 大屏幕單屏幕多個(gè)窗口任意位置的顯示,, 并且可實(shí)現(xiàn)多窗口重疊顯示及“畫(huà)中畫(huà)”等顯示效果,。