UCGUI函数表 (1) - 副本
- 格式:pdf
- 大小:2.00 MB
- 文档页数:18
GUI的种类及uCGUI的架构(说明:本博文转载自他人笔下,希望可以帮助同僚更深刻的认识GUI)GUI的种类及uC/GUI的架构一. GUI概述GUI(Graphic User Interface)是图形化的用户界面,它能提供友好的人机交互接口。
它有以下特性:体积小,运行时耗用系统资源少,层次化的结构,易移植,可靠性高嵌入式GUI种类嵌入式GUI种类有很多,下面列举几种:1. WINCE的GWES(图形、窗口、事件子系统),由应用程序接口(API)、用户接口(UI)和图形设备接口(GDI)组成,包含了消息机制2. Trolltech公司的产品:QT、QTE、QTOPIA,它们跨平台、功能强大,但资源消耗多3.MINIGUI是魏永明创建的嵌入式GUI中间件,可以以多线程、多进程、以及单任务运行,是比较成熟的商用系统4.ucGUI能支持多种环境的GUI,可以以多任务形式运行或者以前后台模式运行。
商用化,但功能相对简单GUI的两种模式:1. Windows模式,采用类似windows的API和相应的消息机制,如ucGUI、MicroWindows、miniGUI2.C/S模式,采用一个XServer,所有的显示都以客户端的形式请求服务,如Nano-XGUI在嵌入式系统或实时系统中的地位越来越多的市场需求数据显示,包括PDA、娱乐消费电子、机顶盒、DVD等影音设备、WAP 手机等高端电子产品得到广泛应用,原先仅在军工、工业控制等领域中使用的GUI图形系统,受到越来越多的关注。
对于轻量级 GUI 的系统而言,对 GUI 的要求相对较低,如传统51类型单片机这类系统一般不希望建立在庞大累赘的、非常消耗系统资源的操作系统和 GUI 之上,如 Windows 或 X Window。
目前此类系统都直接使用原有编程手段,采用比较简单的手法实现GUI。
对于太过庞大和臃肿的GUI系统而言,μc/GUI这类可运用于此类资源较紧张的轻型 GUI 的需求更加突出uc/GUI简介μc/GUI是美国Micrium公司出品的一款针对嵌入式系统的优秀图形软件。
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使⽤最好多参考⼏篇⽂章,⽐如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的配制文件的说明关于UCGUI的配制文件的说明特别说明:需要嵌入式UCOSII ucGUI arm和linux入门资料,项目资料,linux驱动资料可以加我QQ!!希望我的一些项目经验和资料可以带你进入嵌入式之门,在浩瀚的linux世界里找到属于你自己的舞台!!!希望大家多多支持我的QQ:1653687969UCGUI与大家熟悉的UCOS一样, 也提供了大量的可配制功能选项, 采用的方式也是在头文件中进行预定义, 这与UCOS是一样的. 预定义将决定可以使用的UCGUI图形功能, 下面我们将讨论一下UCGUI的配制情况, 并探讨一下其最小资源占用是多少, 即最小内存占用量.从UCGUI源码当中, 可以看到有这样一个文件夹---Config, 这个文件夹下面包含了以下胡三个头文件:1. GUICONF.h--------------基本的GUI预定义控制.2. GUITouchConf.h--------关于触屏的控制预定义.3. LCDConf.h---------------有关LCD夜晶显示的参数控制.一. 关于GUICONF.h这个文件当中, 包含了最基本的一些GUI图形预定义控制.其内容如下:#ifndef GUICONF_H#define GUICONF_H#define GUI_OS (1)/* Compile with multitasking support */#define GUI_SUPPORT_TOUCH (1) /* Support a touch screen(req. win-manager) */#define GUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */#define GUI_DEFAULT_FONT&GUI_Font6x8/* Size of dynamic memory ... For WM and memory devices*/#define GUI_ALLOC_SIZE 12500/***************************************************************** ****** Configuration of available packages*/#define GUI_WINSUPPORT 1 /* Window manager package available */#define GUI_SUPPORT_MEMDEV 1 /* Memorydevices available */#define GUI_SUPPORT_AA 1 /* Anti aliasing available */#endif /* Avoid multiple inclusion */可以看到, 这里面的配制并不是很多, 只有大约十项左右. 1.GUI_OS-------------是否须要多任务支持.在GUI_Protected.h文件当中有如下的代码:.....#if !GUI_OS#define GUI_LOCK()#define GUI_UNLOCK()#define GUITASK_INIT()#else#define GUI_LOCK() GUI_Lock()#define GUI_UNLOCK() GUI_Unlock()#define GUITASK_INIT() GUITASK_Init()#endif......并且在Core\guitask.C文件中, 如果GUI_OS未定义, 则会: void GUI_Unlock(void) {}void GUI_Lock(void) {}void GUITASK_Init(void) {}void GUITASK_StoreDefaultContext(void) {}将上面的几个函数都定义为空的.那什么都不做.所以GUI_OS的主要作用是在进行多任时支持时的互锁功能.当有了多任务支持,才有必要提供锁的功能. 这种锁功能对于资源的访问可以做到独占性而避免出现死锁或使用过程中被修改的情况,在模拟器当中, 这几个函数的实现都是通过WINDOWS的信息量功能来实现的..GUI_OS未定义时,将被定义为0.#ifndef GUI_OS#define GUI_OS 0#endif2.关于GUI_SUPPORT_TOUCH这个是关于触摸屏的支持, 首先必须是非功过硬件有触摸的支持, 详情参看源码.3.关于GUI_SUPPORT_UNICODE是否支持UNICODE码的预定义, 如果进行了预定义,那么显示字符前会先转化为UNICODE码. 主要在GUIUC0.C文件中提供.4.GUI_DEFAULT_FONT缺省字体, 在GUI\CORE\FONT文件夹下, 提供了十几种字体的支持, 这里的预定义将决定哪种字体将被支持, 要UCGUI中字体是点阵形式处理的, 而且是与GUI编译在一起, 使用哪种字体就会将哪种字体编译进去.在这里. 如果要支持多种字体, 而又采用字体与GUI代码编译在一起的做法, 将使GUI的资源占用非常大.缺省字体占用关不多8K左右.5.GUI_ALLOC_SIZEGUI_ALLOC_SIZE指定UCGUI可自己动态使用的内存量, 默认的是12500, 差不多是12K左右.UCGUI中使用动态内存管理是类似NEW,DELETE的,原理是一样的, 但比较简单一点. 使用的是双向链表, 在整个内存(12500)没有使用之前,链表中只有一个节点, 当申请过一次后, 就会变成两个节点, 一个记载申请的结点的内存信息,另外一个则是剩余内存信息.GUIAlloc.c文件当中提供了内存管理的功能.typedef struct {tALLOCINT Off; /* Offset of memory area */ tALLOCINT Size; /* usable size of allocated block */HANDLE Next; /* next handle in linked list */ HANDLE Prev;} tBlock;/**************************************************************** * Static data*/GUI_HEAP GUI_Heap; /* Public for debugging only */static tBlock aBlock[GUI_MAXBLOCKS];struct {int NumUsedBlocks, NumFreeBlocks, NumFreeBlocksMin; /* For statistical purposes only */tALLOCINT NumUsedBytes, NumFreeBytes, NumFreeBytesMin;} GUI_ALLOC;#define HMEM2PTR(hMem)(void*)&GUI_Heap.abHeap[aBlock[hMem].Off] GUIHEAP在GUI.h中提供的.typedef union {int aintHeap[GUI_ALLOC_SIZE/4]; /* required for proper alignement */U8 abHeap[GUI_ALLOC_SIZE];} GUI_HEAP;extern GUI_HEAP GUI_Heap; /* Public for debugging only */以上几点是内存管理的关键数据结构.GUI_Heap是一个联合体结构, 其内数据可以以INT整型,一次以四个字节来访问; 也可以以字节来访问,一次访问一个字节, 这块内存是以数组的形式来提供的.GUI_HEAP GUI_Heap; 这个全局变量即是UCGUI中可以动态分配使用的全部内存, 在分配使用时, 是按照块来使用的. tBlock aBlock[GUI_MAXBLOCKS];这个全局变量定义了可以用来管理动态内存的节点信息的块数组.GUI_MAXBLOCKS的大小如下:#ifndef GUI_MAXBLOCKS#define GUI_MAXBLOCKS (2+GUI_ALLOC_SIZE/32) #endif如果是总共内存为12500个字节, 则要48个这样的块结构.其占用内存大小为48*sizeof(tBlock)=48*16=768字节,这是最大的占用; 小的时候为一半, 结点大小为8个字节. 这768个字节是为了动态内存分配负出的代价.当第一次申请一块内存时. 整个动态内存的最初状态是: aBlock[0].Size = (1<<GUI_BLOCK_ALIGN); /* occupy minimum for a block */aBlock[0].Off = 0;aBlock[0].Next = 0;那么申请动态内存之前, 第一步就是先从块结构数组(即记录动态内存分配状况的数组)中找一个空闲的元素. 来作为记录将要分配内存的节点. 第二步,所有的块结构数组当中查找出可供使用的内存, 并将此内存的偏移地址, 这个偏移是相对于GUI_Heap这个整个动态内存的起始点的偏移. 举一个实际的例子如下:aBlock[0].Size = 4;aBlock[0].Off = 0;aBlock[0].Next = 0;aBlock[0].Pre = 0;当成功分配两块大小为500的内存时, 结点状态如下: aBlock[0].Size = 4;aBlock[0].Off = 0;aBlock[0].Next = &aBlock[1];aBlock[0].Pre = &aBlock[2];aBlock[1].Size = 500;aBlock[1].Off = 3;aBlock[1].Next = &aBlock[2];aBlock[1].Pre = &aBlock[0];aBlock[2].Size = 500;aBlock[2].Off = 503;aBlock[2].Next = &aBlock[0];aBlock[2].Pre = &aBlock[1];此时GUI_Heap的内存使用状态如下:从GUI_Heap.abHeap[0]到GUI_Heap.abHeap[3]为一块,使用状态记录于aBlock[0];从GUI_Heap.abHeap[4]到GUI_Heap.abHeap[503]为一块, 使用状态记录于aBlock[1];从GUI_Heap.abHeap[504]到GUI_Heap.abHeap[1007]为一块, 使用状态记录于aBlock[2];此时剩余的是GUI_Heap.abHeap[1008]---GUI_Heap.abHeap[12499]这一段.如果在此基础上, 要现分一块大小为为1002字节的, 则会首先讨调整大小(1002+1<<GUI_BLOCK_ALIGN-1)& 0x3, 将其大小调整为4的倍数对齐.其后, 则会通过查找, 找到aBlock[3].Size记录为0, 那么这个块节点可以用来记录一个内存配信息.查找用于记录该块内存的结点时, 从aBlock[0]查起, 发觉0---3已用, 查看结点aBlock[1], 得知4-503这夫内存已分配, 再查看其它已分配结点, 可得知0---1007 为已分配, 其余都没有使用, 即此次分配起点为1008, 即1008~(1008+1004).分配之后, 记录内存分配信息的结点状态如下:aBlock[0].Size = 4;aBlock[0].Off = 0;aBlock[0].Next = &aBlock[1];aBlock[0].Pre = &aBlock[3];aBlock[1].Size = 500;aBlock[1].Off = 3;aBlock[1].Next = &aBlock[2];aBlock[1].Pre = &aBlock[0];aBlock[2].Size = 500;aBlock[2].Off = 503;aBlock[2].Next = &aBlock[3];aBlock[2].Pre = &aBlock[1];aBlock[3].Size = 1004;aBlock[3].Off = 2012;aBlock[3].Next = &aBlock[0];aBlock[3].Pre = &aBlock[2];这种情况是最理想的状态下, 如果说内存经过多次分配与释放, 则情况将复杂一些. 比如说, 如果刚才所说的第一次申请的500个字节内存已经用完并被释放掉了,此时记录节点状态如下所示:aBlock[0].Size = 4;aBlock[0].Off = 0;aBlock[0].Next = &aBlock[2]; //不再指向1,直接指向2.aBlock[0].Pre = &aBlock[3];aBlock[1].Size = 0;aBlock[1].Off = 0;aBlock[1].Next = 0;aBlock[1].Pre = 0;aBlock[2].Size = 500;aBlock[2].Off = 503;aBlock[2].Next = &aBlock[3];aBlock[2].Pre = &aBlock[0]; //不再指向1, 直接指向0. aBlock[3].Size = 1004;aBlock[3].Off = 2012;aBlock[3].Next = &aBlock[0];aBlock[3].Pre = &aBlock[2];在这种情况下, 如果再要求申请一块200字节的内存, 则会找到空闲节点aBlock[1]来记录此次内存分配. 此次分配会导致在aBlock[1]与aBlock[2]这间产生一个300字节的HOLE. 如果后来又有200字节的内存分配请求. 则aBlock[4]将会用于记载此次内存分配.现在就有分配, 之后释放, 然后又有分配的过程做一个完整的分析如下:1. 申请500字节,2. 再申请500字节,3. 再申请1002字节4. 进行释放, 将第1次的500字节释放掉.5. 再申请一次200字节,6. 再申请一次100字节,7. 再申请一次400字节.那么此时的内存格局最终是什么样子呢?? 如下所示: aBlock[0].Size = 4;aBlock[0].Off = 0;aBlock[0].Next = &aBlock1]; //再一次指向1.先前在第4步释放500字节时, 指向2.aBlock[1]节点空闲..aBlock[1]最开始记载的是第1次分配的500字节内存aBlock[0].Pre = &aBlock[5]; //指向5..aBlock[1].Size = 200; //第1次申请了500,第5次时被free后被用作记载第4次配200.aBlock[1].Off = 4;aBlock[1].Next = &aBlock[2];aBlock[1].Pre = &aBlock[0]; //指向0..aBlock[2].Size = 500;aBlock[2].Off = 503;aBlock[2].Next = &aBlock[3];aBlock[2].Pre = &aBlock[1]; //再一次指向1. aBlock[3].Size = 1004;aBlock[3].Off = 2012;aBlock[3].Next = &aBlock[4];aBlock[3].Pre = &aBlock[2];aBlock[4].Size = 100; //第5次分配100. 还是在原来的第1次配500的空间内.aBlock[4].Off = 203;aBlock[4].Next = &aBlock[5];aBlock[4].Pre = &aBlock[3];aBlock[5].Size = 400; //第6次分配400, 第1次申请的500 free后已经用300,剩200不够,只能从后面中找空间aBlock[5].Off = 2013+400;aBlock[5].Next = &aBlock[0];aBlock[5].Pre = &aBlock[4];最终内存空间分布情况如下:0~~3-----------------------首结点4字节.4~~203--------------------第4次分配占用204~~303-----------------第5次分配占用304~~503-----------------free504~~1003---------------第二次分配占用1004~~2013--------------第三次分配占用2014~~2413--------------第六次分配占用如此, 这个内存分配的过程与原理就比较清晰的展示出来了, 在整个内存分配过程中, 用于记录内存分配状态的节点数组中, 形成的链表是在为不断的变化中的.认清这种变化才可以对内存分配的本质有所认识, 才能够真正分清内存分配.5.关于GUI_WINSUPPORTGUI_WINSUPPORT是用于是否须要窗口支持的, 在UCGUI当中提供了Frame winodws,edit, button, progress 等基本的图形控件,与WINDOWS上的类似, 但目前的功能则还不尽人意.图形效果与功能都不强..6.关于GUI_SUPPORT_MEMDEVGUI_SUPPORT_MEMDEV是指显示时, 是直接写一个一个象素到显示设备, 还是在内存当中当画好所有要画一屏幕点后再全部一次写到显示设置. 这两点的主要区别是, 如果一个一个点写, 则会出现闪的现象, 因为一个一个点的画, 如果速度慢, 可以扞到画一个复杂的图形时,是分几步一点点的画出来的...但是如果先画到内存当中, 再一次性COPY所有象素点到显示设备就不会有这种现象, 是一个连续的过程..画点时是连续的画,没有间隔.7.关于GUI_SUPPORT_AAGUI_SUPPORT_AA是指是否须要对边界进行模糊填充的功能, 比如说, 画一条斜线, 可以看到是一段一段的:\\\\\\这样从效果上看, 那么不是特别美观, 如果可以在线的偏离的周围进行线的颜色的淡化处理,即在线的周围填充一点*近线的颜色的象素点..那么看上去将会偏离得没那么明显, 比较模糊一点.二. GUITouch.h的配制.#ifndef GUITOUCH_CONF_H#define GUITOUCH_CONF_H#define GUI_TOUCH_AD_LEFT 20#define GUI_TOUCH_AD_RIGHT 240#define GUI_TOUCH_SWAP_XY 1#define GUI_TOUCH_MIRROR_X 0#define GUI_TOUCH_MIRROR_Y 1#endif /* GUITOUCH_CONF_H */由以上可以看出.GUITouch.h可预定义的选项更少了, 只是一些数值上的定义, 基本不会影响到UCGUI编译后的代码大小.三.关于LCDConf.h#define LCD_XSIZE (320) /* X-resolution of LCD,Logical coor. */#define LCD_YSIZE (240) /* Y-resolution of LCD, Logical coor. */#define LCD_BITSPERPIXEL (16)#define LCD_CONTROLLER 1375//Add by houhh 20050420/***************************************************************** ****** List of physical colors******************************************************************* *****//***************************************************************** ****** Full bus configuration******************************************************************* *****/#define LCD_READ_MEM(Off) *((U16*)(0xc00000+(((U32)(Off))<<1)))#define LCD_WRITE_MEM(Off,data) *((U16*)(0xc00000+(((U32)(Off))<<1)))=data#define LCD_READ_REG(Off) *((volatileU16*)(0xc1ffe0+(((U16)(Off))<<1)))#define LCD_WRITE_REG(Off,data) *((volatileU16*)(0xc1ffe0+(((U16)(Off))<<1)))=data....#endif /* LCDCONF_H */1. LCD_XSIZE/LCD_YSIZE这是指定LCD显示屏的宽高的.2.LCD_BITSPERPIXEL是指定屏幕上一个象素由几位来表示. 位数越多, 能够表示的颜色数就越多. 一屏所占用的内存就越多.。
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系统应该谨慎使用,因为它会阻止界面的正常更新。
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编译、连接、下载和固化),就可以很方便将其嵌入到产品中去。
UCGUI 简介译者:UCGUI邮箱:UCGUI@主页:版本:v1.0.0.01.0......UCGUI整体简介................UCGUI简介................本文档的目的...... .........前提学习要求.1.1.....要求...............目标硬件系统................开发环境(编译器).1.2.....UCGUI特性....... ........示例.1.3.....评估板.1.4.....如何使用本手册................印刷上的字体说明.1.5.....屏幕及坐标系统.1.6.....LCD控制器的连接类型.1.7.....数据类型.UCGUIUCGUI是一种嵌入式应用中的图形支持系统.它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示.它的设计架构是模块化的, 由不同的模块中的不同层组成, 由一个LCD驱动层来包含所有对LCD的具体图形操作, UCGUI可以在任何的CPU上运行, 因为它是100%的标准C 代码编写的.UCGUI能够适应大多数的使用黑白或彩色LCD的应用, 它提供非常好的允许处理灰度的颜色管理.还提供一个可扩展的2D图形库及占用极少RAM的窗口管理体系.本文档的目的本文档描述如何在嵌入式应用中安装,配制,使用UCGUI的图形用户接口, 并讲解UCGUI的内部设计架构.前提本文档假定你已经备坚实的C语言程序设计方面的知识, 如果你觉得自己这方面还不够, 那么我们推荐Kernighan 和 Richie的"C语言程序设计"给你, 它描述了最新的C标准, 即ANSI C标准, 本文档不须要具备汇编语言方面的知识.第一章1.1 要求对于开发UCGUI图形应用不须什么目标系统, 大部分的图形应用开发都可以在模拟器下进行; 但是最终的目的是通常还是在目标系统上运行程序.目标系统(硬件)你的目标系统必须具备如下几点:[1].CPU(8/16/32/64位)[2].必要的RAM和ROM存储[3].LCD显示器(任何类型及分辩率的)对于内存的需求取决于你选用的UCGUI的功能模块以及你所使用的目标系统上的编译器的效率. 内存的占用量无法估计准确的值, 下面就一些的数值适用于多数的目标系统.小型系统(不含窗口管理功能)[1].RAM:100字节[2].堆栈:500字节[3].ROM:10~25K(取决于选用的UCGUI功能模块)大型系统(包含窗口管理及各种窗体控件功能)[1].RAM: 2-6 kb (决于选用的应用中建立窗口的数量)[2].堆栈: 1200 bytes[3].ROM: 30-60 kb (决于选用的UCGUI功能模块)还要注意ROM的需求量随着你在应用程序中使用的字体数目而增长,以上的所有值都是粗糙的估计, 并不准确.开发环境(编译器)目标系统中采用的什么样的CPU并不重要, 但必须要有与所用CPU相对应的C编译器,如果你所使用的编译器有什么局限性, 请联系我们, 我们会告知你这些局限性会不会在你编译程序时产生问题, 大多数的16/32/64位的CPU或DSP上的编译器都可以正常使用, 大部分8位的编译也都可以正常编译.并不须要C++编译器, 不过它也可以正常使用, 如果有须求的话, 应用程序也可以在C++环境下正常编译使用.1.2 UCGUI的特性UCGUI的设计目标是为使用LCD作为图形显示装置的应用提供高效的/与LCD控制器独立及处理器独立的图形用户接口. 它适合于单任务环境及多任务环境, 如私用的操作系统或是商业的RTOS(实时操作系统). UCGUI以C源码形式提供, 并适用于任意LCD 控制器和CPU下任何尺寸的真实显示或虚拟显示.它包含以下特性:一般特性[1] 适用任何8/16/32位CPU, 只要有相对应的标准C编译器.[2] 任何的控制器的LCD显示器(单色,灰度,颜色), 只要有适合的LCD驱动可用.[3] 在小模式显示时无须LCD控制器.[4] 所有接口支持使用宏进行配制.[5] 显示尺寸可定制.[6] 字符和位图可在LCD显示器上的任意起点显示,并不仅局限于偶数对齐的地址起点.[7] 程序在大小和速度上都进行了优化.[8] 编译时允许进行不同的优化.[9] 对于缓慢一些的LCD控制器, LCD显存可以映射到内存当中, 从而减少访问次数到最小并达到更高的显示速度.[10]清晰的设计架构.[11]支持虚拟显示, 虚拟显示可以比实际尺寸大(即放大).图形库[1] 支持不同颜色深度的位图.[2] 提供可用的位图转换工具.[3] 图形运算时绝对不含浮点运算.[4] 快速画点/线(不含浮点运算).[5] 高速画圆及多边形.[6] 多种画图模式.字体集[1] 为基础应用提供多种不同字体:4*6, 6*8, 6*9,8*8, 8*9, 8*16, 8*17, 8*18, 24*32, 以及8, 10, 13, 16等几种高度(象素单位)的均衡字体(proportional fonts). 更详细的信息, 请参考第25章:"标准字体".[2] 可以方便的加入及链接进自定义字体.[3] 只有应用程序中用到的字体被实际链接进最后的执行映象文件中, 因此保证占用最小数量的ROM.[4] 提供可用的字体转换工具.任何宿主系统(如微软windows系统)上的可用字体均可以经转换后使用.字符串/数值输出[1] 支持数值的任何字体下的十进制/二进制/十六制显示.[2] 支持数值的任何字体下的十进制/二进制/十六制编辑输入.窗体管理器[1] 齐全的窗口管理, 包括剪切, 在窗体客户区外[2] 窗体可以移动及改变大小.[3] 支持窗口回调函数(可选功能).[4] 窗体占用最低RAM(每个窗体占用20个字节).可选的类似PC机的窗体控件[1] 可用的窗体控件(窗体对象, 也称作控件), 操作简便而且容易使用.触摸屏及鼠标支持[1]对于窗体控件如按钮, UCGUI提供触摸屏及鼠标支持.PC下的工具[1] 模拟器及查看器.[2] 位图转器工具.[3] 字体转换工具.示范样例为了给你一个更好的关于UCGUI可以完成什么的概念. 我们编写了不同的可用范例程序, 执行映象文件在Sample\exe下, 源码码在Sample目录下. Sample\GUIDemo下包含了展示更多UCGUI特性的范围范例程序.1.3 评估板一个完整的评估板包括有LCD显示器的演示板/C编译器/完整的工程示例, 评估板的目的主要是测试和演示UCGUI, 并可以熟悉UCGUI的开发.评估板[1] 三菱M30803 CPU/SED 13705 LCD 控制器(包含图表及文档说明).[2] LCD(320*240 分辨率)单色, 1/4 VGA彩色显示或者TFT.更详细的说明, 请查看网站.1.4 如何使用此文档本文档介绍了如何安装、配制、使用UCGUI, 并描述了UCGUI的内部设计架构以及所有提供的功能(即应用程序开发手册, 简称API接口).在实际使用UCGUI之前, 你应该阅读或者至少概览一遍整个手册以对UCGUI有一个整体的认识, 建议按照以下的步骤进行UCGUI的学习:[1] 获取UCGUI源码到硬盘中.[2] 通读本文档第二章:"UCGUI开篇".[3] 使用UCGUI模拟器以慢慢熟悉用它可以做什么(参考第三章:"UCGUI模拟器").[4] 使用文档其它部分提供的知识扩展你的程序.文档排版中使用符号标志的约定[参看具体的E文档]风格作用[1] 正文.[2][3] API参数.[4] 程序示例源码.[5] 已经加入存在的应用中的源码.1.5 屏幕及坐标体系屏幕由许多可以单独控制的点组成, 这些点称为象素, 大部分UCGUI提供的文本显示及画图函数均可以在任意指定的点进行画写.水平刻度为X轴, 垂直刻度为Y轴. 由X轴及Y轴坐标组成(x,y)二维坐标来描述屏幕中一点, 在需要X,Y坐标的作为参数的函数中X坐标在Y坐标之前传递. 屏幕(或者窗口)左上角点的坐标为(0,0). X轴右方向为正, Y轴下方向为正. 上图描述了UCGUI中的会标体系及X轴Y轴. 所有传入API参数中的坐标值的单位均为象素.1.6 LCD显示器到微控制器连接方式UCGUI提供所有LCD的访问支持, 实际上对几乎所有LCD控制器的都能提供独立透明的访问支持. 了解详细情况, 请参考第20章:"初级UCGUI配制". 如果你的LCD控制器不被支持的话请与我们联系, 我们目前正在为市场上所有的的LCD控制器编写驱动, 也许我们已经可以提供你打算使用的LCD控制器的驱动. 通常的为你应用写访问LCD的驱动是非常简单的工作. 如果在你目标硬件中需要的话, MIcrium公司可提供专业化的用户支持服务.LCD显示器控制器是以何种方式连接到系统中以及它是如何被程序访问的都不重要, 通常可以有几种连接方法, 在驱动程序中提供实现大部分的相同访问接口. 驱动程序通常情况下无须做什么大的修改, 可以在LCDConf.h文件中进行适合你的硬件的配制修改. 有关如何配制的情况可参考在第22章:"LCD 驱动程序"中的解释说明. 最通常的LCD 访问方法如下所描述, 如果你只想知道如何使用UCGUI, 以下小节可跳过.[1] LCD控制器总线型连接LCD控制器直接连接到系统总线上, 即意味着可以象RAM一样访问它, 这是一种非常高效的访问方法, 是强烈推荐使用的方法. LCD显存地址定义在LCDSEG当中, 为了能访问LCD显存, 必须知道LCD显存在物理空间中的映射区域, 这种连接方式的不同LCD控制器的驱动通用的.[2] LCD控制器端口型连接对于速度缓慢一些的控制器使用在快速的处理器上, 使用端口连接方式是唯一的解决方案. 这种连接方法的缺点是访问LCD的速度比总线型连接慢, 不过加上访问缓存后可以最大化的提高LCD的访问速度, 从而使LCD画面更新不会明显的下降. 编写驱动时所要做的就是写出设置及读写与LCD控制器连接的硬件端口的宏. 这种连接方式对于不同的LCD控制器需要不同的驱动程序.[3] 无须控制器的连接LCD显示器也可以不用LCD控制器而直接连接到系统上, LCD显示数据可以直接通过一个4位或是8位的移位寄存器来传送, 这种方式的硬件解决方案的优点是成本低, 但是缺点是占用大部分的处理器时间, 其占用率在不同的CPU上从20%到差不多100%不等; 对于速度慢的处理器, 这是根本不能接受的. 这种连接方式根本不须要指定的驱动程序, 因为UCGUI只是简单的将要显示的数据传送到LCD显存当中, 其余就是编写周期性的将LCD显存中的数据传送到LCD中显示的硬件图形显示相关部分.样例中提供了用C及优化过的M16C及M16C/80汇编语言编写的传送显存中数据到LCD中显示的代码.1.7 数据类型因为C并没有提供在不同的平台中固定长度的数据类型, 所以UCGUI定义了大部分自己的数据类型如下表所示:数据类型定义注解位有符号整数char 8-bitI8 signed无符号整数char 16-bitU8 unsignedI16 signed short 16-bit 有符号整数U16 unsigned short 16-bit 无符号整数I32 signed long 32-bit 有符号整数U32 unsigned long 32-bit 无符号整数I16P signed short 16-bit 有符号整数U16P unsigned short 16-bit 无符号整数对于多数16/32位的定义都可以非常方便的设置, 如果你在自己的应用程序部分定义改变或是重新定义自己的数据类型,推荐放在LCDConf.h配置文件内.。
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的中文手册。
一、ucGUBuilder使用方法 (2)1,新建ucGUI窗体 (2)2、设置窗体的属性 (3)3、向窗体添加控件 (4)二、V ersion 2.1.0.5 新增功能 (9)1、新增C语言语法高亮显示 (9)2、支持设计的窗体保存为文件,并可以打开 (9)3、对所有控件属性添加了Description (12)4、保存窗体布局 (13)三、Version 3.0.0.0 新增功能 (15)1、支持窗体设计器基本操作 (15)2、多控件操作 (15)3、文件关联 (16)4、在线检查更新 (18)5、自定义控件ID (20)四、Version 3.1.0.0新增功能 (22)1、添加了控件ID自动增加功能 (22)2、用户自定义字体 (22)3、中英文切换 (23)4、自动检查更新 (24)6、问题反馈或提建议 (25)五、Version 4.0新增功能 (27)1、代码分离 (27)2、添加编辑器工具栏 (28)3、内嵌VC编译器能直接运行模拟器 (29)4、如何使用代码自动完成功能 (30)声明:此程序用C#开发,需要.Net Framework 3.5或跟高版本支持大家在测试的过程中发现什么BUG或者有什么建议可以发Email:ucguibuilder@给我,一、ucGUBuilder使用方法1,新建ucGUI窗体或者单击新建窗体设计器工具栏按钮或者点下拉箭头选择新建窗体设计器新建后的效果:2、设置窗体的属性(包括大小,标题栏文本,……)3、向窗体添加控件(1)、在工具箱单击选中你要添加的控件将鼠标移动到窗体上,鼠标光标变成了十字形然后按住鼠标左键,拖动会出现一个矩形,拖动到合适大小,松开鼠标,在刚才矩形区域的地方就会添加一个同样大小的在工具箱选中的控件。
或者在工具箱中选中控件,将鼠标移动到窗体上,鼠标光标变成十字形时,单击鼠标,也能在单击处添加一个默认大小的选择的控件。
4、调整控件的大小及属性把鼠标移动到选中的控件四周的小方块上,当鼠标指针变成箭头时,按住鼠标左键就可向对应的方向调整控件大小,把鼠标移动到控件上,按住鼠标左键就可拖动控件,移动控件位置也可以,修改控件属性,来调整控件二、Version 2.1.0.5 新增功能1、新增C语言语法高亮显示2、支持设计的窗体保存为文件,并可以打开单击保存按钮或者菜单-》保存会弹出保存文件对话框选择路径,输入文件名即可保存(保存格式为ucfrm 格式)保存完毕。