1. 程式人生 > >STemwin5.xx底層驅動移植與優化 ------ 編寫自定義EmWin Driver參考

STemwin5.xx底層驅動移植與優化 ------ 編寫自定義EmWin Driver參考

首先得說一下為什麼要用STemwin;很多人搞嵌入式的同志應該都想有一個自己的開發環境,每個功能每個模組都自己寫;但是到最後發現無從下手,寫出來的程式碼效率也並不高,因為腦袋裡就沒有這些模組或者功能執行的模式。就像很多人說的“你再怎麼寫,也超不過現有的成熟技術,除非你學會了,在做一些昇華”。

STemWin在ST官網上是停止更新的了,最新的STemwin都不含在了stm32cube裡面了。不過區別也不大,移植就用5.22版本,硬體用的是F407(後續會更新F439的移植於優化,主要不同在於有了SDRAM STemwin的記憶體空間可以做到很大,而且LCD的資料傳輸F439有LCD介面和LCD的專屬DMA通道,效能肯定比F407快很多)。

第一步:軟體包下載:官方下載地址:http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stemwin.zip

第二部:STM32 DSP包下載名字叫做STSW-STM32065,有利於STemwin的內部計算速度。官方下載地址:

http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stm32f4_dsp_stdperiph_lib.zip

 

整個需要改動的的檔案分別是:

GUIConf.c  ----->分配GUI的記憶體池,根據自己平臺來分配

GUIDRV_Template.c----->點,線,面,圖,的基本LCD操作函式,這個是我們移植和優化的重點

LCDConf_FlexColor_Template.c--->涉及到LCD的尺寸與顯示裝置屬性的宣告,這個也是重點。

GUI_X.c-->無作業系統外部依賴配置(就是程式心跳,時鐘OS_TimeMS)

GUI_XOS.c-->有作業系統外部依賴設定。(時鐘,訊號量,郵箱)

新建LCD_Conf.h-->可以為空,但是必須要有這個檔案

 

GUI的配置也就是需要這幾個檔案,STemWin522_CM4_Keil.lib用於無作業系統,STemWin522_CM4_OS_Keil.lib用於作業系統

 

這次是以無作業系統版本修改;修改前必須完成LCD的驅動程式碼除錯,這樣才能進行GUI的移植。

修改的重點在於三個點:

第一:GUI_X.c,GUI時鐘訊號OS_TimeMS的驅動,通常用sysTick為之提供毫秒級的時鐘。

第二:LCDConf_FlexColor_Template.c,LCD的尺寸與顯示裝置屬性的宣告

第三:GUIDRV_Template.c,畫,點,面,圖,的基本LCD操作函式嵌入。

 

上邊三個問題解決基本上GUI就可以顯示出來了。

第一點:

首先我們開啟GUIConf.h

確保 GUI_OS                    (0) ;因為不用作業系統

其次我們得開啟系統sysTick的功能:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);

SysTick_Config(21000);

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//(168M/8)

產生毫秒中斷,在stm32f4xx_it.c中加入

#include "gui.h"

extern __IO int32_t OS_TimeMS;

void SysTick_Handler(void)

{

  OS_TimeMS ++;

}

這樣GUI的時鐘源就解決了

第二點:

這一步就是選擇用STemwin自帶的LCD的驅動還是用自己的API函式,這個選擇在void LCD_X_Config(void) 函式中體現;

用自己的LCD API函式就只保留void LCD_X_Config(void) 和LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData);

void LCD_X_Config(void) 預設用的是自帶驅動函式這個地修改:

void LCD_X_Config(void) {

  GUI_DEVICE * pDevice;

  //

  // Set display driver and color conversion

  //

  pDevice = GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_565, 0, 0);//宣告用什麼函式介面驅動LCD,還有一個就是LCD的畫素格式GUIDRV_Template_API在GUIDRV_Template.c中定義。

  //

  // Display driver configuration, required for Lin-driver

  //

  LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS); //設定LCD解析度

  LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS); //設定LCD顯示解析度,這個可以動態修改,用於螢幕的橫豎反轉。

}

 

LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData)這個函式可以把我們的LCD初始化,開關函式加進去,以自己的系統為準,有的系統在GUI啟動之前就得初始化。

{

     int r;

  (void) LayerIndex;

  (void) pData;

  switch (Cmd) {

  case LCD_X_INITCONTROLLER: {

   //初始化函式

    return 0;

  };

case LCD_X_OFF:{

     //關閉顯示

    return 0;

};

case LCD_X_ON:{

    //開啟顯示

    return 0;

};

  default:

    r = -1;

  }

  return r;

}

 

第三點:

這一步我們需要LCD的驅動程式碼;

分別修改GUIDRV_Template.c中的:

 

//畫點函式

static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) 

{

        //自己的畫點函式

}

 

//讀點函式

static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) 

{

unsigned int PixelIndex;

        PixelIndex = //自己的讀點函式

return PixelIndex;

}

 

//填充函式

static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) 

{

LCD_PIXELINDEX PixelIndex;

int x;

PixelIndex = LCD__GetColorIndex();

       //自己的填充函式 

}

 

//16bit資料劃線函式

static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const GUI_UNI_PTR * p, int xsize) 

{

    //自己劃線或者開窗函式,

    //如果LCD可以直接定點輸入,先定點在迴圈輸入顏色即可

    例如:LCD_SetCursor(x, y);(確保自己的LCD游標輸入不影響LCD的輸入視窗,如果影響就用開視窗函式)

    for (;xsize > 0; xsize--, x++, p++) 

{

LCDADDR->LCD_RAM = *p;

}

}

 

修改好後GUI就可以正常的運行了,程式碼優化主要是在GUIDRV_Template.c中,那些基礎函式需要自己根據自己LCD去優化,主要是消除程式碼冗餘,原生的驅動,都是靠打點函式實現的線,面,圖函式。

我的沒有優化輸入點速度只有70幾萬點美妙,優化後速度到140多萬基本提速一陪。

之後會更新有作業系統下的修改。

 

參考:http://hy907539007.lofter.com/post/1d028850_a311041