emWin图形库移植—-stm32F103

本次emWin移植根据开发板自带的教程《普中STM32F1xx-STemWin开发指南》进行 ,stemWin的源码也使用教程资源自带的5.26版本的源码。

源码目录结构如下

253xEV.png

首先可以看下emWin的框架图

2fa34K.png

从中可以看出,连接emWin与硬件的是驱动层,所以我们移植中需要修改和重点关注的是与显示外设的驱动有关的部分

  • 移植思路如下
  1. 修改emWIn需要分配内存部分的代码来兼容不同芯片与外设配置(外部RAM)下的内存分配接口,主要在GUIConf.c 中修改。
  2. 使用LCD的接口函数来替代emWin的底层画图函数(读点、画点、画线、填充),主要在GUIDRV_Template.c 中修改
  3. 修改emWin驱动底层硬件的接口代码,来适配显示外设

根据移植思路,首先创建好移植的工程模板,并在工程模板文件夹下创建EMWIN文件夹,并将emWin源码放入文件夹中

25GQiT.png

接下来在工程中建立好管理组,并添加包含路径

25wcIs.png

其中需要注意的是在OS文件夹中,由于本次只是移植到裸机中,所以使用GUI_X.c,如果要移植到实时操作系统中则需要添加相应操作系统版本的OS文件,同理在LIB中我们也要选择相应的链接库

  • 准备好源码后就可以开始修改移植emWIn了,首先修改GUIConf.c文件,修改emWIn中的内存分配代码来适配硬件

      在·GUIConf.c·中我们需要修改GUI_X_Config()函数,来完成内存初始化的分配任务,使用我们自己的管理内存接口来为其分配内存

    源代码如下:

    void GUI_X_Config(void) 
    {
    //
    // 32 bit aligned memory area
    //
    static U32 aMemory[GUI_NUMBYTES / 4];
    //
    // Assign memory to emWin
    //
    GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
    //
    // Set default font
    //
    GUI_SetDefaultFont(GUI_FONT_6X8);
    }

    其中我们需要修改的是使aMemory指针所分配到的内存由我们自己分配来适配我们的硬件,使其能正确分配到合适且足够的内存空间。

    修改代码如下:

    #include "malloc.h" 
    //设置 EMWIN 内存大小 
    #define GUI_NUMBYTES (500*1024) 
    #define GUI_BLOCKSIZE 0X80 //块大小
    
    void GUI_X_Config(void) 
    {
    //
    // 32 bit aligned memory area
    //
    //static U32 aMemory[GUI_NUMBYTES / 4];
    
    U32 *aMemory = mymalloc(SRAMEX,GUI_NUMBYTES); //从外部 SRAM 中分配 GUI_NUMBYTES 字节的内存
    
    //
    // Assign memory to emWin
    //
    GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
    
    GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE); //设置存储快的平均尺寸,该区越大,可用的存 储快数量越少
    
    //
    // Set default font
    //
    GUI_SetDefaultFont(GUI_FONT_6X8);
    }
  • 接下来就是修改emWIn的底层画图函数,使其使用LCD屏的底层接口函数来完成底层的画图函数接口

    打点函数

    static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int >PixelIndex) 
    {
       LCD_DrawFRONT_COLOR(x,y,PixelIndex); //调用 tftlcd.c 文件中的打点函数 
    }

读点函数

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);
    {
      PixelIndex = LCD_ReadPoint(x,y);//这个是彩屏底层的读点函数
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
  return PixelIndex;
}

填充函数

static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) 
{ 
    LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);//这个是彩屏底层的填充函数 
}

画图函数

static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const GUI_UNI_PTR * p, int xsize) 
{
    LCD_PIXELINDEX pixel; 
    for (;xsize > 0; xsize--, x++, p++) 
    { 
        if(xsize>tftlcd_data.width)
            y++; 
        LCD_Set_Window(x,y,tftlcd_data.width-xsize,y); 
        pixel = *p; 
        LCD_WriteData_Color(pixel); 
    } 
}
  • 然后修改`LCDConf_FlexColor_Template.c中的驱动函数,使其适配我们的LCD屏

    其中LcdWriteReg()、LcdWriteData()、LcdWriteDataMultiple()、 LcdReadDataMultiple()、LCD_X_Config()和 LCD_X_DisplayDriver()这 6 个函数中的前4个函数是直接使用STemWin的LCD驱动程序,与我们的LCD不适配,所以我们不需要,将其删除并修改LCD_X_Config()来适配LCD

    修改代码如下:

    void LCD_X_Config(void) 
    { 
    GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0); //创建显示驱动器件 
    LCD_SetSizeEx (0, tftlcd_data.width, tftlcd_data.height); 
    LCD_SetVSizeEx (0, tftlcd_data.width, tftlcd_data.height);
    }

    完成上述操作后,就完成了最基本移植功能,触摸功能移植等下次有时间再来添加

    接下来编写一段测试代码,检测是否移植成功

    #include "stm32f10x.h"
    #include "system.h"
    #include "SysTick.h"
    #include "tftlcd.h"
    #include "24cxx.h"
    #include "malloc.h" 
    #include "time.h"
    #include "flash.h"
    #include "sram.h"
    #include "GUI.h"
    
    int main()
    {
    SysTick_Init(72);
    
    TFTLCD_Init();          //LCD初始化
    
    FSMC_SRAM_Init(); 
    
    my_mem_init(SRAMIN);        //初始化内部内存池
    my_mem_init(SRAMEX);        //初始化外部SRAM内存池
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);//使能CRC时钟,否则STemWin不能使用
    
    GUI_Init();
    
    GUI_SetBkColor(GUI_BLUE); //设置背景颜色 
    GUI_SetColor(GUI_RED); //设置颜色 
    GUI_Clear(); //清屏 
    GUI_SetFont(&GUI_Font24_ASCII); //设置字体 
    GUI_DispStringAt("Hello Word!",0,0); //在指定位置显示字符串
    
    while(1)
    {
    
    }
    }
    

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注