UCGUI
ucGUI移植详细设计及总结

ucGUI移植详细设计及总结序本文档阐述了将ucGUI移植到IM12上的过程。
ucGUI版本为3.9,移植到IM12上,触摸屏及按键能够正常使用。
在ucGUI源码包的基础上,添加了一些接口函数以适应IM12,在使用时应该根据情况使用这些接口,这些新增加的函数的接口将在后面章节中详细讲述。
此外,适应IM12的ucGUI在Wind River Workbench 3.0环境下被编译成两个静态库文件libNoWindow.a和libWindow.a,编译程序时应该连接这两个库。
文档篇章安排如下:第一章,ucGUI源码包简介。
主要介绍了所使用的ucGUI图形库中各文件夹的内容及功能,并对IM12中与ucGUI移植相关的部分,包括触摸屏、LCD、按键板等进行了简单的介绍。
第二章,图形库移植。
阐述如何对ucGUI进行配置、编译,以在IM12的LCD上显示图形,此部分还未实现触摸屏及按键功能,只是纯粹的显示而已第三章,触摸屏移植。
第四章,按键移植。
第五章,带触摸屏及按键功能的ucGUI应用程序模板。
第一章ucGUI源码包简介ucGUI要移植到im12上,实际上就是根据im12的情况修改ucGUI中的一些配置项,或增加、删减一些程序以适应im12,同时要保持ucGUI的特性。
要做好移植工作,需对ucGUI 及IM12相关部分有足够的了解。
1.1ucGUI简介移植所采用的ucGUI版本为3.9,主要包含的文件夹如图1所示图1 ucGUI源码结构图各文件夹的主要内容如下:Config ----------- 配置文件GUI ----------- 源代码GUI_X ---------- 操作系统接口函数定义文件GUI 源代码文件:1)AntiAlias: 抗锯齿显示效果支持。
2)ConvertColor: 彩色显示的色彩转换支持。
3)ConvertMono: (b/w)和灰度显示的色彩转换支持。
4)Core: 核心文件,提供了GUI基本的功能。
uCGUI 汉字显示技巧及总结

UCGUI的基础应用汉字显示在uC/GUI中显示汉字,必要的一个步骤就是汉字取模。
通常有两种方法:一、单个字模法:使用字模取模软件,进行单个字的取模。
此方法可应用于显示汉字字数较少的情况下。
其优点是:占用存储空间小,无冗余。
但当显示汉字字数较多时,该方法则非常繁琐。
二、字模库法:该方式需要移植整个汉字字库,若项目要求需显示多种汉字字体,则需移植多种字体的字库。
其优点是:操作方便。
若嵌入式系统的FLASH存储容量够大时,该方式可行。
根据作者多年的项目实践,找到一个兼具上述两种方式优点的显示方案:利用UCGUIFontTool软件,提取windows自带的字模库。
该方法的使用步骤:1、将项目中所要显示的汉字根据字体进行分类并汇总。
2、使用UCGUIFontTool软件分别提取上述字模。
3、将所产生的.C文件添加到工程中。
4、更改gui.h中的配置,添加该汉字的宏定义,如图5、显示汉字前更改需显示的字体,如图6、利用函数进行显示。
该方法移植方便,易实现同时显示多种字体,无字模冗余,占用存储空间最小。
图片显示uC/GUI提供了位图的解决方案,在GUI显示图片时,需先将其他格式的图片转换为bmp格式。
可利用windows系统自带的画图软件打开一个图片,再另存为bmp格式,继而转换为.c 格式文件加入到工程中。
其操作步骤如下:1、将其他格式的图片另存为bmp格式。
2、打开UCGUI源码自带的工具uC-GUI-BitmapConvert,选择相应参数,并转换为.c文件。
3、将该.c文件加入到工程中。
4、添加外部变量,并调用相应函数进行显示。
如图5、也可UCGUI提供的缩放函数可对图片进行缩放显示。
如图这里说一个技巧:如果无需在显示过程中对图片进行缩放,那么建议在第二步的时候就完成图片的缩放操作,以减少CPU的工作量。
控件显示UCGUI提供了很多控件,这里不再赘述,每个控件的操作方式类同。
这里以按钮控件作为举例。
UCGUI移植

移植UCGUI只需要修改3个文件:GUIConf.h,LCDConf.h,LCDDummy.c,并从源代码的Sample/GUI_X文件夹下复制GUI_X.c文件到工程的GUILib/Config目录下1、GUIConf.h刚开始移植的时候是没有RTOS的,LCD也不是触摸屏,所以GUI_OS和GUI_SUPPORT_TOUCH都定义为0,其他宏不需要修改2、LCDConf.hLCD_XSIZE、LCD_YSIZE和LCD_BITSPERPIXEL根据开发板LCD的配置定义,我用的屏的分辨率是480*272的,16位RGB;LCD_CONTROLLER必须定义成-1,表示使用自己定义的LCD驱动,这个LCD驱动是通过修改LCDDummy.c模板来实现的,因为LCDDummy.c中开始部分要判断宏LCD_CONTROLLER是否等于-1,如果不等于-1,LCDDummy.c中的内容不会被编译,当然LCD_CONTROLLER也可以定义成其他植,但和LCDDummy.c中一定要对应起来,而且不能等于UCGUI自带的LCD驱动号LCD_ON和LCD_OFF一定要定义,因为LCDDummy.c中的LCD_On()和LCD_Off()函数先判断相应的宏是否被定义,如果没定义则不会执行函数体中的内容UCGUI的初始化过程中的LCD部分是通过GUI_Init()(GUICore.c)->LCD_Init()(LCD.c)->LCD_L0_Init()(LCD_Dummy.c)实现的,因为LCDDummy.c中的LCD初始化函数LCD_L0_Init()调用LCD_INIT_CONTROLLER()宏来调用自定义的LCD初始化函数,所以要将宏LCD_INIT_CONTROLLER()定义成自定义的LCD 初始化函数GLCD_Init()。
也可以在不用修改LCD_INIT_CONTROLLER()宏,而是在LCD_L0_Init()直接调用GLCD_Init()3、LCDDummy.cLCDDummy.c文件中需要修改的函数有:1)、void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)2)、void LCD_L0_GetPixelIndex(int x, int y)3)、void LCD_On(void)4)、void LCD_Off(void)5)、int LCD_L0_Init(void)修改如下:其中395行的SetPixelIndex函数,422行的GetPixelIndex函数,536行的GLCD_On函数,542行GLCD_Off函数都是自己在LCD驱动文件中定义的函数,LCD_INIT_CONTROLLER()也被定义成LCD驱动文件中的LCD初始化函数4、LCD驱动文件1)、头文件drv_glcd.h:#include "lpc_types.h"#include "sdram_mt48lc2m32lfb5.h"#ifndef __GLCD_DRV_H#define __GLCD_DRV_H#define C_GLCD_PIX_CLK 9000000#define C_GLCD_REFRESH_FREQ (50HZ)#define C_GLCD_H_SIZE 480#define C_GLCD_H_PULSE 41#define C_GLCD_H_FRONT_PORCH 2#define C_GLCD_H_BACK_PORCH 2#define C_GLCD_V_SIZE 272#define C_GLCD_V_PULSE 10#define C_GLCD_V_FRONT_PORCH 2#define C_GLCD_V_BACK_PORCH 2#define LCD_RED 0xf800 /* red color */#define LCD_GREEN 0x07e0 /* green color */#define LCD_BLUE 0x001f /* blue color */#define LCD_BLACK 0x0000 /* black color */#define LCD_WHITE 0xffff /* white color */#define C_GLCD_PWR_ENA_DIS_DL Y 10000#define C_GLCD_ENA_DIS_DL Y 10000extern uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];void GLCD_Init(void);void GLCD_Ctrl(BOOLEAN bEna);void SetPixelIndex(int x, int y, int PixelIndex);uint16_t GetPixelIndex(int x, int y);void GLCD_On(void);void GLCD_Off(void);#endif // __GLCD_DRV_H2)、drv_glcd.c文件#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "board.h"#include "sdram_mt48lc2m32lfb5.h"#include "drv_glcd.h"#include "lpc177x_8x_clkpwr.h"#include "lpc177x_8x_pinsel.h"uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];/************************************************************************** Function Name: GLCD_Init* Parameters: const uint32_t *pPain, const uint32_t * pPallete** Return: none** Description: GLCD controller init**************************************************************************/ void GLCD_Init(void){uint32_t i;//uint32_t *pDst = (uint32_t *)LCD_Frame_Buffer;//uint32_t p0,p1,p2,p3;/*Back light enable*///Turn on LCD clockCLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);// Disable cursorLPC_LCD->CRSR_CTRL &=~(1<<0);// disable GLCD controllerLPC_LCD->CTRL = 0;// 16 bppLPC_LCD->CTRL &= ~(0x07 <<1);LPC_LCD->CTRL |=(6<<1);// TFT panelLPC_LCD->CTRL |= (1<<5);// single panelLPC_LCD->CTRL &= ~(1<<7);// notmal output// LPC_LCD->CTRL &= ~(1<<8);LPC_LCD->CTRL |= (1<<8);// little endian byte orderLPC_LCD->CTRL &= ~(1<<9);// little endian pix orderLPC_LCD->CTRL &= ~(1<<10);// disable powerLPC_LCD->CTRL &= ~(1<<11);// init pixel clockLPC_SC->LCD_CFG = 1;//CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((uint32_t)C_GLCD_PIX_CLK);// bypass inrenal clk dividerLPC_LCD->POL |=(1<<26);// clock source for the LCD block is HCLKLPC_LCD->POL &= ~(1<<5);// LCDFP pin is active LOW and inactive HIGHLPC_LCD->POL |= (1<<11);// LCDLP pin is active LOW and inactive HIGH// LPC_LCD->POL |= (1<<12);LPC_LCD->POL &= ~(1<<12);// data is driven out into the LCD on the falling edge// LPC_LCD->POL |= (1<<13);LPC_LCD->POL &= ~(1<<13);// active highLPC_LCD->POL &= ~(1<<14);LPC_LCD->POL &= ~(0x3FF <<16);LPC_LCD->POL |= (C_GLCD_H_SIZE-1)<<16;// init Horizontal TimingLPC_LCD->TIMH = 0; //reset TIMH before set valueLPC_LCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;LPC_LCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;LPC_LCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;LPC_LCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;// init Vertical TimingLPC_LCD->TIMV = 0; //reset TIMV value before settingLPC_LCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;LPC_LCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;LPC_LCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;LPC_LCD->TIMV |= C_GLCD_V_SIZE - 1;// Frame Base Address doubleword alignedLPC_LCD->UPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;LPC_LCD->LPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;for(i = C_GLCD_ENA_DIS_DL Y; i; i--);return ;}/************************************************************************* * Function Name: GLCD_Ctrl* Parameters: Bool bEna** Return: none** Description: GLCD enable disabe sequence**************************************************************************/void GLCD_Ctrl (BOOLEAN bEna){volatile uint32_t i;if (bEna){// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}else{// LCD_CTRL_bit.LcdPwr= 0; // disable powerLPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}}void SetPixelIndex(int x, int y, int PixelIndex){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE] = (uint16_t)PixelIndex;}}uint16_t GetPixelIndex(int x, int y){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {return LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE];}return 0;}void GLCD_On(void){uint32_t i;// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}void GLCD_Off(void){uint32_t i;// LCD_CTRL_bit.LcdPwr= 0; // disable power LPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--); // LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}。
uCGUI使用

uCGUI使⽤最好多参考⼏篇⽂章,⽐如UC/GUI中⽂⼿册与emWin5_UM_SC0:画图函数GUI_DrawRect:在当前窗⼝中的指定位置绘制矩形(不填充,画线颜⾊为前景⾊)void GUI_DrawRect(int x0, int y0, int x1, int y1);在当前窗⼝中的指定位置绘制填充的矩形区域(填充前景⾊)(填充前景⾊)GUI_FillRect:在当前窗⼝中的指定位置绘制填充的矩形区域:清除矩形区域(为矩形区域填充背景颜⾊,图形界⾯⽤填充背景⾊达到清除屏幕的矩形区域填充背景颜⾊,图形界⾯⽤填充背景⾊达到清除屏幕的GUI_ClearRect:清除矩形区域(为)效果)效果1:存储设备不使⽤存储设备时,绘制操作直接写⼊显⽰器。
屏幕在执⾏绘制操作时随时更新,从⽽在进⾏各种更新时使屏幕闪烁。
如果在此过程中使⽤存储设备,则所有绘制操作都在存储器中执⾏。
仅在所有操作都完成后才将最终结果显⽰在屏幕上,其优点是没有闪烁。
如果不使⽤存储设备,则可以看到⼀步步的绘制操作效果,缺点是会出现显⽰器闪烁。
使⽤存储设备时,⼀次可见到所有例程的效果,就象单次操作⼀样,不能实际看见中间步骤。
以下例程是在使⽤存储设备时通常会调⽤的,基本⽤法⾮常简单:1. 创建存储设备(使⽤GUI_MEMDEV_Create() )。
2. 激活它(使⽤GUI_MEMDEV_Select() )。
3. 执⾏绘制操作。
4. 将结果复制到显⽰器中(使⽤GUI_MEMDEV_CopyToLCD() )。
5. 不再需要它时,删除该存储设备(使⽤ GUI_MEMDEV_Delete() )。
2:WM窗⼝管理器回调例程:回调例程由⽤户程序定义,指⽰在特定事件出现时图形系统调⽤特定的函数。
它们通常⽤于在窗⼝内容更改时⾃动重绘窗⼝。
窗⼝管理器的默认特性是向每个需要重绘的窗⼝发送⼀条 WM_PAINT 。
当⽤户对窗⼝有操作时,WM会发送相应的消息给该窗⼝,窗⼝可通过回调函数根据消息直接对屏(没有⽤存储设备时)或对窗⼝的存储设备进⾏操作再拷贝到屏幕上,具体的消息说明可以参考emWin的中⽂⼿册。
ucGUI重点内容

1.目前国内普遍认同的嵌入式定义为:以应用为中心, 以计算机技术为基础, 软硬件可裁剪, 适应应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
2.嵌入式系统的特点:是专用的计算机系统。
系统资源需求较少。
使用高实时操作系统RTOS。
具有很好地可裁剪性。
功耗低、体积小、集成度高、成本低。
Ch31. GUI(Graphic User Interface)系统是是指计算机与其使用者之间的图形化对话接口。
2.嵌入式GUI具有以下特点:●体积小●功能强;●图形算法简洁、快速,占用系统资源少●高可靠性,高可裁剪性;●模块结构,上层接口与硬件无关,便于移植和定制3. GUI的主要特征:●Windows,采用窗口界面,每个窗口是用户或系统的一个工作区域。
一个屏幕上可以有多个窗口。
●Icons,采用形象化的图标或图符,易于操作者理解与操作。
●Menu,采用菜单,可供用户选择的功能提示●Pointing Devices ,指鼠标器、触摸屏等,便于用户直接对屏幕对象进行操作。
Ch41.正常文本GUI_TEXTMODE_NORMAL 或 0。
2.反转文本GUI_TEXTMODE_REVERSE。
3.透明文本GUI_TEXTMODE_TRANS4.透明反转文本GUI_TEXTMODE_TRANS |GUI_TEXTMODE_REVERSE5.文本对齐的选择:1). int GUI_GetTextAlign(void);返回当前文本对齐模式。
2).int GUI_SetTextAlign(int TextAlign);设置文本对齐模式,用于当前视窗的字符串输出。
水平对齐:GUI_TA_LEFT X轴方向左对齐(默认)GUI_TA_HCENTER X轴方向对中GUI_TA_RIGHT X轴方向右对齐(默认)垂直对齐:GUI_TA_TOP 在字符Y轴方向顶部对齐(默认)GUI_TA_VCENTER 在Y轴方向对中CUI_TA_BOTTOM 在字体Y轴底部线像素对齐Ch6 字体1.在应用程序中显示汉字的方式是通过字体转换器转换后得到的.C文件步骤:1.将所需显示的各种字体汉字库.C文件加入到Font目录中。
ucgui gui_lock()原理

ucgui gui_lock()原理ucgui 并不是我所熟知的某个特定的GUI库,可能是某个特定环境或定制版本中的GUI库。
不过,基于一般的GUI库设计原理,gui_lock() 函数通常用于锁定GUI系统,防止在关键操作期间发生意外的界面更新或重绘。
以下是关于 gui_lock() 函数可能的工作原理的一般性描述:工作原理:1.状态管理:gui_lock() 函数会更改GUI库的内部状态,将GUI系统标记为锁定状态。
这通常通过设置一个标志位或计数器来实现。
2.阻止重绘:当GUI系统处于锁定状态时,任何尝试更新或重绘界面的操作都会被阻止或延迟。
这确保了在锁定期间,界面不会发生变化,从而避免了可能的界面闪烁或错误显示。
3.同步和异步操作:在某些情况下,GUI操作可能是异步的,即它们会在后台线程或定时任务中执行。
gui_lock() 需要确保即使在这些异步操作中,锁定状态也能被正确识别和处理。
4.嵌套锁定:有些GUI库支持嵌套锁定,即多次调用 gui_lock() 会增加锁定计数,而只有对应的 gui_unlock() 调用次数足够多时,GUI系统才会真正解锁。
这可以防止由于误操作导致的锁定和解锁不匹配问题。
5.解锁操作:通常会有一个与 gui_lock() 对应的 gui_unlock() 函数,用于解除锁定状态。
当GUI系统解锁时,之前被阻止的界面更新操作可以继续执行。
示例伪代码:c复制代码// 假设有一个全局变量来表示GUI的锁定状态int gui_locked = 0;void gui_lock() {gui_locked++;// 可能还有其他操作,如禁用定时器或事件处理等}void gui_unlock() {if (gui_locked > 0) {gui_locked--;// 如果解锁完成,恢复定时器或事件处理if (gui_locked == 0) {// 触发界面更新或重绘}}}注意事项:•谨慎使用:锁定GUI系统应该谨慎使用,因为它会阻止界面的正常更新。
第十讲 uCGUI简介

1 GUI 概述 1.1 GUI的功能
• GUI的功能 以API函数的形式向应用程序提供图 形界面的操作功能,如描点、画线、填 充、显示控件、字体管理等功能。 可以降低在嵌入式系统开发过程中的 图形操作界面的开发难度,提高效率, 美化界面。
第十讲 uCGUI简介 第十讲 uCGUI 简介
1、GUI 概述 2、GUI常见种类 3、uCGUI 的特点 4、uCGUI的功能函数 5、uCGUI的使用
下图为颜色模式555的效果图:
4 uC/GUI 的功能函数 4.4.6 定义物理调色板
4) 定义物理调色板
在LCDConf.h中定义4种颜色(全部为灰色) 的调色板:
4 uC/GUI 的功能函数 4.4.7 颜色管理函数
4) 颜色管理函数(1)
4 uC/GUI 的功能函数 4.4.8 颜色管理函数
3 uCGUI的特点 3.1.3 uC/GUI 概述
1) uCGUI的特征
• 视窗显示和管理功能; • 支持触摸屏和鼠标的输入; • 具有功能全面的PC机实用软件工具,如模拟 器、观察器、位图转换器、字体转换器等。
3 uCGUI的组成 3.1.4 uC/GUI 概述
2) uCGUI的组成 通常GUI文件放 在工程文件的根目
5) 字体操作函数(1) uCGUI支持ASC11,IOS8859-1,Unicode
字体编码;有宽位图字体、比例位图字体、
2bpp (bit/pixel)和4bpp比例位图等4种字体
字体的选择在GUIConf.h中定义,字体
需要与应用程序连接在一起。
4 4.5.2 增加字体 uC/GUI 的功能函数
▪文本显示函数 ▪数值显示函数
▪平面(2D)图形库
原创ucGUI入门心得

ucGUI 入门心得学习ucGUI 近一个月,感觉已经达到入门的级别,先前掌握的Windows 应用程序开发经验对于学习ucGUI 有着很大的帮助。
首先,我使用的是ucGUI 的高版本——emwin5.22 。
这个版本较旧版本多了些可用的控件和皮肤,这会让我们设计出外观更好,功能更强的界面。
然后,我们设计出来的界面需要在VC6.0 上进行调试。
网上可以下载到移植好的emwin及附带的小工具。
这些工具包括界面设计工具GUIBuilder ,图片转16进制数据工具BmpCvt和字体生成工具FontCvt。
用好这些工具对我们开发GUI有很大的帮助。
接着开始创建一个GUI 工程。
第一步用GUIBuilder 创建一个对话框做为窗体,第二步在这个对话框上面放上一些用到的控件,接下来对这些控件进行属性设置,这些都做完以后,点击保存菜单就会生成一个C文件。
VC6.0引用这个C文件就可以显示刚才设计的界面了。
如果让我们的界面更加美观就需要用到BmpCvt 工具,它可以把图片生成16 进制数据供图片框调用。
BmpCvt可以生成透明背景的图片,效果相当不错。
制作透明图片需要用到Photoshop,在PS里新建一个带透明背景的图片,然后把我们图片粘贴进去,再擦除一此不需要的颜色就可以了。
带透明背景的图片用BmpCvt打开以后,可以看到透明部分显示的是马赛克就对了。
用FontCvt 工具可以生成我们需要的各种字体,也包括汉字。
我习惯使用Keil 开发环境,Keil 里使用汉字是Ansi 编码,而FontCvt 生成的是Unicode 编码,这显然不能兼容。
这需要转换一下就可以直接使用了。
最后总结一下在使用emwin 过程中遇到的一些问题。
1. 在对话框里使用画线画多边形或显示文字这些基本绘图功能。
只需要在窗口回调函数下的WM_PAINT肖息里操作即可。
2. 在点取下拉列表的表项时,会点击到其下边的其它控件,造成误操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
uC/GUI作为一个通用的嵌入式应用的图形模块,它在嵌入式系统中的作用也显得的越来越重要。
uC/GUI是一个源代码开放的图形系统,它提供了丰富的资源,包括二维绘图库、多字体及可扩充字符集、Unicode、位图显示、多级RGB及灰度调整、动画优化显示、具有Windows风格的对话框和预定义控件(按钮、编辑框、列表框等),以及对键盘、鼠标、触摸屏等输入设备和双LCD输出的支持,目前在具有图形界面的嵌入式产品中得到越来越广泛地应用。
2 通用嵌入式图形模块uC/GUIuC/GUI是一个通用的嵌入式应用的图形模块,它是美国Micrium公司开发的一种高效的、与处理器和LCD控制器独立的通用GUI,可以适用各种CPU和LC D,在单任务和多任务操作系统中,它都可以工作得很好。
它具有驱动接口层和应用层,全部代码采用ANSI _C编写,提供源代码,可以方便的移植到各种平台下。
2.1 uC/GUI特点(1) 支持任何8位、16位和32位的CPU,只要求CPU具有相应的ANSI_C编译器即可。
(2) 所有硬件接口定义都使用可配置的宏。
(3) 字符、位图可显示与LCD的任意点,并不限制与字节长度的整数倍数地址。
(4) 所有程序在长度和速度方面都进行了优化,结构清晰。
(5) 对于慢速的LCD控制器,可以使用缓冲存储器减少访问时间,提高显示速度[1]。
因为uC/GUI具有这些优点,它越来越受到更多嵌入式设计者的青睐。
2.2 uC/OS-II介绍在嵌入式系统的开发过程中,选择操作系统与选择开发平台一样的重要。
虽然不是一个完整的实时操作系统,只是一个实时内核,但与其它操作系统比起来它具有很多优点因而得到了广泛的应用。
首先它是一种结构简单、源代码公开的操作系统,适合所有的开发者使用;它具有可移植性,它的绝大部分源码都是用移植性很强的ANSI _C编写,与微处理器硬件相关的部分采用汇编语言编写,很容易被移植到各种微处理器上;它还具有可固化和可裁剪等特点,对于嵌入式设计者来讲的,只要拥有固化手段(C编译、连接、下载和固化),就可以很方便将其嵌入到产品中去。
设计者还可以根据系统应用程序的需要对uC/OS-I I进行相应的裁剪来减少产品中的uC/OS-II所需的存储器空间,这可以通过条件编译来实现。
2.3 uC/GUI接口uC/GUI 是运行于操作系统之上的程序,它既需要与操作系统的协调,又需要与各种输入输出设备的协调,来实现用户层与应用程序层的联结,即通过输入设备接收用户请求、通过输出设备反映微处理器的响应。
因此在这一过程中GUI至少要与3个对象打交道:输入设备、输出设备和操作系统。
因此uC/GUI接口主要包括2 个,与操作系统的接口和与输入输出设备的接口,这也正是在移植uC/GUI的过程中所要解决的关键问题。
对于操作系统,GUI作为操作系统的一个显示任务接受操作系统的调度,uC/GU I提供了与操作系统的接口支持。
与操作系统的接口主要解决系统实时性的要求。
对于用户输入,uC/GUI提供了键盘、鼠标以及触摸屏等支持,对于输出设备G UI反映微处理器的响应给用户是通过LCD输出图像来完成的,对于不同型号和显示原理的LCD要编制相应的驱动程序。
关于ucgui 的lcd驱动ucgui 是一个分层结构的gui系统,大概可以分为以下几个层次1、设备驱动层(LCD,键盘触摸屏等设备驱动)2、基本显示层3、在基本显示层上搭建的api层,字体等的显示4、窗口管理和控件层5、ap层这里主要记录显示驱动层的相关事项.ucgui的显示驱动层是显示的最下层,用户基本不用直接调用该层的接口,只有在移植和优化时要考虑修改和配置该层。
ucgui的lcd 驱动层是支持多lcd显示的,GUI_NUM_ LAYERS 宏来配置,GUI_NUM_LAYERS 最大为5.一、lcd驱动层的主要配置参数#define LCD_XSIZE (640) /* lcd 的X 方向的像素点数*/#define LCD_YSIZE (480) /* lcd 的Y 方向的像素点数*/#define LCD_BITSPERPIXEL (8) /* lcd 上每个像素点占的位数*/#define LCD_CONTROLLER 1375 /* lcd 控制器id号*/#define GUI_NUM_LAYERS /* lcd 的分层数目*/GUI_NUM_LAYERS 这个参数是分层显示的层数,ucgui中层可以是虚拟的显示层,也可以是实际的lcd屏。
这取决于各个层的接口函数。
二、lcd驱动需要提供的函数接口lcd驱动层要实现以下类型的接口函数typedef LCD_COLOR tLCDDEV_Index2Color (int Index);typedef unsigned int tLCDDEV_Color2Index (LCD_COLOR Color);typedef unsigned int tLCDDEV_GetIndexMask (void);typedef void tLCDDEV_DrawBitmap (int x0, int y0, int xsize, int ysize,int BitsPerPixel, int BytesPerLine,const U8 GUI_UNI_PTR * pData, int Diff,const void* pTrans); /* Really LCD_PIXELINDEX, but is void to avoid co mpiler warnings*/typedef void tLCDDEV_DrawHLine (int x0, int y0, int x1);typedef void tLCDDEV_DrawVLine (int x , int y0, int y1);typedef void tLCDDEV_FillRect (int x0, int y0, int x1, int y1);typedef unsigned int tLCDDEV_GetPixelIndex(int x, int y);typedef void tLCDDEV_SetPixelIndex(int x, int y, int ColorIndex);typedef void tLCDDEV_XorPixel (int x, int y);typedef void tLCDDEV_FillPolygon (const GUI_POINT* pPoints, int N umPoints, int x0, int y0);typedef void tLCDDEV_FillPolygonAA(const GUI_POINT* pPoints, int N umPoints, int x0, int y0);typedef void tLCDDEV_GetRect (LCD_RECT*pRect);typedef int tLCDDEV_Init (void);typedef int tLCDDEV_ReInit (void);typedef void tLCDDEV_On (void);typedef void tLCDDEV_Off (void);typedef void tLCDDEV_SetLUTEntry (U8 Pos, LCD_COLOR color);lcd驱动各个类型的接口函数的功能tLCDDEV_On 打开lcdtLCDDEV_Off 关闭lcdtLCDDEV_ReInit 重新初始化lcd,不清除lcd显示内容tLCDDEV_Init 初始化lcd,该是在初始化时被调用的,调用路径为GUI_Init->LCD_I nit->LCD_L0_Inittypedef void tLCDDEV_DrawBitmap(int x0, int y0, int xsize, int ysize,int BitsPerPixel, int BytesPerLine, const U8 GUI_UNI_PTR * pData, int Diff, const void* pTrans);功能:绘制位图参数:x0, y0 位图的左上角坐标xsize, ysize 位图宽度和高度BitsPerPixel 位图每个像素点占的位数BytesPerLine 位图每行的字节数pData 位图数据指针Diff 从左侧开始跳过的像素数pTrans 颜色转换表typedef LCD_COLOR tLCDDEV_Index2Color (int Index);将颜色索引转换成颜色值typedef unsigned int tLCDDEV_Color2Index (LCD_COLOR Color);将颜色值转换成颜色索引typedef unsigned int tLCDDEV_GetIndexMask (void);得到颜色索引的屏蔽字typedef void tLCDDEV_DrawHLine (int x0, int y0, int x1);功能:画一条水平线参数:x0 起点x坐标x1 终点x坐标y0 横线的y坐标typedef void tLCDDEV_DrawVLine (int x , int y0, int y1);功能:画一条垂直线参数:x 垂直线的x坐标y0 起点y坐标y1 终点y坐标typedef void tLCDDEV_FillRect (int x0, int y0, int x1, int y1); 功能:填充一个矩形参数:x0 , y0 矩形的左上角坐标x1 , y1 矩形的右上角坐标typedef unsigned int tLCDDEV_GetPixelIndex(int x, int y);读取给定点的颜色的索引typedef void tLCDDEV_SetPixelIndex(int x, int y, int ColorIndex); 以给定的颜色在指定的点画一个像素点typedef void tLCDDEV_XorPixel (int x, int y);反现指定点的像素typedef void tLCDDEV_FillPolygon (const GUI_POINT* pPoints, int N umPoints, int x0, int y0);填充一个多边形typedef void tLCDDEV_FillPolygonAA(const GUI_POINT* pPoints, int N umPoints, int x0, int y0);带抗锯齿功能的填充多边形typedef void tLCDDEV_GetRect (LCD_RECT*pRect);得到lcd的显示区域typedef void tLCDDEV_SetLUTEntry (U8 Pos, LCD_COLOR color);修改lcd控制器的LUT条目lcd 信息函数接口,每个显示层都应该提供lcd信息函数lcd 0层信息接口函数名如下:int LCD_GetXSize(void)读取lcd的物理宽度(像素值)int LCD_GetYSize(void)读取lcd的物理高度(像素值)int LCD_GetVXSize(void)读取lcd的虚拟宽度int LCD_GetVYSize(void)读取lcd的虚拟高度int LCD_GetBitsPerPixel(void)读取lcd每个像素的位数U32 LCD_GetNumColors(void)读取lcd颜色的数目int LCD_GetYMag(void)读取lcd虚拟高度的放大因子int LCD_GetXMag(void)读取lcd虚拟宽度的放大因子int LCD_GetFixedPalette(void)读取固定调试板的模式lcd 1-4层信息函数接口名如下:?=1,2,3,4int LCD_GetXSize_?(void)int LCD_GetYSize_?(void)int LCD_GetVXSize_?(void)int LCD_GetVYSize_?(void)int LCD_GetBitsPerPixel_?(void)U32 LCD_GetNumColors_?(void)int LCD_GetYMag_?(void)int LCD_GetXMag_?(void)int LCD_GetFixedPalette_?(void)uC/GUI与输入输出设备驱动接口模块设计本文以LCD驱动接口模块设计为例介绍在uC/GUI移植过程中LCD驱动程序的编写,以最终实现图形显示。