STemWin 和 FreeRTOS 移植和优化

17 篇文章 1 订阅

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

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

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

1.FreeRTOS移植内容

OS根目录必备资源如图                                       

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

2.STemWin移植

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

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

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

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

DSP和标准外设库: 资源编号 : STSW-STM32065 资源名称 : STM32F4 DSP and standard peripherals library 文件名 : stm32_f105-07_f2_f4_usb-host-device_lib.zip 下载地址 : http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257901# USB库: 资源编号 : STSW-STM32046 资源名称 : STM32F105/7, STM32F2 and STM32F4 USB on-the-go Host and device library (UM1021) 文件名 : stm32_f105-07_f2_f4_usb-host-device_lib.zip 下载地址 : http://www.st.com/web/en/catalog/tools/PF257882 ETH以太网库: 资源编号 : STSW-STM32046 资源名称 : LwIP TCP/IP stack demonstration for STM32F4x7 microcontrollers (AN3966) 文件名 : stsw-stm32070.zip 下载地址 : http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257906 【CMSIS】 Cortex微控制器软件接口程序(Cortex Microcontroller Software Interface Standard (CMSIS). ) 版本: V4.2 发布日期: 31. July 2014 【STM32F4xx_StdPeriph_Driver】 STM32F40x系列CPU标准外设驱动程序 版本: V1.5.0 发布日期: 06-March-2015 【STM32_USB_OTG_Driver】 STM32F105/7xx, STM32F2xx and STM32F4xx USB Device Library 版本: V2.1.0 发布日期: 2012-03-19 【STM32_USB_Device_Library】 STM32F105/7xx, STM32F2xx and STM32F4xx USB Device Library 版本: V1.1.0 发布日期: 2012-03-05 【STM32_USB_HOST_Library】 STM32F105/7xx, STM32F2xx and STM32F4xx USB Host Library 版本: V2.1.0 发布日期: 2012-03-19 【STM32F4x7_ETH_Driver】 STM32F4x7 Eth Library 版本: V1.1.0 发布日期: 31-July-2013 ********************************************************************************************************* * * 版 本 : V1.0 * 说 明 : 本实验主要实现FreeRTOS+STemWin+FatFS+USB Host综合 * 实验目的: * 1. 学习FreeRTOS+STemWin+FatFS+USB Host综合 * 2. 这里的USB Host主要实现U盘相关处理,支持U盘热插拔。 * 用户可以根据需要在usb_usr.c文件中的插入检测函数: * USBH_USR_Configuration_DescAvailable或者函数USBH_USR_Init函数加入插入标志 * 拔出检测函数: * USBH_USR_DeviceDisconnected * 实验内容: * 1. 按下按键K1可以通过串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1) * ================================================= * 任务名 任务状态 优先级 剩余栈 任务序号 * vTaskUserIF R 2 272 2 * vTaskGUI R 1 657 1 * IDLE R 0 113 6 * vTaskMsgPro B 4 1957 4 * vTaskLED B 3 483 3 * vTaskStart B 5 489 5 * * * 任务名 运行计数 使用率 * vTaskUserIF 5583 1% * vTaskGUI 10782 2% * IDLE 355589 91% * vTaskLED 0 <1% * vTaskMsgPro 16770 4% * vTaskStart 17 <1% * 串口软件建议使用SecureCRT(V6光盘里面有此软件)查看打印信息。 * 各个任务实现的功能如下: * vTaskGUI 任务: emWin任务 * vTaskTaskUserIF 任务: 接口消息处理 * vTaskLED 任务: LED闪烁 * vTaskMsgPro 任务: U盘中文件处理和浏览 * vTaskStart 任务: 启动任务,也就是最高优先级任务,这里实现按键扫描和触摸检测 * 2. 任务运行状态的定义如下,跟上面串口打印字母B, R, D, S对应: * #define tskBLOCKED_CHAR ( 'B' ) 阻塞 * #define tskREADY_CHAR ( 'R' ) 就绪 * #define tskDELETED_CHAR ( 'D' ) 删除 * #define tskSUSPENDED_CHAR ( 'S' ) 挂起 * 3. 本实验的USB Host主要是对U盘的操作,通过电脑端的串口软件SecureCRT软件, * 给板子发送相关命令实现操作,具体实现在demo_fatfs文件里面。 * printf("请选择操作命令:\r\n"); * printf("1 - 显示根目录下的文件列表\r\n"); * printf("2 - 创建一个新文件armfly.txt\r\n"); * printf("3 - 读armfly.txt文件的内容\r\n"); * printf("4 - 创建目录\r\n"); * printf("5 - 删除文件和目录\r\n"); * printf("6 - 读写文件速度测试\r\n"); * printf("7 - 挂载U盘\r\n"); * printf("8 - 卸载U盘\r\n"); * 注意事项: * 1. 本实验推荐使用串口软件SecureCRT,要不串口打印效果不整齐。此软件在 * V5开发板光盘里面有。 * 2. 务必将编辑器的缩进参数和TAB设置为4来阅读本文件,要不代码显示不整齐。 * * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2016-03-15 Eric2013 1. ST固件库到V1.5.0版本 * 2. BSP驱动包V1.2 * 3. FreeRTOS版本V8.2.3 * 4. STemWin版本V5.28 * 5. FatFS版本V0.11a * * Copyright (C), 2016-2020, 安富莱电子 www.armfly.com * *********************************************************************************************************
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值