本文详细介绍了在STM32平台上移植ucGUI图形库的完整步骤。主要内容包括:1)工程目录结构调整,重命名冲突文件;2)ucGUI源码文件的复制与配置;3)关键配置文件的修改(GUIConf.h、LCDConf.h);4)LCD驱动适配,包括初始化函数重命名和绘图函数添加;5)ColorBar示例程序的移植与优化;6)刷屏性能优化,通过修改填充矩形函数显著提升速度。移植过程中特别注意了文件冲突处理、函数重命名和硬件抽象层的适配,最终实现了在240x320分辨率TFTLCD上的图形显示功能,并通过逻辑颜色到物理颜色的映射机制保证了颜色显示的灵活性。
https://download.csdn.net/download/czhaii/93038231?spm=1001.2014.3001.5503
1、打开调试好的TFTLCD测试程序(这里是打开"ALIENTEK MINISTM32 实验10 TFTLCD显示实验")的工程文件夹,在其中创建ucGUI的文件夹。由于ucGUI/CORE文件中已经存在了lcd.h和lcd.c的文件,所以我们将工程目录HARDWARE/LCD中的lcd.c文件和lcd.h文件的文件名换成ili93xx.c和ili93xx.h,并将其中的预处理命令也相应的更换。然后将ili93xx.h和ili93xx.c中用来标识液晶屏宽和高的LCD_H与LCD_W分别换成LCD_HEIGHT和LCD_WIDTH。
2、打开ucGUI源码文件,将其Start/GUI目录下的除JPEG文件夹以外的文件夹复制到第一步中创建的ucGUI文件夹中。
3、将Start/Config和Sample/GUI_X也复制到之前的文件夹 ucGUI中。
其中,USER、HARDWARE、SYSTEM、CORE、FWLib是工程中原有的文件,除此之外为需要新建的文件。 由于ucGUI目录下的CORE文件名与原有的文件名相冲突,故将其修改为ucCORE。并将ucGUI目录下的除GUI_X、Config以外的所有文件添加到相应的文件夹下。然后再添加Config目录下对应的三个.h文件和GUI_X目录下的GUI_X.c文件。
5、打开Config/GUIConf.h将其修改如下:
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_OS (0) /* Compile with multitasking support */
#define GUI_SUPPORT_TOUCH (0) /* Support a touch screen (req. win-manager) */
#define GUI_SUPPORT_UNICODE (0) /* Support mixed ASCII/UNICODE strings */
#define GUI_DEFAULT_FONT &GUI_Font6x8
//#define GUI_ALLOC_SIZE 12500 /* Size of dynamic memory ... For WM and memory devices*/
#define GUI_ALLOC_SIZE 5000 /* Size of dynamic memory ... For WM and memory devices*/
/*********************************************************************
*
* Configuration of available packages
*/
#define GUI_WINSUPPORT 0 /* Window manager package available */
#define GUI_SUPPORT_MEMDEV 0 /* Memory devices available */
#define GUI_SUPPORT_AA 0 /* Anti aliasing available */
#endif /* Avoid multiple inclusion */
6、打开Config/LCDConf.h将其修改为如下:
#ifndef LCDCONF_H
#define LCDCONF_H
/*********************************************************************
*
* General configuration of LCD
*
**********************************************************************
*/
#define LCD_XSIZE (240) /* 320 -> 400 */
#define LCD_YSIZE (320) /* 240 */
#define LCD_CONTROLLER (-1) /* 9320 -> 5420 */
#define LCD_BITSPERPIXEL (16)
#define LCD_FIXEDPALETTE (565)
#define LCD_SWAP_RB (1) //红蓝反色交换
//#define LCD_SWAP_XY (1)
//LCD_MIRROR_X
#define LCD_INIT_CONTROLLER() LCD_hard_Init();
#endif /* LCDCONF_H */
7、打开ili93xx.c和ili93xx.h文件,将其中的void LCD_Init(void)函数更名为void LCD_hard_Init(void)以防与ucGUI中的原有函数名冲突。然后再在ili93xx.c中添加如下函数,并在ili93xx.h中将其声明。
void ili9320_SetPoint(u16 x,u16 y,u16 color)
{
POINT_COLOR=color;
LCD_DrawPoint(x,y);
}
8、打开LCDDummy.c文件,添加头文件包含#include "ili93xx.h";将预处理命令修改为#if (LCD_CONTROLLER == -1) 。
9、在void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)函数最后添加语句ili9320_SetPoint( xPhys, yPhys ,PixelIndex);
10、在unsigned int LCD_L0_GetPixelIndex(int x, int y)函return语句之前添加PixelIndex = LCD_ReadPoint(x,y);
11、移植ColorBar程序,将main.c文件修改为如下形式(别忘了在main.c文件中添加#include "gui.h"的预处理命令):
void DemoShowColorBar(void);
int main(void)
{
SystemInit();
delay_init(72); //延时初始化
NVIC_Configuration();
uart_init(9600);
LED_Init();
KEY_Init();
// LCD_Init();
GUI_Init();
GUI_SetBkColor(GUI_BLACK);
GUI_SetColor(GUI_WHITE);
GUI_Clear();
GUI_SetFont(&GUI_Font24_ASCII);
GUI_DispStringHCenterAt("COLOR_ShowColorBar - Sample", 160, 5);
DemoShowColorBar();
while(1)
{
delay_ms(400);
LED0 = !LED0;
}
}
void DemoShowColorBar(void)
{
int x0 = 60, y0 = 40, yStep = 15, i;
int xsize = LCD_GetDevCap(LCD_DEVCAP_XSIZE) - x0;
GUI_SetFont(&GUI_Font8x16);
#if (LCD_FIXEDPALETTE)
y0 = 66;
yStep = 13;
GUI_DispStringAt("Fixed palette: ", 0, 40);
GUI_DispDecMin(LCD_FIXEDPALETTE);
#endif
GUI_DispStringAt("Red", 0, y0 + yStep);
GUI_DispStringAt("Green", 0, y0 + 3 * yStep);
GUI_DispStringAt("Blue", 0, y0 + 5 * yStep);
GUI_DispStringAt("Grey", 0, y0 + 6 * yStep);
GUI_DispStringAt("Yellow", 0, y0 + 8 * yStep);
GUI_DispStringAt("Cyan", 0, y0 + 10 * yStep);
GUI_DispStringAt("Magenta", 0, y0 + 12 * yStep);
for (i = 0; i < xsize; i++) {
U16 cs = (255 * (U32)i) / xsize;
U16 x = x0 + i;;
/* Red */
GUI_SetColor(cs);
GUI_DrawVLine(x, y0 , y0 + yStep - 1);
GUI_SetColor(0xff + (255 - cs) * 0x10100L);
GUI_DrawVLine(x, y0 + yStep, y0 + 2 * yStep - 1);
/* Green */
GUI_SetColor(cs<<8);
GUI_DrawVLine(x, y0 + 2 * yStep, y0 + 3 * yStep - 1);
GUI_SetColor(0xff00 + (255 - cs) * 0x10001L);
GUI_DrawVLine(x, y0 + 3 * yStep, y0 + 4 * yStep - 1);
/* Blue */
GUI_SetColor(cs * 0x10000L);
GUI_DrawVLine(x, y0 + 4 * yStep, y0 + 5 * yStep - 1);
GUI_SetColor(0xff0000 + (255 - cs) * 0x101L);
GUI_DrawVLine(x, y0 + 5 * yStep, y0 + 6 * yStep - 1);
/* Gray */
GUI_SetColor((U32)cs * 0x10101L);
GUI_DrawVLine(x, y0 + 6 * yStep, y0 + 7 * yStep - 1);
/* Yellow */
GUI_SetColor(cs * 0x101);
GUI_DrawVLine(x, y0 + 7 * yStep, y0 + 8 * yStep - 1);
GUI_SetColor(0xffff + (255 - cs) * 0x10000L);
GUI_DrawVLine(x, y0 + 8 * yStep, y0 + 9 * yStep - 1);
/* Cyan */
GUI_SetColor(cs * 0x10100L);
GUI_DrawVLine(x, y0 + 9 * yStep, y0 + 10 * yStep - 1);
GUI_SetColor(0xffff00 + (255 - cs) * 0x1L);
GUI_DrawVLine(x, y0 + 10 * yStep, y0 + 11 * yStep - 1);
/* Magenta */
GUI_SetColor(cs * 0x10001);
GUI_DrawVLine(x, y0 + 11 * yStep, y0 + 12 * yStep - 1);
GUI_SetColor(0xff00ff + (255 - cs) * 0x100L);
GUI_DrawVLine(x, y0 + 12 * yStep, y0 + 13 * yStep - 1);
}
}
13、以上就完成了ucGUI裸机移植的所有步骤,但是发现刷屏较慢。然后我们跟踪GUI_Clear()刷屏函数的执行情况,发现是void LCD_L0_FillRect(int x0, int y0, int x1, int y1)函数执行效率不高。于是将其修改如下:
void LCD_L0_FillRect(int x0, int y0, int x1, int y1)
{
LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);
}
重新烧写程序,发现刷屏速度大幅度提升!
14、ucGUI预定义了一些颜色,这些预定义是放在gui.h文件中。然而,我们发现这些颜色是以24bits的方式定义的。通过查询手册发现我们所使用的颜色被ucGUI定义成了"逻辑颜色" ,它通过最小平方偏移搜索的方式将其映射为"物理颜色"。所以在用户使用颜色时有很强的灵活性。