STemWin 和 FreeRTOS 移植和优化

笔者之前做了一个带LCD屏的项目,根据评估,果断选择 STemWin + FreeRTOS的方案。下面讲讲移植优化emWin的过程 -------------------- 不喜勿喷呀!

基本硬件平台:STM32F205VGTx(Cortex M3)    3.5寸LCD屏(ILI9488)------------- 没有SDRAM,所以资源不怎样

移植相关平台:FreeRTOS V9.0.0    STemWin528

1.FreeRTOS移植内容

OS根目录必备资源如图                                       

STemWin 和 FreeRTOS 移植和优化_第1张图片

根据MCU型号,工程配置文件如下(具体可以找找相关资料,这里不细讲了):

STemWin 和 FreeRTOS 移植和优化_第2张图片

2.STemWin移植

根目录下基本文件夹如下(资源具体作用,根据名称,也能猜到部分,config是配置相关的参考例子,笔者直接使用的是修改后的GUIConfig)

STemWin 和 FreeRTOS 移植和优化_第3张图片

因为采用的是带OS的emWin 所以注意别移植错了(如:GUI_X_FreeRTOS  CM3_OS_Keil.lib);xBSP_LCD_Config 实际是 LCDConf 的变体,笔者加了相关LCD配置,加上个人命名习惯,所以采用这个名称。

STemWin 和 FreeRTOS 移植和优化_第4张图片

GUI_X_FreeRTOS 具体内容,看了这些大家也知道为什么必须移植修改这部分了吧:

STemWin 和 FreeRTOS 移植和优化_第5张图片

3.emWin的优化:

$1.LCD驱动的优化:

根据LCD IC型号,项目中用到的刷屏方向,刷新速率来修改,下面展示修改比较重要的部分(分段的哦):

    LcdWriteReg(0xB1);    //Frame rate 
    LcdWriteData(0xC0);    
    LcdWriteData(0x11);     

    LcdWriteReg(0xB6);       //Display Function Control
    LcdWriteData(0x02);       
    LcdWriteData((0<<6)|(1<<5)|(0<<4));       //D6:GS  D5:SS  D4:SM       //0x22


    LcdWriteReg(0x36);
    LcdWriteData((1<<7)|(0<<6)|(0<<5)|(1<<4)|(0<<2)); //D7:MY D6:MX D5:MV D4:V Refersh  D2:H Refersh

    SRAM_Timing.AddressSetupTime = 1;
    SRAM_Timing.AddressHoldTime = 0;
    SRAM_Timing.DataSetupTime = 1;           /* 根据SRAM的最大速度进行调整  */
    SRAM_Timing.BusTurnAroundDuration = 0;
    SRAM_Timing.CLKDivision = 0;
    SRAM_Timing.DataLatency = 0;    

另外根据将基本的绘制通过写命令的方式直接得到,这样用到emWin上会大大提高绘制时间,减少MCU负荷(下面的函数将用到emWin 中):

void xLCD_SetPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor)
{
    xLCD_SetCursor(_usX,_usY);        //设置光标位置 
    
    LcdWriteReg(0x2c);
    LcdWriteData(_usColor);

uint16_t xLCD_GetPixel(uint16_t _usX, uint16_t _usY)
{
    uint16_t R = 0, G = 0, B = 0 ;
    xLCD_SetCursor(_usX,_usY);        //设置光标位置     
    
    LcdWriteReg(0x2e);
    R = LcdReadData();  /* 第1个哑读,丢弃 */
    R = LcdReadData();
    G = LcdReadData();
    B = LcdReadData();

    return (((R >> 11) << 11) | ((G >> 10 ) << 5) | (B >> 11));    
}

void xLCD_DrawVLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usY2 , uint16_t _usColor)

void xLCD_DrawHLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usColor)

void xLCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor)

void xLCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)

void xLCD_DrawFillRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)

$2.emWin 初始化 和 驱动的优化:

前面已经说了我们最好根据项目需要,选择最优的刷屏方向(横屏还是竖屏),另外选对RGB 还是 GBR(IC手册有命令),能用命令解决,就用命令解决,不要让emWin来帮我们配置好,这样效率很低下。

void LCD_X_Config(void)
{
  GUI_DEVICE *pDevice;
  CONFIG_FLEXCOLOR Config = {0};
  GUI_PORT_API PortAPI = {0};
  //
  // Set display driver and color conversion
  //
  pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);   //RGB 基础色配置选择 GUICC_565 //  
  //
  // Display driver configuration, required for Lin-driver
  //
    
  LCD_SetSizeEx(0, XSIZE_PHYS , YSIZE_PHYS);
  LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);    
    
//  LCD_SetSizeEx(0, 480 , 320);
//  LCD_SetVSizeEx(0, 480, 320);        
  //
  // Orientation
  //
    Config.FirstCOM = 0;                                         
    Config.FirstSEG = 0; 
    Config.NumDummyReads = 2;
    {
//        Config.Orientation = GUI_SWAP_XY| GUI_MIRROR_Y;// 
    }

  GUIDRV_FlexColor_Config(pDevice, &Config);
  //
  // Set controller and operation mode
  //        
    PortAPI.pfWrite16_A0  = LcdWriteReg;
    PortAPI.pfWrite16_A1  = LcdWriteData;
    PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;
    PortAPI.pfReadM16_A1  = LcdReadDataMultiple;
    PortAPI.pfRead16_A1   = LcdReadData;    
                
  // Find the current LCD and initialize GUIDRV
    GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66709, GUIDRV_FLEXCOLOR_M16C0B16);   //  GUIDRV_FLEXCOLOR_M16C0B8
}

接下来,很重要的优化部分,在GUIDRV.c中,因为只要我们使用emWin,那么最基本绘制都调用这里的函数,所以我们必须优化这里。最基本的绘制是什么呢?无非就是点,线,面。这里我们直接使用自己配置好基础绘制,删除emWin自带的。

static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) 
{
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    GUI_USE_PARA(PixelIndex);
    {
       //优化位置
            xLCD_SetPixel(x,y,PixelIndex);
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
}

static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
  unsigned int PixelIndex;
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    {
      //
      // Write into hardware ... Adapt to your system
      //
      // TBD by customer...
      //
      PixelIndex = xLCD_GetPixel(xPhys, yPhys);        
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
  return PixelIndex;
}

内容较多,直接省略掉。。。。。。

 

最终结果,你会发现,LCD刷屏快,绘制速度快,这样我们大大释放了MCU,那岂不美滋滋!!!

具体代码可以根据链接下载 https://download.csdn.net/download/weixin_38426553/11032284

 

 

你可能感兴趣的:(ARM)