zoukankan      html  css  js  c++  java
  • STemWin移植

    目前micrium官网ucgui版本是v5.26Trial版本,无源代码,只有lib文件,现在网上流传最多的源码是ucgui3.90或3.98版本的,这些源码没有完整官方版本。emWin是segger公司的,segger与ST等公司都有合作,使用ST的芯片可以免费使用emWin,STemWin:http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF259225?s_searchtype=partnumber,目前版本是5.22。
    移植环境:

    • 芯片STM32F103ZET6
    • TFTLCD驱动芯片ILI9341,带有电阻触屏
    • 编译环境Keil uVision5
    • 不带OS

    在移植之前,我们应该要有LCD的基本驱动函数,包括初始化、点亮一个像素等(这些驱动文件不能和emWin中的文件重名,即不能命名为LCD.h、LCD.c)。在文件夹STemWin_Library_V1.1.2中,有以下几个文件:
    STemWin_Library_V1.1.2目录
    其中Libraries中就有emWin:
    emWin目录
    Config是emWin配置文件
    Documentation是Segger公司的用户手册
    inc是头文件
    Lib是将源码封装成的lib
    OS是带OS和不带OS的GUI文件
    Software里有一些跟图片、字体相关的实用小工具
    我们可以将整个STemWin_Library_V1.1.2放入我们的Keil工程中,然后加入以下4个文件:

    • GUI_X.C:STemWinLibrary522OS
    • GUIConf.cLCDConf_FlexColor_Template.c:STemWinLibrary522Config
    • STemWin522_CM3_Keil.lib :STemWinLibrary522Lib

    接着我们开始修改文件

    • GUIConf.c:
    #define GUI_NUMBYTES  1024*50

    这个宏定义的含义在于向系统申请一个静态空间 aMemory ,接着调用 emWin的库函数GUI_ALLOC_AssignMemory 把该空间分配给 emWin,“1024*50”是50KB的意思。

    • LCDConf_FlexColor_Template.c
    static void LcdWriteReg(U16 Data) {
      // ... TBD by user
        MYLCD->LCD_REG=Data;
    }
    
    static void LcdWriteData(U16 Data) {
      // ... TBD by user
        MYLCD->LCD_RAM=Data;
    }
    
    static void LcdWriteDataMultiple(U16 * pData, int NumItems) {
      while (NumItems--) {
        // ... TBD by user
            MYLCD->LCD_RAM = *pData++;
      }
    }
    
    static void LcdReadDataMultiple(U16 * pData, int NumItems) {
      while (NumItems--) {
        // ... TBD by user
             *pData++ = MYLCD->LCD_RAM;
      }
    }

    这里需要填写4个函数,分别是写单个寄存器、写单个数据、写多个数据、读多个数据。这里利用了FSMC驱动ILI9341。MYLCD是一个类型定义。

    typedef struct
    {
        u16 LCD_REG;
        u16 LCD_RAM;
    } LCD_TypeDef;
    //0x6C000000 | 0x000007FE 就是相应的FSMC的地址
    #define LCD_BASE        ((u32)(0x6C000000 | 0x000007FE))
    #define MYLCD           ((LCD_TypeDef *) LCD_BASE)

    接下去来到函数LCD_X_Config()

    void LCD_X_Config(void) {
      ……
      // Orientation
      // 这里可以利用GUI_SWAP_XY,GUI_MIRROR_Y,GUI_MIRROR_X来改变方向
      Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;
    
      // Set controller and operation mode
      //不同的LCD驱动IC,F66709这个编号也会不一样具体查看手册1002页
      //M16C0B16代表16bpp, no cache, 16 bit bus
      ……
      GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI,      GUIDRV_FLEXCOLOR_F66709, GUIDRV_FLEXCOLOR_M16C0B16);
    }

    接下去来到

    int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
      ……
      switch (Cmd) {
      case LCD_X_INITCONTROLLER: {
            MYLCD_Init();//在这里加入自己的LCD初始化程序
        return 0;
      }
      default:
        r = -1;
      }
      return r;
    }

    emWin在运行过程中会调用延时之类的函数,为了实现精确定时,我们还需要为emWin开一路定时器,这里我们选用SysTick。在mian()函数中加入SysTick_Config(),来初始化SysTick定时器,而在SysTick_Handler中断函数中,我们需要进行这样的修改:

    extern __IO int32_t OS_TimeMS;  //OS_Time 已在GUI_X.C中声明。
    void SysTick_Handler(void)
    {
        OS_TimeMS++;
    }

    OS_TimeMS已经在GUI_X.c中定义。
    这些工作完成后我们再回到main()中,在main()中我们需要添加
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);函数,注意如果不添加将无法使用emWin。然后进行GUI初始化,记得先包含“GUI.h”。如我的程序是这样子的:

    #include "stm32f10x.h"
    #include "GUI.h"
    #include "core_cm3.h"
    
    #define TICKS_PER_SEC 1000
    
    int OS_CPU_SysTickClkFreq(void)
    {
      return 72000000;  
    }
    
    int main(void)
    {
        SysTick_Config(OS_CPU_SysTickClkFreq()/TICKS_PER_SEC-1);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
    
        GUI_Init();
        GUI_DispString("Hello emWin!");
        while(1)
        {       
        }
    }

    接下来我们加入触摸的部分,这部分我们需要写4个函数:
    GUI_TOUCH_X_ActivateX(), GUI_TOUCH_X_ActivateY()
    GUI_TOUCH_X_MeasureX(), GUI_TOUCH_X_MeasureY()

    //这里返回的y值是AD采样的值
    int GUI_TOUCH_X_MeasureX(void) {
      u16  x,y;
        TP_Read_XY(&x,&y);
      return y;
    }
    //这个写个空函数就可以了
    void GUI_TOUCH_X_ActivateX(void){}

    然后我们需在LCDConf_FlexColor_Template.c文件中加入对触摸屏的校准

    //这4个宏定义是屏幕的四个角的AD值
    #define TOUCH_AD_TOP                221
    #define TOUCH_AD_BOTTOM             3900
    #define TOUCH_AD_LEFT               160
    #define TOUCH_AD_RIGHT              3883
    GUI_TOUCH_Calibrate(GUI_COORD_X, 0, 240, TOUCH_AD_TOP, TOUCH_AD_BOTTOM);
    GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, 320, TOUCH_AD_LEFT, TOUCH_AD_RIGHT);    

    【Reference】
    1.http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=462311

  • 相关阅读:
    Oracle内置函数之数值型函数
    【Java基础】java 获得本日,本周,本月的时间戳区间
    【mybatis】1、入门CURD基本操作(环境搭建)
    【hibernate】<第二节>hibernate的一对多映射(基本类型)
    Hibernate Java、Hibernate、SQL 之间数据类型转换
    【hibernate】<第一节>hibernate简单入门
    WebService wsdl没有types的问题
    Hibernate出现javax.naming.NoInitialContextException 错误的解决办法
    easyui 的 DataGrid View 使用
    Date与String之间相互转换
  • 原文地址:https://www.cnblogs.com/season-peng/p/6713514.html
Copyright © 2011-2022 走看看