2.3. 定时器驱动uCGUI通过OS_TimeMS来作为时基,因此需要一个定时器实现1ms/tick更新OS_TimeMS这个时基计数器。此处采用S5PV210的Timer4,初始化并注册相应的中断后,在其中断回调函数更新OS_TimeMS,同时处理uCGUI约100HZ频率查询触摸屏输入任务。
uint8_tTP_Period;
staticvoid Timer4_Callback(void)
{
extern volatile int OS_TimeMS;
OS_TimeMS++; // 1ms计数,在GUI_X.c中定义,用来uCGUI延时计数
#ifGUI_SUPPORT_TOUCH
TP_Period++;
if (TP_Period >= 10) { // 每隔10ms检查触摸屏输入
TP_Period = 0;
IRQ_DisableInt(INT_TIMER4); // 禁止同一中断重入
IRQ_Enable(); // 在定时器中断处理中允许I2C嵌套中断
GUI_TOUCH_Exec(); // 保证100HZ的触摸屏输入检查
IRQ_EnableInt(INT_TIMER4);
}
#endif
}
3. uCGUI修改3.1. GUIConfig目录进入GUIConfig目录,打开GUIConf.h对GUI进行总体的配置,由于内存充足,可以设置较大的动态内存以及支持内存设备,此处并不支持操作系统以及鼠标。修改后的内容如下:
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_OS (0) /* 不支持多任务 */
#defineGUI_SUPPORT_TOUCH (1) /* Support a touch screen (req. win-manager)*/
#define GUI_SUPPORT_MOUSE (0) /* 不支持鼠标 */
#defineGUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */
#defineGUI_DEFAULT_FONT &GUI_Font6x8
#defineGUI_ALLOC_SIZE (4*1024*1024) /* 动态内存4M*/
/*********************************************************************
*
* Configuration of available packages
*/
#defineGUI_WINSUPPORT 1 /* Window manager package available */
#defineGUI_SUPPORT_MEMDEV 1 /* Memory devices available */
#defineGUI_SUPPORT_AA 1 /* Anti aliasing available */
#endif /* Avoidmultiple inclusion */
打开LCDConf.h对LCD进行配置,笔者使用的是16位(R:5-G:6-B:5)色深800*480的RGB屏,清空LCDConf.h中的所有内容,因为这是其它LCD屏的配置,与所用屏完全不一致,修改后的内容如下:
#ifndef LCDCONF_H
#define LCDCONF_H
/*********************************************************************
* Generalconfiguration of LCD
**********************************************************************
*/
#define LCD_XSIZE (800) /* 屏X水平像素点 */
#define LCD_YSIZE (480) /* 屏Y水平像素点 */
#define LCD_BITSPERPIXEL (16) /* 16位色深*/
#define LCD_CONTROLLER (-1) /* 宏开关,使用LCDDriver下的模板 */
#define LCD_FIXEDPALETTE (565) /* R:5-G:6-B:5 */
#define LCD_SWAP_RB (1) /*RB颜色调换 */
#define LCD_SWAP_XY (0) /* 屏x,y方向不调换 */
#define LCD_INIT_CONTROLLER() Display_Init()/* 屏驱动初始化接口 */
#endif /* LCDCONF_H */
打开GUITouchConf.h对触摸屏进行配置,笔者使用的是电容屏,驱动IC已处理好返回的触摸坐标值与屏像素坐标一一对应,也可以在移植后进行校准。
#ifndefGUITOUCH_CONF_H
#defineGUITOUCH_CONF_H
#define GUI_TOUCH_AD_LEFT 0 /* 触摸屏能返回最左边的值 */
#defineGUI_TOUCH_AD_RIGHT 800 /* 触摸屏能返回最右边的值 */
#defineGUI_TOUCH_AD_TOP 0 /* 触摸屏能返回最上面的值 */
#defineGUI_TOUCH_AD_BOTTOM 480 /* 触摸屏能返回最下面的值 */
#defineGUI_TOUCH_SWAP_XY 0 /* 触摸屏x,y方向不调换 */
#defineGUI_TOUCH_MIRROR_X 0 /* 触摸屏x方向不镜像调换*/
#defineGUI_TOUCH_MIRROR_Y 0 /* 触摸屏y方向不镜像调换*/
#endif /*GUITOUCH_CONF_H */
3.2. LCDDriver目录进入GUI->LCDDriver目录,需修改uCGUI关于实际LCD的底层接口调用。由于我们在LCDConf.h里配置LCD_CONTROLLER为-1,这个宏开关会选择LCDTemplate.c这个模板文件进行编译,其它的接口文件不会被编译。LCDTemplate.c里面已经有相关的模板代码,只需加入LCD_L0_SetPixelIndex()和LCD_L0_GetPixelIndex()的实现即可,LCD_L0_SetPixelIndex设置LCD某一坐标的像素值,LCD_L0_GetPixelIndex从LCD某一坐标读出像素值,分别对应RGB屏驱动底层函数Display_SetPixel ()和Display_GetPixel()。加入这两个底层函数即可。
LCD_L0_SetPixelIndex()修改后代码如下:
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Write into hardware ... Adapt toyour system */
{
Display_SetPixel(x, y, (unsignedshort)PixelIndex);
}
}
LCD_L0_GetPixelIndex()修改后的代码如下:
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
LCD_PIXELINDEX PixelIndex;
GUI_USE_PARA(x);
GUI_USE_PARA(y);
/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Read from hardware ... Adapt toyour system */
{
PixelIndex= (LCD_PIXELINDEX)(Display_GetPixel(x, y));
}
return PixelIndex;
}
3.3. GUI_X目录GUI启动前,除了LCD可能还有其它需初始化的硬件设备,例如uCGUI要用到LCD以及触摸屏,那么在GUI使用前就应先初始化这些设备,这部分在GUI_X_Init()函数中处理,在GUI_X_Init()函数中实现如下:
void GUI_X_Init(void)
{
#if GUI_SUPPORT_TOUCH
TP_Init();// 使用uCGUI时先初始化触摸屏
#endif
}
GUI_X_Touch.c为uCGUI触摸屏访问接口,只要实现GUI_TOUCH_X_MeasureX()和GUI_TOUCH_X_MeasureY()即可。这两个函数分别与电容屏驱动获得第一个触摸点x,y位置的底层函数TP_GetPoint1_X()与TP_GetPoint1_Y()对应。
int GUI_TOUCH_X_MeasureX(void) {
return TP_GetPoint1_X();
}
int GUI_TOUCH_X_MeasureY(void) {
return TP_GetPoint1_Y();
}
4. uCGUI Demo应用应用程序中调用相应的uCGUI的例程Demo,其效果如下:
5. 附录S5PV210_uCGUI.rar,uCGUI在IAR下的移植工程,包括S5PV210 Bootloader、uCGUI源码、以及相应的RGB、TP、I2C、Timer驱动。
`