專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

uC/OS ii與μc/gui移植詳細(xì)介紹

作者:佚名   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年08月18日   【字體:

uC/OS ii文件體系結(jié)構(gòu):

1:核心部分(OSCore.c)
   這部分代碼是操作系統(tǒng)的核心,包括操作系統(tǒng)的初始化、操作系統(tǒng)運(yùn)行、中斷進(jìn)出的前導(dǎo)、時(shí)鐘節(jié)拍、任務(wù)調(diào)度、事件處理等多部分。能夠維持系統(tǒng)基本工作的部分都在這里。
2:任務(wù)處理部分(OSTask.c)
   任務(wù)處理部分中的代碼內(nèi)容都是與任務(wù)的操作密切相關(guān)的,包括任務(wù)的建立、刪除、掛起、恢復(fù)等待。因?yàn)?span style="line-height: 19.09090805053711px;">uC/OS ii是以任務(wù)為基本單位進(jìn)行調(diào)度的,所以這部分內(nèi)容相當(dāng)重要。
3:時(shí)鐘部分(OSTime.c)
   uC/OS ii的最小時(shí)鐘單位是timetick(時(shí)鐘節(jié)拍)。任務(wù)延時(shí)等操作就是在這里完成。
4:任務(wù)同步與通信部分
   這部分代碼為事先處理部分(需要在OS_cfg.h文件中進(jìn)行功能選擇使能),包括信號量、郵箱、郵箱隊(duì)列、事件標(biāo)志等部分,主要用于任務(wù)間的相互聯(lián)系和對臨界資源的訪問。
5:CPU的接口部分(Ports)--需要移植的代碼部分
  這部分是需要根據(jù)具體的CPU來做移植,且這部分由于很多涉及到具體硬件,所以很多都是用匯編來寫。主要包括中斷級任務(wù)切換的底層實(shí)現(xiàn)、任務(wù)級任務(wù)切換的底層實(shí)現(xiàn)、時(shí)鐘節(jié)拍的產(chǎn)生和處理、中斷的相關(guān)部分等。
 
uC/OS ii移植需要滿足的條件:
1:處理器支持中斷,并能夠產(chǎn)生定時(shí)中斷(通常在10~1000HZ)
   uC/OS ii是通過中斷(軟)來實(shí)現(xiàn)任務(wù)現(xiàn)場的切換,做到任務(wù)的切換;uC/OS ii中需要時(shí)基函數(shù)來進(jìn)行任務(wù)的延時(shí)等(uC/OS iii支持時(shí)間片輪轉(zhuǎn),所以時(shí)基還用來做任務(wù)切換),M3中有一個(gè)硬件的systick定時(shí)器,專門用來產(chǎn)生定時(shí)中斷。
2:在程序中可以打開或者關(guān)閉中斷
  uC/OS ii中,打開/關(guān)閉中斷主要通過OS_ENTER_CRITICAL()或OS_EXIT_CRITICAL()兩個(gè)宏實(shí)現(xiàn),在任務(wù)的切換時(shí),是需要關(guān)中斷的(進(jìn)入臨界區(qū))。
3:處理器的C編譯器能產(chǎn)生可重入代碼
  uC/OS ii中,大部分函數(shù)都是用C編寫的,所以編譯時(shí),需要產(chǎn)生可重入的代碼(可以被一個(gè)以上的任務(wù)調(diào)用),可重入代碼中不能使用全局變量,且可重入代碼中的局部變量一般使用CPU的通用寄存器或堆棧(這個(gè)需要編譯器支持),所以對編譯器是有要求的。
4:處理器需具備一定量數(shù)據(jù)的硬件堆棧
  uC/OS ii中,有一些系統(tǒng)使用的數(shù)據(jù)結(jié)構(gòu)(各種列表來管理系統(tǒng)的資源)需要一定的RAM空間,同時(shí)任務(wù)切換、局部變量等都需要使用堆棧,所以對RAM(堆棧也有要求),M3中,應(yīng)用程序(PSP)與異常服務(wù)程序(MSP)使用的堆棧指針是不一樣的,這樣起保護(hù)作用。
5:處理器有將堆棧指針和其他CPU寄存器 存儲(chǔ)與讀出到內(nèi)存(堆棧)的指令
  uC/OS ii中,任務(wù)切換時(shí)一般要讀取CPU的各個(gè)通用與特殊功能寄存器,M3用MRS、MSR等命令。
uC/OS ii的移植要點(diǎn):
  uC/OS ii的移植相當(dāng)LINUX來說是非常簡單的,uC/OS ii的移植涉及到的代碼很少;我們只需要修改與處理器相關(guān)的代碼即可;
  OS_CPU.H:設(shè)置與處理器與編譯器有關(guān)的代碼
  OS_CPU_C.C:在這其中用C語言編寫6個(gè)與操作系統(tǒng)相關(guān)的函數(shù)
  OS_CPU.ASM:在這其中用匯編語言編寫4個(gè)與處理器相關(guān)的函數(shù)
  如上圖,需要移植的部分就是Ports路徑下的幾個(gè)代碼文件,其他的代碼都不要移植(os_cfg.h只是用來配置系統(tǒng)的各個(gè)功能,做系統(tǒng)的裁剪而且,ucos_ii.h中提供系統(tǒng)所有的接口函數(shù),os_cpu_a.asm就是OS_CPU.ASM
1:修改OS_CPU.H
  OS_CPU.H中定義了數(shù)據(jù)類型、處理器的堆棧數(shù)據(jù)類型的字長、堆棧增長方向、任務(wù)切換宏、臨界區(qū)訪問處理。
  從方便移植的角度,uC/OS ii使用的數(shù)據(jù)類型,都是自己定義的那一套。
      typedef unsigned char  BOOLEAN;
      typedef unsigned char  INT8U;                   
      typedef signed   char  INT8S;                    
      typedef unsigned short INT16U;                   
      typedef signed   short INT16S;                  
      typedef unsigned long  INT32U;                  
      typedef signed   long  INT32S;                  
      typedef float          FP32;                    
      typedef double         FP64;   
                  
      typedef unsigned int   OS_STK;                  
      typedef unsigned int   OS_CPU_SR;          
   M3使用的是向下生長的滿棧,堆棧指針指向最后一個(gè)被壓入堆棧的32位整數(shù):
      #define  OS_STK_GROWTH  
   定義開關(guān)中斷的宏:
      #define  OS_CRITICAL_METHOD   3
      #if OS_CRITICAL_METHOD == 3
      #define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}
      #define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}
      #endif
   定義宏OS_TASK_SW執(zhí)行任務(wù)切換:#define  OS_TASK_SW()         OSCtxSw()

2:在OS_CPU_C.C中要求用戶編寫10個(gè)簡單的C函數(shù)【唯一必要修改的函數(shù)是OSTaskStkInit(),其余的函數(shù)必須聲明,但并不一定要包含任何代碼
OSTaskStkInit():任務(wù)創(chuàng)建函數(shù)OSCreate()與OSCreateExt()通過調(diào)用OSTaskStkInit,初始化任務(wù)的棧結(jié)構(gòu),因此,任務(wù)的堆?雌饋砭拖駝偘l(fā)生了中斷一樣(所以的寄存器按一定的次序都保存在堆棧中,為什么要這樣做?因?yàn)槿蝿?wù)間的切換就是任務(wù)堆棧中保存的CPU現(xiàn)場的切換,所以任務(wù)被創(chuàng)建時(shí),要初始化它的堆棧,為后面的切換做準(zhǔn)備)
OSTaskCreateHook(ptcb):【系統(tǒng)提供給用戶的鉤子函數(shù)】任務(wù)創(chuàng)建時(shí)OSCreate()與OSCreateExt()調(diào)用OS_TCBInit,OS_TCBInit會(huì)調(diào)用OSTaskCreateHook,同時(shí)傳遞指向剛剛建立的任務(wù)的任務(wù)控制塊的指針,這樣OSTaskCreateHook就可以訪問任務(wù)控制塊結(jié)構(gòu)的所有成員,這個(gè)函數(shù)的功能有限,不是必要的函數(shù),且需要通過OS_APP_HOOKS_EN使能,且該函數(shù)調(diào)用時(shí)中斷是開著的。
OSTaskDelHook(ptcb):OSTaskDel()會(huì)調(diào)用OSTaskDelHook(ptcb),即在將任務(wù)從uC/OS II的內(nèi)部有效鏈表中刪除之前被調(diào)用,同時(shí)傳遞一個(gè)指向被刪除任務(wù)的任務(wù)控制塊的指針,OSTaskDelHook可以用來檢驗(yàn)TCB擴(kuò)展部分是否已建立(一個(gè)非空指針),并可進(jìn)行一些清0操作,OSTaskDelHook調(diào)用時(shí),中斷是關(guān)閉的,函數(shù)太長會(huì)影響中斷響應(yīng)時(shí)間。
OSTaskSwHook():在任務(wù)切換時(shí)會(huì)調(diào)用OSTaskSwHook,不論是在OSCtxSw()還是OSIntCtxSw(),都會(huì)調(diào)用該函數(shù),OSTaskSwHook可訪問全局變量OSTCBCur(指向?qū)⒈磺袚Q出去的任務(wù)的任務(wù)控制塊)、OSTCBHiggRdy(指向新任務(wù)的任務(wù)控制塊) ,OSTaskSwHook被調(diào)用時(shí),中斷是關(guān)閉的,函數(shù)太長會(huì)影響中斷響應(yīng)時(shí)間。
OSTaskIdleHook():很多微處理器都允許執(zhí)行相應(yīng)的指令,將CPU置于低功耗模式,而當(dāng)接收到中斷信號時(shí),CPU就會(huì)自動(dòng)退出低功耗模式。OS_TaskIdle()函數(shù)可以調(diào)用OSTaskIdleHook()來實(shí)現(xiàn)CPU的這種低功耗模式【很好】。
OSTaskStatHook():該函數(shù)每秒都會(huì)被統(tǒng)計(jì)任務(wù)OS_TaskStat()【統(tǒng)計(jì)任務(wù)每秒執(zhí)行一次】調(diào)用一次,可以通過該函數(shù)擴(kuò)展統(tǒng)計(jì)任務(wù)的功能,如可跟蹤并顯示每個(gè)任務(wù)的執(zhí)行時(shí)間、每個(gè)任務(wù)所用的CPU份額以及每個(gè)任務(wù)執(zhí)行的頻率等等,該函數(shù)沒有任何參數(shù)。
OSTimeTickHook():該函數(shù)在每個(gè)時(shí)鐘節(jié)拍都會(huì)被OSTimeTick()調(diào)用;systick中斷服務(wù)程序SysTickHandler調(diào)用OSTimeTickHook,在這里面用戶可以處理應(yīng)急的事務(wù)。
OSInitHookBegin():進(jìn)入OSInit()函數(shù)后,OSInitHookBegin就會(huì)被調(diào)用,添加這個(gè)函數(shù)的原因在于想把與OS有關(guān)的初始化代碼也放在OSInti()函數(shù)中,這個(gè)函數(shù)使得用戶可以將自己特定的代碼也放在OSInit()函數(shù)中。
OSInitHookEnd():OSInitHookEnd與OSInitHookBegin相似,只是他在OSInit()函數(shù)返回之前被調(diào)用,添加這個(gè)函數(shù)的原因與OSInitHookBegin是一樣的。
OSTCBInitHook(ptcb):任務(wù)創(chuàng)建時(shí)OSCreate()與OSCreateExt()調(diào)用OS_TCBInit,OS_TCBInit會(huì)在調(diào)用OSTaskCreateHook前調(diào)用 OSTCBInitHook ,用戶可以在OSTCBInitHook函數(shù)中做一些與初始化控制塊OS_TCB有關(guān)的處理,在OSTaskCreateHook中做一些與初始化任務(wù)有關(guān)的處理;OSTCBInitHook收到的ptcb參數(shù)指向新添加任務(wù)的任務(wù)控制塊的指針,而這個(gè)新添加任務(wù)的任務(wù)控制塊絕大部分已經(jīng)初始化完成,但是還沒有鏈接到已經(jīng)建立任務(wù)的鏈表中。
OS_STK * OSTaskStkInit (void (*task)(void *p_arg), 
                        void *p_arg, 
                        OS_STK *ptos, 
                        INT16U opt)
{
    OS_STK *stk;
    (void)opt;                                
    stk       = ptos;    
    *(stk)    = (INT32U)0x01000000L;           //xPSR                                 
    *(--stk)  = (INT32U)task;                  //Entry Point                          
 *(--stk) = (INT32U)0xFFFFFFFEL; // R14(LR) (init value will cause fault if ever used)    
    *(--stk)  = (INT32U)0x12121212L;          // R12                                  
    *(--stk)  = (INT32U)0x03030303L;          // R3  
    *(--stk)  = (INT32U)0x02020202L;           // R2   
    *(--stk)  = (INT32U)0x01010101L;           //  R1    
    *(--stk)  = (INT32U)p_arg;                 // R0 : argument  

   //Remaining registers saved on process stack 
    *(--stk)  = (INT32U)0x11111111L;           // R11  
    *(--stk)  = (INT32U)0x10101010L;           // R10  
    *(--stk)  = (INT32U)0x09090909L;           // R9    
    *(--stk)  = (INT32U)0x08080808L;           // R8      
    *(--stk)  = (INT32U)0x07070707L;           // R7     
    *(--stk)  = (INT32U)0x06060606L;           // R6     
    *(--stk)  = (INT32U)0x05050505L;           // R5     
    *(--stk)  = (INT32U)0x04040404L;           // R4       
    return (stk);
}
 
   
3:在OS_CPU_A.ASM中用匯編寫4個(gè)與處理器相關(guān)的函數(shù)
   需要移植的函數(shù)有,如下所示,
   OSStartHighRdy():在調(diào)用OSStart()函數(shù)時(shí),使就緒態(tài)任務(wù)中優(yōu)先級最高的任務(wù)開始運(yùn)行
   OSCtxSw():
   OSIntCtxSw():
   OSTickISR():
   OS_CPU_SR_Save()
   OS_CPU_SR_Restore():
 
OSCtxSw():可以參考學(xué)習(xí)筆記中的記錄,M3中任務(wù)切換還需實(shí)現(xiàn)軟中斷的處理函數(shù)
OSCtxSw   ;懸起PSV異常
    LDR     R0, =NVIC_INT_CTRL                                  
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR
 
OSIntCtxSw():在退出中斷前調(diào)用OSIntCtxSw,在ISR中執(zhí)行任務(wù)的切換功能,OSIntCtxSw與OSCtxSw基本相同,M3的是一模一樣的。

OSPendSV 【軟中斷的處理函數(shù)】
    MRS     R0, PSP                                            
    CBZ     R0, OSPendSV_nosave                                
 
    SUBS    R0, R0, #0x20                                      
    STM     R0, {R4-R11}
 
    LDR     R1, __OS_TCBCur                                    
    LDR     R1, [R1]
    STR     R0, [R1]                                           
              
OSPendSV_nosave
    PUSH    {R14}                                               
    LDR     R0, __OS_TaskSwHook                                 ; OSTaskSwHook();
    BLX     R0
    POP     {R14}
 
    LDR     R0, __OS_PrioCur                                  
    LDR     R1, __OS_PrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]
 
    LDR     R0, __OS_TCBCur                                   
    LDR     R1, __OS_TCBHighRdy
    LDR     R2, [R1]
    STR     R2, [R0]
 
    LDR     R0, [R2]                                          
    LDM     R0, {R4-R11}                                        
    ADDS    R0, R0, #0x20
    MSR     PSP, R0                                             
    ORR     LR, LR, #0x04                                       
    BX      LR   


OSTickISR在這里即SysTickHandler函數(shù)
void SysTickHandler(void)
{
    OS_CPU_SR  cpu_sr;
    OS_ENTER_CRITICAL();  
    OSIntNesting++;
    OS_EXIT_CRITICAL();  
    OSTimeTick();     //主要判斷延時(shí)的任務(wù)是否計(jì)時(shí)到
    OSIntExit();  //在os_core.c文件里定義,如果有更高優(yōu)先級的任務(wù)就緒了,則執(zhí)行一次任務(wù)切換
}

OSStartHighRdy
    LDR     R0, =NVIC_SYSPRI2                                   
    LDR     R1, =NVIC_PENDSV_PRI
    STRB    R1, [R0]               //這幾句是設(shè)置PendSV優(yōu)先級

    MOVS    R0, #0                                             
    MSR     PSP, R0          //設(shè)置PSP的初始值0(在第一次PendSV中斷服務(wù)程序中不用保存CPU的各寄存器)

    LDR     R0, __OS_Running                                 
    MOVS    R1, #1
    STRB    R1, [R0]             // OSRunning = TRUE,表明操作系統(tǒng)已經(jīng)運(yùn)行 

    LDR     R0, =NVIC_INT_CTRL                                 
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]            //觸發(fā)PendSV中斷,暫時(shí)掛起

    CPSIE   I                   //開總中斷【一定要在這里才開總中斷,如果在此之前任何一個(gè)地方開中斷,系統(tǒng)一旦響應(yīng)中斷,很有可能造成系統(tǒng)因沒有做出足夠的準(zhǔn)備而出錯(cuò)(比如如果在初始化systicks時(shí)就開啟了中斷,uC/OS此時(shí)還處于未知階段,就會(huì)崩潰),所在在這里開啟總中斷才是安全的                                       
 
OS_CPU_SR_Save() 
    MRS     R0, PRIMASK   ;保存全局中斷標(biāo)志  
    CPSID   I           ;關(guān)中斷
    BX      LR
OS_CPU_SR_Restore()
    MSR     PRIMASK, R0    ;恢復(fù)全局中斷標(biāo)志
    BX      LR
 
 
【到此移植完畢】
 
---------下面談?wù)剈CGUI的移植------------------------------------------------------------------------------------------------------------------
 
   μc/gui與 uC/OS出于同一公司,是美國micrium公司出品的一款針對嵌入式系統(tǒng)的優(yōu)秀圖形軟件。它是為任何使用lcd圖形顯示的應(yīng)用提供高效的獨(dú)立于處理器及l(fā)cd控制器而設(shè)計(jì)的圖形用戶接口,它適用單任務(wù)或是多任務(wù)系統(tǒng)環(huán)境。架構(gòu)基于模塊化設(shè)計(jì),由不同的模塊中的不同層組成。包括液晶驅(qū)動(dòng)模塊,內(nèi)存設(shè)備模塊,窗口系統(tǒng)模塊,窗口控件模塊,反鋸齒模塊和觸摸屏及外圍模塊。其主要特性包括豐富圖形庫,多窗口、多任務(wù)機(jī)制,窗口管理及豐富窗口控件類(按鈕、檢驗(yàn)框、單/多行編輯框、列表框、進(jìn)度條、菜單等),多字符集和多字體支持,多種常見圖像文件支持,鼠標(biāo)、觸摸屏支持,靈活自由配制等特性。
   如下圖,uCGUI中,有基于emWin與uCGUI的DEMO,其實(shí)兩個(gè)很類似;INC目錄下包含了所有圖形庫提供的功能函數(shù)接口,直接調(diào)用就好了,工程中圖形庫是以lib方式給出的。
 
 
參考uCGUI中文手冊
1:首先通過網(wǎng)絡(luò)上相關(guān)資料的介紹,大致清楚UCGUI的整個(gè)框架與需要移植的地方。
2:結(jié)合uCGUI中文手冊與自己的開發(fā)板具體進(jìn)行移植。
///////////////////////////////////////
1:指針光標(biāo)輸入設(shè)備(觸摸屏)

指針光標(biāo)輸入設(shè)備包括鼠標(biāo)和觸摸屏。 它們共用一組通用的指針光標(biāo)輸入設(shè)備(PID)函數(shù)使得鼠標(biāo)和觸摸屏能同時(shí)起作用。 該函數(shù)一般由視窗管理器自動(dòng)地調(diào)用,如前所述的那樣,起刷新顯示屏的作用。 如果視窗管理器未使用,你的應(yīng)用程序要負(fù)責(zé)調(diào)用PID 函數(shù)。

 
 
 
 
 
//////////////////////////////下面的內(nèi)容是整理自網(wǎng)絡(luò)//////////////////////////////////////////

0:準(zhǔn)備工作

  

在移植之前,首先要了解在網(wǎng)上下的UCGUI 3.90源碼包,且需要先寫好裸機(jī)下成功驅(qū)動(dòng)LCD的驅(qū)動(dòng)代碼。

1)“tool文件夾”              基本都是字體和模板查看之類的.

2)“sample文件夾”       是實(shí)例代碼和模版配置頭文件,如跟操作系統(tǒng)有關(guān)的GUI_X或者一些模板

3)“Start文件夾”           是uCGUI的源代碼包 


Config,配置文件;
GUI/AntiAlias,抗鋸齒支持;
GUI/ConvertMono,用于B/W(黑白兩色)及灰度顯示的色彩轉(zhuǎn)換程序;
GUI/ConvertColor,用于彩色顯示的色彩轉(zhuǎn)換的程序;
GUI/Core ??C/GUI,內(nèi)核文件;
GUI/Font,字體文件;
GUI/LCDDriver,LCD 驅(qū)動(dòng);
GUI/Mendev,存儲(chǔ)器件支持;
GUI/Touch,觸摸屏支持;
GUI/Widget,視窗控件庫;
GUI/WM,視窗管理器;


1: 定義/修改GUIConf.h、LCDConf.h 、GUITouchConf.h

     

    GUIConf.h : μc/GUI功能模塊、動(dòng)態(tài)存儲(chǔ)空間(用于內(nèi)存設(shè)備和窗口對象)大小、默認(rèn)字體設(shè)置等 基本GUI預(yù)定                           義控制的定義

                   在圖形接口的配置文件GUIconf.h 的默認(rèn)設(shè)置中,窗口

               管理、存儲(chǔ)器支持、觸摸屏等功能被屏蔽。默認(rèn)字體設(shè)置為

               GUI_Font6x8。uC/GUI 同樣支持漢字的顯示,使用生成漢字

               字庫的軟件,可以將Windows 操作系統(tǒng)內(nèi)的任何字體字庫轉(zhuǎn)

               換漢字字庫文件,也可以根據(jù)實(shí)際顯示的需要,將所需顯示

               的漢字建立一個(gè)自定義字庫,添加到uC/GUI 中。文中選用

               的漢字字庫文件為hzk16s.c(16×16 點(diǎn)陣的宋體漢字字庫),

               uC/GUI 便支持16×16 點(diǎn)陣宋體漢字的顯示。

       

 

        #define GUI_OS                  (1)             //多任務(wù) 

              #define GUI_SUPPORT_TOUCH       (0)             //觸摸 

             #define GUI_SUPPORT_UNICODE    (1)             //Unicode支持 

              #define GUI_DEFAULT_FONT         &GUI_Font6x8   //GUI默認(rèn)字體 

              #define GUI_ALLOC_SIZE           5000           //動(dòng)態(tài)內(nèi)存的大小 

              #define GUI_WINSUPPORT           1              //窗口控件支持 

              #define GUI_SUPPORT_MEMDEV       1              //支持內(nèi)存設(shè)備 

              #define GUI_SUPPORT_AA           1               


    LCDConf.h:LCD大小、控制器類別、總線寬度、顏色選取等LCD參數(shù)控制文件


 

        #define LCD_XSIZE           (160)    //配置TFT的水平分辨率 

        #define LCD_YSIZE           (128)    //配置TFT的垂直分辨率 

        #define LCD_CONTROLLER      (54124) //TFT控制器的名稱 

        #define LCD_BITSPERPIXEL    (16)     //每個(gè)像素的位數(shù) 

        #define LCD_FIXEDPALETTE    (565)    //調(diào)色板格式 

        #define LCD_SWAP_RB         (0)      //紅藍(lán)反色交換 

        #define LCD_INIT_CONTROLLER()    TFT_Init() ;  //此處需要定義的是你的TFT初始化函數(shù) 

    GUITouchConf.h:配備觸摸屏,根據(jù)觸摸屏及其控制芯片編制以下幾個(gè)函數(shù)

        void TOUCH_X_ActivateX (void);// 準(zhǔn)備Y軸數(shù)據(jù)測量
     void TOUCH_X_ActivateY (void);// 準(zhǔn)備X軸數(shù)據(jù)測量
     int TOUCH_X_MeasureX(void);    // 根據(jù)AD轉(zhuǎn)換結(jié)果返回X的值
     int TOUCH_X_MeasureY(void);    // 根據(jù)AD轉(zhuǎn)換結(jié)果返回Y的值

         以上幾個(gè)函數(shù)在GUI_TOUCH_Exec()會(huì)被調(diào)用。     

               

   GUI/CORE/LCD_ConfDefaults.h文件內(nèi)可以找到所有囊括LCD配制默認(rèn)選項(xiàng),包括LCD屏個(gè)數(shù),控制器個(gè)數(shù) ,調(diào)色板,屏幕反向設(shè)置等眾多配制選項(xiàng)。

 

 

2:LCD配置內(nèi)容與驅(qū)動(dòng)接口

    對于自帶控制器的LCD液晶屏,通過LCDConf.h文件中的總線接口和寄存器接口對硬件接口進(jìn)行配置與定義;

    對于片上已經(jīng)集成了LCD控制器的控制器,通過對片內(nèi)LCD控制器的寄存器設(shè)置來配置LCD各接口信號;

    一般LCD的接口信息配置包括VFRAME幀同步信號,VLINE線同步脈沖信號,VCLK象素時(shí)鐘信號,VM信號和數(shù)據(jù)位不等的象素點(diǎn)數(shù)據(jù)輸出信號。

 

3:LCD驅(qū)動(dòng)底層實(shí)現(xiàn)

    LCD驅(qū)動(dòng)編程的實(shí)質(zhì)是液晶屏上的點(diǎn)對應(yīng)的顯存編程,最底層調(diào)用函數(shù)為畫點(diǎn)函數(shù),用戶可根據(jù)LCD屏的驅(qū)動(dòng)控制器的實(shí)際情況(通過總線接口、寄存器接口或LCD控制器的寄存器來操作)來實(shí)現(xiàn)底層驅(qū)動(dòng)。  

    _SetPixel(),_GetPixel(),XorPixel()為最底層直接對顯存操作函數(shù)。

    uc/GUI提供部分控制器驅(qū)動(dòng),文件為GUI/LCDDriver/LCDSLin.c,如sed1335,T6963等簡單LCD控制器。核心函數(shù)為LCD_Write().     _SetPixel()調(diào)用LCD_Write()寫顯存。 

         uC/GUI 的圖形庫應(yīng)用程序、漢字顯示、窗口等功能的實(shí)       

      現(xiàn),都建立在底層的LCD 驅(qū)動(dòng)和畫點(diǎn)功能的基礎(chǔ)上,uC/GUI

      的移植,必須先完成 LCD 的驅(qū)動(dòng),以及畫點(diǎn)、線等基本功

      能?刂破鱐FT3224 在驅(qū)動(dòng)液晶顯示時(shí),只需設(shè)置好顯示的

      行列坐標(biāo),向顯示寄存器寫入顯示數(shù)據(jù),便實(shí)現(xiàn)顯示功能,

      而無需計(jì)算顯示存儲(chǔ)器和顯示區(qū)域的地址

 

      畫點(diǎn)程序如下:

      static void _SetPixel(int x, int y, LCD_PIXELINDEX c) 

      {

          Y_ADDR = y;

          X_ADDR = x;

          CMD = ((x/256)<<2) | (y/256); //控制寄存器CMD 存放行列坐標(biāo)的高位數(shù)據(jù)

          DAT = c;     //數(shù)據(jù)寄存器DAT

      } 

 

      讓GUI能夠找到你的LCD驅(qū)動(dòng),修改LCDDriver。 

      在編寫你的TFT底層驅(qū)動(dòng)程序的時(shí)候,一定不能忘記編寫這兩個(gè)函數(shù):設(shè)置一個(gè)像素和獲取一個(gè)像素的顏       色,因?yàn)楹竺婧芏郩CGUI和你的TFT驅(qū)動(dòng)關(guān)聯(lián)起來需要這兩個(gè)函數(shù)為前提。以我的TFT為例: 

      void LCD_SetPixel(unsigned short x, unsigned short y, unsigned short color) 

     

      } 

     unsigned short LCD_GetPixel(unsigned short x, unsigned short y) 

    { 

     }


     uC/GUI 的驗(yàn)證程序如下:

      …

     GUI_SetColor(GUI_WHITE); //設(shè)置前景色為白色

     LCD_L0_DrawHLine(0,100,100); //繪制水平直線

     GUI_InitLUT(); //初始化調(diào)色板

     GUI_DrawBitmap(&bm2,0,0); //繪制位圖,位圖文件為2.c

     GUI_SetFont(&GUI_FontHZ_Song_16);//設(shè)置當(dāng)前字體16×16 宋體

     GUI_DispStringAt("uC/GUI 移植實(shí)現(xiàn)",10,40); //顯示漢字

     

  這兩個(gè)函數(shù)寫好,并測試可以正常顯示后,接下來需要修改TFT與UCGUI關(guān)聯(lián)的函數(shù)(在一個(gè)C文件下(我的是ili9320_ucgui.c),建議大家在移植GCGUI之前最好下載個(gè)別人移植好的例程,對著修改這樣難度降低很多): 

int LCD_L0_Init(void) 

{   

   TFT_Init(); 

   return 0; 

這個(gè)函數(shù),是GCGUI初始化TFT需要調(diào)用的,里面的函數(shù)就是你TFT底層驅(qū)動(dòng)的初始化函數(shù)。 

void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) 

   LCD_SetPixel(x,y,PixelIndex); 

unsigned int LCD_L0_GetPixelIndex(int x, int y) 

   return LCD_GetPixel(x,y); 

上面兩個(gè)函數(shù)是其他函數(shù)的最基本元素,其他函數(shù)比如畫線、點(diǎn)、圓都需要調(diào)用改函數(shù)。里面的LCD_SetPixel(x,y,PixelIndex)、LCD_GetPixel(x,y);就是你TFT底層驅(qū)動(dòng)設(shè)置像素和獲取像素的兩個(gè)函數(shù)。 

緊接著把該ili9320_ucgui.c文件下其他函數(shù)修改一下(凡是遇到設(shè)置像素和獲取像素的地方用以上兩個(gè)函數(shù)代替。) 

接著,修改另一個(gè)C文件(ili9320_api.c)這里修改很簡單,僅僅也是將設(shè)置像素和獲取像素的函數(shù)替換掉自己定義的即可。 

4:GUI_X文件夾內(nèi)包括有與硬件聯(lián)系緊密的文件


   GUI_X文件夾下:

  GUI_X.C——無操作系統(tǒng)情況

  GUI_X_embOS.c——嵌入式操作系統(tǒng)

  GUI_X_ucos.c——UCOS環(huán)境下

   GUI_X.c包括大部分與硬件的關(guān)聯(lián)函數(shù),如定時(shí)器的初始化和觸摸屏相關(guān)函數(shù)。

   uc/GUI與操作系統(tǒng)掛接的核心是定時(shí)器的設(shè)置和掛接。

   uc/GUI是通過延時(shí)函數(shù)GUI_Delay()調(diào)用GUI_X_Delay,再調(diào)用GUI_Exec()處理窗口部件中的回調(diào)函數(shù)進(jìn)行重繪。在任何一款嵌入式操作系統(tǒng)中都需要定時(shí)器的心臟跳動(dòng)作用,支持OS的uc/GUI可以通過定時(shí)器的設(shè)置達(dá)到嵌入式操作系統(tǒng)和圖形系統(tǒng)的實(shí)時(shí)和同步操作。在GUI_X_uCos.c中通過uc/os中的延時(shí)程序同μc/GUI掛接實(shí)現(xiàn)整合。


4:移植完畢

經(jīng)過移植之后,GUI應(yīng)用程序開發(fā)通過uc/GUI而變得非常容易,在調(diào)用GUI_Init()后,用戶可以根據(jù)需要正確配制uc/GUI后,可使用其強(qiáng)大的庫函數(shù)和豐富的GUI資源進(jìn)行編程。在GUI編程過程中,可以打開抗鋸齒功能減小圖形失真,得到高質(zhì)量的圖形和字體效果。采用內(nèi)存設(shè)備能有效克服閃爍現(xiàn)象,獲得更快的顯示速度,但它和抗鋸齒功能一樣需要額外的內(nèi)存開銷。

關(guān)閉窗口