STM32的ucgui移植

  这里移植的是UCGUI3.90a版本,虽然已经有更新的版本,例如UCGUI3.98、甚至4.04版本,但目前只有这个版本的代码是最全的,包括JPEGMULTILAYERMEMDEVAntiAlias等模块。
  UCGUI的文件数量很大,主要用到UCGUI390a/Start/ConfigUCGUI390a/Start/GUI两个文件夹下文件,相关文件介绍如下。将ConfigGUI下的所有文件加入工程,这是UCGUI官方推荐的结构:

目录 内容 目录 内容
Config 配置文件 GUI/ConvertMono 用于B/W(黑白两色)以及灰度显示的色彩转换程序
GUI/AntiAlias 抗锯齿支持 GUI/ConvertColor 用于彩色显示的色彩转换程序
GUI/Core UCGUI内核文件 GUI/Font 字体文件
GUI/LCDDriver LCD驱动 GUI/Mendev 存储器件支持
GUI/Touch 触摸屏支持 GUI/Widget 视窗控件库
GUI/WM 视窗管理器

  JPEGMemDevMultiLayerWidgetWm5个文件夹的内容可以暂时不加入MDK工程,因为这些文件起到的是扩展功能。ConverMonoConverColorCoreFont这四个目录下的文件是不用修改的,要修改的文件在LCDDriverConfig这两个目录下的内容。LCDDriverLCD的驱动接口函数文件,需要将自己的LCD驱动函数提供给UCGUI调用。需要提供3LCD底层驱动函数:

  • void LCD_L0_SetPixelIndex ( int x, int y, int PixelIndex )LCD画点函数,用指定颜色填充一个像素。
  • unsigned int LCD_L0_GetPixelIndex ( int x, int y )LCD读取定点颜色函数,读取一个像素点的16RGB颜色值。
  • void LCD_L0_FillRect ( int x0, int y0, int x1, int y1 ):矩形填充函数,用指定颜色填充一个矩形。这个函数也可以不改,使用UCGUI的函数,用一个一个的像素点填充成一个矩形。也可以在底层驱动根据像素个数直接往GRAM中写数据,封装成函数,供这个函数调用,速度会快很多。

  LCDDriver下有三个文件,即LCDDummy.cLCDNull.cLCDWin.c,它们都是UCGUILCD接口模板文件。以LCDDummy.c为例:

#include "LCD_Private.h" /* private modul definitions & config */
#include "GUI_Private.h"
#include "GUIDebug.h"

/* #if (LCD_CONTROLLER == -1) \
    && (!defined(WIN32) | defined(LCD_SIMCONTROLLER)) */ /* 必须注释,否则不会编译 */
#include "ili93xx.h" /* 包含你的LCD驱动函数声明 */
#if (LCD_CONTROLLER == -1) /* 这句对应“Config/LCDConf.h” */

void LCD_L0_SetPixelIndex ( int x, int y, int PixelIndex ) {
    
    
    POINT_COLOR = PixelIndex; /* 我的画点函数使用了一个全局变量设定颜色 */
    LCD_DrawPoint ( x, y ); /* 画点函数 */
}

unsigned int LCD_L0_GetPixelIndex ( int x, int y ) {
    
    
    return LCD_ReadPoint ( x, y ); /* 我的读取像素颜色函数 */
}

void LCD_L0_FillRect ( int x0, int y0, int x1, int y1 ) {
    
    
    LCD_Fill ( x0, y0, x1, y1, LCD_COLORINDEX ); /* 填充矩形函数 */
    /*------------------------
    for ( ; y0 <= y1; y0++ ) {
        LCD_L0_DrawHLine ( x0, y0, x1 );
    }
    ------------------------*/
}

UCGUI提供了一些LCD控制器的驱动函数,但是这种配置方法可以适用于任何控制IC
  接下来修改Config文件夹下文件,即GUIConf.hLCDConf.hGUITouchConf.h。还需要加入一个GUI_X.c文件,否则编译时会有错误,直接复制UCGUI390a\Sample\GUI_X\GUI_X.c即可。如果打开了触摸功能,还需要加入UCGUI390a\Sample\GUI_X\GUI_X_Touch.c。这三个文件是UCGUI的上层配置文件,也就是GUI一些功能的开关。
  GUIConf.h如下:

#ifndef GUICONF_H
#define GUICONF_H

#define GUI_OS              (0) /* 操作系统的支持,当用到ucos时需要打开 */
#define GUI_SUPPORT_TOUCH   (0) /* 触摸屏的支持 */
#define GUI_SUPPORT_UNICODE (0) /* 用汉字库时再打开 */

#define GUI_DEFAULT_FONT &GUI_Font6x8 /* 定义字体大小 */
#define GUI_ALLOC_SIZE   12500 /* 分配的动态内存空间 */

/*********************************************************************
*
*        Configuration of available packages
*/
#define GUI_WINSUPPORT     0 /* 窗口功能支持  要使用指针图标时必须打开 */
#define GUI_SUPPORT_MEMDEV 0 /* 内存管理 */
#define GUI_SUPPORT_AA     0 /* 抗锯齿功能,打开后可以提高显示效果 */

#endif /* Avoid multiple inclusion */

  LCDConf.h如下:

#ifndef LCDCONF_H
#define LCDCONF_H

#define LCD_XSIZE (320) /* lcd的水平分辨率 */
#define LCD_YSIZE (480) /* lcd的垂直分辨率 */

#define LCD_BITSPERPIXEL (16) /* 16位颜色RGB值(颜色深度) */
#define LCD_SWAP_RB      (1)  /* 红蓝反色交换 */

/* lcd控制器的具体型号
 *
 * 设置为“-1”时,会编译LCDDriver下的LCDDummy.c
 * 设置为“-2”时,会编译LCDDriver下的LCDNull.c
 *
 * 还需要修改LCDDriver下文件的宏定义才可以被编译
 * eg. LCDDummy.c:
 *
 * #if (LCD_CONTROLLER == -1) && (!defined(WIN32) |defined(LCD_SIMCONTROLLER))
 * 改为#if (LCD_CONTROLLER == -1)
 */
#define LCD_CONTROLLER  -1 /* 设置为“-1”或“-2”,因为UCGUI没有相应LCD控制IC驱动 */
#define LCD_INIT_CONTROLLER() LCD_Config(); /* 绑定相关LCD底层驱动的初始化函数 */

配置完这两个文件,如果不启用触摸屏的话,UCGUI已经可以正常运行。
  先修改主函数,添加#include "GUI.h",在main里添加:

GUI_Init();
GUI_SetBkColor ( GUI_BLUE );
GUI_SetColor ( GUI_RED );
GUI_Clear();
GUI_DrawCircle ( 100, 100, 50 ); /* 画圆 */

while ( 1 );

要实现横屏效果,首先让显示屏基本驱动实现横屏,然后将LCDConf.h中的LCD_XSIZELCD_YSIZE进行互换。
  下面讲解UCGUI触摸屏的配置。在ucguiConfig目录中添加GUI_X_Touch.c,然后将GUIConf.h文件中的GUI_WINSUPPORTGUI_SUPPORT_TOUCH设置为1。配置GUIToucConf.h文件(下面的配置是针对320 * 2402.8TFT LCD,上面的是针对480 * 320TFT LCD):

#ifndef GUITOUCH_CONF_H
#define GUITOUCH_CONF_H

#define GUI_TOUCH_AD_LEFT   0
#define GUI_TOUCH_AD_RIGHT  240
#define GUI_TOUCH_AD_TOP    0
#define GUI_TOUCH_AD_BOTTOM 320

#define GUI_TOUCH_SWAP_XY  0
#define GUI_TOUCH_MIRROR_X 0
#define GUI_TOUCH_MIRROR_Y 0

#endif

UCGUI触摸屏驱动接口函数文件GUI_X_Touch.c

#include "GUI.h"
#include "GUI_X.h"
#include "touch.h"

void GUI_TOUCH_X_ActivateX ( void ) {
    
    
}

void GUI_TOUCH_X_ActivateY ( void ) {
    
    
}

int GUI_TOUCH_X_MeasureX ( void ) {
    
    
    Convert_Pos();
    return Pen_Point.X0;
}

int GUI_TOUCH_X_MeasureY ( void ) {
    
    
    Convert_Pos();
    return Pen_Point.Y0;
}

main函数进行如下修改:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "GUI.h"
#include "touch.h"

int main ( void ) {
    
    
    SystemInit();
    delay_init ( 72 );
    NVIC_Configuration();
    uart_init ( 9600 );
    LED_Init();
    GUI_Init();
    Touch_Init();
    GUI_SetBkColor ( GUI_RED ); /* 设置背景颜色 */
    GUI_SetColor ( GUI_WHITE ); /* 设置前景颜色,即字体和绘图的颜色 */
    GUI_Clear(); /* 按指定颜色清屏 */
    GUI_DispStringAt ( "Hello World ..", 10, 10 ); /* 显示字符 */
    GUI_CURSOR_Show(); /* 显示鼠标来测试触摸屏,必须打开窗口功能GUI_WINSUPPORT */

    while ( 1 ) {
    
    
        GUI_TOUCH_Exec(); /* 调用UCGUI的TOUCH相关函数 */
        GUI_Exec(); /* GUI事件更新 */
    }
}

  触摸屏横屏的方法如下:
  1. 修改LCD的默认显示方向:LCD的驱动文件里有个LCD_MyInit函数,用于初始化LCD。该函数中有个LCD_Display_Dir函数,用于切换LCD的显示方向,根据需要选择:

LCD_Display_Dir ( 1 ); /* 0为竖屏,1为横屏 */

  2. 修改ucgui中对应于触摸的坐标检测函数:GUI_X_Touch.c有两个检测触摸的函数,即GUI_TOUCH_X_MeasureXGUI_TOUCH_X_MeasureY。如果是竖屏显示,GUI_TOUCH_X_MeasureX返回X坐标,GUI_TOUCH_X_MeasureY返回Y坐标,横屏显示的话反过来就可以了:

int GUI_TOUCH_X_MeasureX ( void ) {
    
    
    tp_dev.scan ( 0 );
    // return tp_dev.x; /* 竖屏显示 */
    return tp_dev.y; /* 横屏显示 */
}

int GUI_TOUCH_X_MeasureY ( void ) {
    
    
    tp_dev.scan ( 0 );
    // return tp_dev.y; /* 竖屏显示 */
    return tp_dev.x; /* 横屏显示 */
}

  3. 修改ucgui中触摸屏的相关设置:在LCDConf.h中修改LCD_XSIZELCD_YSIZE,在GUITouchConf.h中修改GUI_TOUCH_AD_RIGHTGUI_TOUCH_AD_BOTTOM。如果X轴触摸是反的,需要修改一下GUI_TOUCH_MIRROR
  如果需要将UCOS系统移植到ucgui上,可以参考以下步骤:
  1. 首先将ucos系统移植到STM32上,并通过信号量、消息邮箱等机制的测试。
  2. 将GUIConf.h文件中的GUI_OS设置为1,同时在Config文件夹下添加GUI_X_uCOS.c文件,并加入到工程中。
  3. 将GUI_X_uCOS.c文件中的GUI_X_ExecIdle函数改为:

void GUI_X_ExecIdle ( void ) {
    
    
    //OS_X_Delay ( 1 );
    OSTimeDly ( 50 );
}

同时在该文件中增加宏定义:

#define TRUE  1
#define FALSE 0

GUI_X.c文件中的如下4个函数注释掉:

  • GUI_X_GetTime(void);
  • GUI_X_Delay(int ms);
  • GUI_X_Init(void);
  • GUI_X_ExecIdle(void);

最后将TFT显示屏中的延时函数用ucos的延时函数替代,延时毫秒的(如delay_ms)用OSTimeDly替代,延时微秒的(如delay_us)用OSTimeDly(1);替代。至此所有移植工作结束!

猜你喜欢

转载自blog.csdn.net/fukangwei_lite/article/details/121715686