UCGUI函数表 (1) - 副本
GUI的种类及uCGUI的架构
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移植详细设计及总结序本文档阐述了将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中⽂⼿册与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的配制文件的说明关于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_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
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邮箱: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使用
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的中文手册。
uCGUIBuilder使用说明
一、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 格式)保存完毕。
ucgui移植(包括触摸)
快速移植
将所有的源代码(配置文件除外,会在下面提及)的.c和.h文件都添加到工程中的一个文件夹下面
再将配置文件添加到另一个文件夹下面
在设置几个接口函数
LCDDummy.c文件中的
画点函数接口:
读点函数接口:
液晶屏初始化函数接口:
GUI_X_touch.c文件中的
读触摸事件的X,Y值(模拟值)函数接口:
GUIConf.h文件中的开触摸功能以及其他相关配置
GUITouchConf.h文件中的配置
配置触摸事件模拟坐标值在屏幕的左右上下的坐标值,GUI会将其转换为实际坐标值
LCDConf.h文件中的屏幕大小配置及相关配置
另外,触摸屏事件需要一个检测周期,需在定时器中调用检测函数
其中GUI_TOUCH_Exec()是触摸事件的检测函数。
GUI_Exec()在窗口设计时用到,与刷屏、回调函数有关。
在main.c中添加这两行即可测试触摸功能。
至此,结束。
--屈环宇
--2013年11月10日。
第01章 ucGUI的介绍
第1章 µC/GUI的介绍µC/GUIµC/GUI是一种用于嵌入式应用的图形支持软件。
它被设计用于为任何使用一个图形LCD 的应用提供一个有效的不依赖于处理器和LCD控制器的图形用户接口。
它能工作于单任务或多任务的系统环境下。
µC/GUI适用于使用任何LCD控制和CPU的任何尺寸的物理和虚拟显示。
它的设计是模块化的,由在不同的模块中的不同的层组成。
一个层,称作LCD驱动程序,包含了对LCD的全部访问。
µC/GUI适用于所有的CPU,因为它100%由的ANSI的C语言编写的。
µC/GUI很适合大多数的使用黑色/白色和彩色LCD的应用程序。
它有一个很好的颜色管理器,允许它处理灰阶。
µC/GUI也提供一个可扩展的2D图形库和一个视窗管理器,在使用一个最小的RAM时能支持显示窗口。
本文档的目的本指南描述如何安装,配置和在嵌入式应用中使用µC/GUI图形用户界面。
它也说明了软件的内部结构。
假设本指南假定你对C编程语言已经具有一个扎实的认识。
如果你觉得你对C语言的认识不是很充分的话,我们推荐该由Kernighan和Richie编写的“C语言编程语言”给你,它描述了程序设计标准,而在新版中,也包含了ANSI的C语言标准。
汇编语言编程的知识不需要。
µC/GUI中文手册第1页1.1 需求在你使用µC/GUI进行软件开发时,并不需要一个目标系统;只需要使用模拟器,大多数软件就能够进行开发。
然而,最后的目的通常是能够在一个目标系统上运行该软件。
目标系统(硬件)你的目标系统必须:• 有一个CPU(8/16/32/64位)• 有最少的RAM和ROM• 有一个完全的图形LCD(任何类型和任何分辩率)内存需求的变化取决于软件的哪些部分被使用以及你的目标编译程序的效率有多高。
所以指定精确值是不可能的,但是下面的数值适合典型系统。
[转载]ucgui绘制多边形、仪表盘(主要练习圆弧的画法)
[转载]ucgui绘制多边形、仪表盘(主要练习圆弧的画法)原⽂地址:ucgui绘制多边形、仪表盘(主要练习圆弧的画法)作者:雷娟学习⽇记⼀:ucgui绘制多边形、仪表盘(主要练习圆弧的画法)2011-05-30 19:57本次学习主要学习多边形的画法。
主要功能函数:1、绘制多边形,参数说明(依照括号中参数的顺序说明)显⽰的多边形的指针,多边形顶点个数,多边形中点横坐标,多边形中点纵坐标LCD_DrawPolygon(const GUI_POINT *pPoint,int NumPoints,int x,int y);其中多边形的指针通常是我们⾃⼰定义的多边形顶点数组的⾸元素地址,在以下程序中会涉及到,已经⽤红⾊标记出。
如果要实现图像的闪动效果,我们可以在每次绘制图形前使⽤函数GUI_ClearRect(int x0,int y0,int x1,int y1);功能是使⽤背景⾊填充⼀个矩形区域,当然要实现⼭东效果,这个矩形的⼤⼩当然是要包含所要绘制的多边形的⼤⼩了。
2、绘制圆弧函数,参数说明(依照括号中参数的顺序说明)圆弧的⽔平坐标,圆弧的垂直坐标,x轴半径,y轴半径,起始⾓度,终⽌⾓度LCD_DrawArc(int x0,int y0,int rx,int ry,int a0,int a1);虽然画圆弧只是简单的调⽤此函数即可,但是还未真正准确的掌握起始⾓度与终⽌⾓度如何选择。
有待补充与练习。
#include "GUI.H"#include "windows.h"#include <math.h>#include <stddef.h>void MainTask(void);void DrawScale(void);#define SPEED 1100//绘制速度#define DEG2RAD (3.1415926f/180) //绘制弧度的转化static const GUI_POINT _aPointArrow[] = {{0,0},{-40,-30},{-10,-20},{-10,-70},{10,-70},{10,-20},{40,-30}};static const GUI_POINT _aPointStar[] = {{0,-36},{8,-8},{36,0},{8,8},{0,36},{-8,8},{-36,0},{-8,-8}};static const GUI_POINT _aPointHexagon[] = {{0,-30},{26,-15},{26,15},{0,30},{-26,15},{-26,-15}};static void _DrawPolygon(void){int y = 90;GUI_SetBkColor(GUI_BLACK);//定义屏幕背景⾊,为⿊⾊GUI_Clear();//在编写应⽤程序前,⾸先清屏,是⼀种编程习惯GUI_SetColor(GUI_WHITE);//设置绘图颜⾊为⽩⾊GUI_SetFont(&GUI_Font24_ASCII);//设置字体GUI_SetTextAlign(GUI_TA_HCENTER);//设置⽂本对其⽅式为⽔平GUI_DispStringAt("Drawpolygon - sample",160,5);GUI_SetFont(&GUI_Font8x16);GUI_DispStringAt("using",5,40);GUI_DispStringAt("GUI_FillPolygon",5,55);GUI_SetTextAlign(GUI_TA_HCENTER);GUI_DispStringAt("polygon of arbitrary shapenin any color",160,y+90);// GUI_Delay(500);//延时函数,单位为毫秒//while(1)//{GUI_ClearRect(100,y,220,y+85);//以背景⾊填充⼀个矩形框,相当于选定⼀个初始矩形框,以作为下图的绘图 GUI_SetColor(GUI_BLUE);GUI_FillPolygon(&_aPointArrow[0],7,160,y+80);GUI_Delay(1000);GUI_ClearRect(100,y,220,y+85);GUI_SetColor(GUI_RED);GUI_FillPolygon(&_aPointStar[0],8,160,y+45);GUI_Delay(1000);GUI_ClearRect(100,y,220,y+85);GUI_SetColor(GUI_GREEN);GUI_FillPolygon(&_aPointHexagon[0],6,160,y+45);GUI_Delay(1000);//}}void _MainTask(void)//应⽤程序开始{_DrawPolygon();}void _DrawScale(void){int XSize = LCD_GetXSize(); //取得LCD物理尺⼨,这个参数是在lcdconf.h⾥⾯定义int YSize = LCD_GetYSize();int XMide = XSize/2;int i = 0;int r1 = 110;//定义效果图中下⾯的⼀条弧的半径int r2 = 140;//定义效果图中上⾯的⼀条弧半径int rt = 100;//定义效果图中刻度(数字)所在弧的半径int step = 15;int r= (r1+r2)/2;int c = 0;GUI_SetPenSize(r2-r1);//设置线型宽度为30GUI_SetColor(GUI_RED);//第⼀个扇形块填充红⾊GUI_AA_DrawArc(XMide,YSize,r,r,45,60);GUI_Delay(SPEED);GUI_SetColor(GUI_WHITE);GUI_SetPenSize(5);//设置线性宽度为2,绘制上下两条圆弧GUI_AA_DrawArc(XMide,YSize,r1,r1,45,135);//绘制下圆弧GUI_Delay(SPEED);GUI_AA_DrawArc(XMide,YSize,r2,r2,45,135);//绘制上圆弧GUI_Delay(SPEED);for(i = 45;i<=135;i+= step){float co = cos(i*DEG2RAD);float si = sin(i*DEG2RAD);int x1 = XMide - r1*co;int y1 = YSize - r1*si;int x2 = XMide - (r2-1)*co;int y2 = YSize - (r2-1)*si;int xt = XMide - rt*co;int yt = YSize - rt*si;GUI_SetColor(GUI_WHITE);GUI_AA_DrawLine(x1,y1,x2,y2);//绘制刻度线,共4个参数,x1,y1为直线起始坐标,x2,y2为直线终⽌坐标 GUI_SetColor(GUI_GREEN);GUI_SetFont(&GUI_Font8x8);GUI_DispCharAt('0'+ c++,xt - 4,yt - 4);GUI_Delay(SPEED/2);}GUI_Delay(SPEED*3);GUI_ClearRect(0,30,320,240);}void TaskScale(void){_DrawScale();}//主函数void main(void){int i;while(1){GUI_Init();for(i = 0 ;i<1;i++){GUI_Clear();_MainTask();//应⽤程序开始}GUI_Clear();for(i = 0 ;i<1;i++){GUI_Clear();TaskScale();}}}。
第34章emWin(ucgui)窗口管理器实例(一)
第34章窗口管理器实例(一)为了帮助大家更好的理解窗口管理器的回调和消息机制,本期教程专门做了三个相关的例子,帮助大家更好的理解。
34. 1 用户自定义消息类型实例34. 2 桌面窗口回调函数实例34. 3 官方WM_Redraw.c实例34. 4 总结34.1用户自定义消息类型实例这里用上期教程所介绍的自定义消息类型做一个实例。
代码跟上期教程的三个实例类似。
实现源码如下(可以直接将代码复制到模拟器或者开发板上面运行)。
#include <stddef.h>#include "GUI.h"#include "DIALOG.h"#include "WM.h"#include "BUTTON.h"#include "CHECKBOX.h"#include "DROPDOWN.h"#include "EDIT.h"#include "FRAMEWIN.h"#include "LISTBOX.h"#include "MULTIEDIT.h"#include "RADIO.h"#include "SLIDER.h"#include "TEXT.h"#include "PROGBAR.h"#include "SCROLLBAR.h"#include "LISTVIEW.h"#define WM_UPDATE WM_USER + 1(1)/*********************************************************************** static data************************************************************************/GUI_COLOR _acColor[3] = {GUI_BLUE,GUI_RED,GUI_YELLOW};static char ucBackColor;/*********************************************************************** Dialog resource** This table conatins the info required to create the dialog.* It has been created by ucGUIbuilder.*/static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {{ FRAMEWIN_CreateIndirect, "armfly", 0, 0, 0, 800,480,FRAMEWIN_CF_MOVEABLE,0}, { BUTTON_CreateIndirect, "BUTTON0", GUI_ID_BUTTON0, 82, 122,162,37, 0,0},{ BUTTON_CreateIndirect, "BUTTON1", GUI_ID_BUTTON1, 357,123,152,35, 0,0}};/******************************************************************* FunctionName:void PaintDialog(WM_MESSAGE * pMsg)** Function: to initialize the Dialog items**** call this function in _cbCallback --> WM_PAINT*****************************************************************/void PaintDialog(WM_MESSAGE * pMsg){WM_HWIN hWin = pMsg->hWin;GUI_SetBkColor(_acColor[ucBackColor]);GUI_Clear();}/******************************************************************* FunctionName:void InitDialog(WM_MESSAGE * pMsg)** Function: to initialize the Dialog items**** call this function in _cbCallback --> WM_INIT_DIALOG*****************************************************************/void InitDialog(WM_MESSAGE * pMsg){WM_HWIN hWin = pMsg->hWin;////FRAMEWIN//FRAMEWIN_SetFont(hWin,&GUI_Font24B_ASCII);FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);FRAMEWIN_SetTitleHeight(hWin,30);/* 默认颜色取*/ucBackColor = 0;}/*********************************************************************** Dialog callback routine*/static void _cbCallback(WM_MESSAGE * pMsg){int NCode, Id;WM_HWIN hWin = pMsg->hWin;switch (pMsg->MsgId){case WM_UPDATE: (2)ucBackColor++;if (ucBackColor == 3){ucBackColor = 0;}WM_InvalidateWindow(hWin);break;case WM_MOUSEOVER:break;case WM_PAINT:PaintDialog(pMsg);break;case WM_INIT_DIALOG:InitDialog(pMsg);break;case WM_KEY:switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) {case GUI_KEY_ESCAPE:GUI_EndDialog(hWin, 1);break;case GUI_KEY_ENTER:GUI_EndDialog(hWin, 0);break;}break;case WM_NOTIFY_PARENT:Id = WM_GetId(pMsg->hWinSrc);NCode = pMsg->Data.v;switch (Id){case GUI_ID_OK:if(NCode==WM_NOTIFICATION_RELEASED)GUI_EndDialog(hWin, 0);break;case GUI_ID_CANCEL:if(NCode==WM_NOTIFICATION_RELEASED)GUI_EndDialog(hWin, 0);break;case GUI_ID_BUTTON0:switch(NCode){case WM_NOTIFICATION_CLICKED:ucBackColor++;if (ucBackColor == 3){ucBackColor = 0;}WM_InvalidateWindow(hWin); break;case WM_NOTIFICATION_RELEASED:break;case WM_NOTIFICATION_MOVED_OUT:break;}break;case GUI_ID_BUTTON1:switch(NCode){case WM_NOTIFICATION_CLICKED:ucBackColor--;if (ucBackColor < 0){ucBackColor = 2;}WM_InvalidateWindow(hWin);break;case WM_NOTIFICATION_RELEASED:break;case WM_NOTIFICATION_MOVED_OUT:break;}break;}break;default:WM_DefaultProc(pMsg);}}/*********************************************************************** MainTask************************************************************************/void MainTask(void){WM_HWIN hDlg;GUI_Init();WM_SetDesktopColor(GUI_BLUE); /* Automacally update desktop window */WM_SetCreateFlags(WM_CF_MEMDEV); /* Use memory devices on all windows to avoid flicker */ PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);/* 创建一个对话框 */hDlg = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);while (1){WM_SendMessageNoPara(WM_GetClientWindow(hDlg), WM_UPDATE); (3)GUI_Delay(500);}}1.定义一个用户消息WM_UPDATE。
ucGUI触摸支持
ucGUI本身支持键盘,鼠标,触摸屏等外设,并在源码级对其消息进行了响应,为使得触摸屏正常工作,用户除实现触摸屏底层驱动之外,还必需对其相应配置文件的修改和添加一些相关函数。
文件中将宏GUI_SUPPORT_TOUCH概念为1。
文件包括触摸屏矫正时利用的一些宏概念,咱们需要依照目标板的具体配置设置具体的值,实验板2410,其中触摸板和液晶屏都是’’,修改后相应的值如下:#define GUI_TOUCH_AD_LEFT 60 #define GUI_TOUCH_AD_RIGHT 970#define GUI_TOUCH_AD_TOP 50 #define GUI_TOUCH_AD_BOTTOM 980#define GUI_TOUCH_SWAP_XY 1 #define GUI_TOUCH_MIRROR_X 1#define GUI_TOUCH_MIRROR_Y 1理论上来讲,GUI_TOUCH_AD_RIGHT 与GUI_TOUCH_AD_LEFT的取值或为0,或为1024(这是S3C2410内置的AD决定的),二者只取其一,GUI_TOUC_AD_BOTTOM与GUI_TOUCH_AD_TOP的取值一样遵守上述规定,可是在实际操作中往往可不能如此设置,均会依照具体情形灵活处置,进行校准操作,诸如windowsCE等其它嵌入式系统中利用触摸屏时一样也需要进行触摸屏校准操作,触摸屏的校正是在触摸屏底层驱动的基础上实现的,通过点击触摸板上边界点位置,经由串口打印的坐标值判定上述宏的取值。
咱们只取左上角和右下角两点坐标作为校正点,通过量次实验左上角坐标大约为(50,60), 右下角位置相应的值为(970,980), 故而确信相应宏的取值。
余下几个宏试均属于开关量,取值视相应情形而定。
在uCGUI框架基础上再增加一个文件,,该文件中增加四个函数:void GUI_TOUCH_X_ActivateX(void){} void GUI_TOUCH_X_ActivateY(void) {}int GUI_TOUCH_X_MeasureX(void) {} int GUI_TOUCH_X_MeasureY(void){}其中前面两个函数能够不予理会,只需在后面两个函数中返回测量值即可。
VFP常用函数大全
Visual Foxpro 常用函数数值函数:1.绝对值和符号函数格式:ABS(<数值表达式>)SIGN(<数值表达式>)例如:ABS(-5)=5,ABS(4)=4,SIGN(8)=1,SIGN(-3)=-1,SIGN(0)=02.求平方根表达式格式:SQRT(<数值表达式>)例如:SQRT(16)=4,它与开二分之一次方等同。
3.圆周率函数格式:PI()4.求整数函数格式:INT(<数值表达式>)返回数值表达式的整数部分CEILING(<数值表达式>)返回大于或等于表达式的最小整数FLOOR(<数值表达式>)返回小于或等于表达式的最大整数例如:INT(5.8)=5.8,INT(-7.8)=-7,CEILING(6.4)=7,CEILING(-5.9)=-5FLOOR(9.9)=95.四舍五入函数格式:ROUND(<数值表达式1>,<数值表达式2>)功能:返回制定表达式在制定位置四舍五入的结果例如:ROUND(345.345,2)=345.35,ROUND(345.345,1)=345.3,ROUND(345.345,0)=345,ROUND(345.345,-1)=3506.求余函数格式:MOD(<数值表达式1>,<数值表达式2>)例如:MOD(10,3)=1 MOD(10,-3)=-2 MOD(-10,3)=2 MOD(-10,-3)=-1求余数的规律:1.首先按照两数的绝对值求余2.表达式1的绝对值大于表达式2的绝对值,则余数为表达式1的值3.余数取表达式1的正负号4.若两数异好号,余数在加上表达式2的值为最终的结果7. 求最大值和最小值函数MAX(数值表达式列表)MIN (数值表达式列表)例如:MAX(2,3,5)=5 MAX(‘2’,’12’,’05’)=2MAX(‘汽车’,’飞机’,’轮船’)字符串比较的规律:字符串比较首先比较第一个字母,如果有结果那就不用在进行比较了。
ucgui显示数值
ucGUI第二篇:Displaying Values(显示数值)说明:我的硬件平台STM32F103ZET6,开发软件是KEIL V4.12 ,OS系统和GUI的版本分别是uCOS-II V2.86,ucGUI V3.94。
数值的显示部分也比较的简单些,总体来说有几点要注意,我下面就把要注意的问题说说。
(-)十进制数的显示GUI_DispDec(),这个要注意的是首位不能是0,是0的话显示会出现错误。
显示负数的话,负号也要算在No. of digits里面,切记,要不也会出错。
设置的No. of digits比实际要显示的字符串大的话,前面会补0。
设置的No. of digits比实际要显示的字符串小的话,会出现错位。
GUI_DispDecAt()这个的显示类似上面,只是多了个可以设置显示的坐标。
GUI_DispDecMin()不需要指定长度,自动的用最少的字符显示,如果需要对其方式且显示的个数不一样的话,这个方式不太合适。
这个的首位也不可以是0,是0的话也会出现错位。
GUI_DispDecShift()首位也不可以是0。
负号和小数点都要算在No. of digits,最大支持9位。
No. of digits设置的大了的话前面要补0。
GUI_DispSDec()类似于GUI_DispDec(),不支持首位是0,不管是正的,还是负的,都要显示负号,而且这个正负号也要算在No. of digits里面。
GUI_DispSDecShift()这个是GUI_DispSDec()和GUI_DispDecShift()的合并版,只要注意No. of digits里面要包括正号负号还有小数点。
总结:用时一定要保证自己设置的No. of digits要大于等于自己实际要显示的。
多了的话前面会补零,少了的话就会出错的,显示一堆9.(二)十六进制和二进制GUI_DispBin()GUI_DispBinAt()GUI_DispHex()GUI_DispHexAt()这四个差不多,第一个最大支持32位的显示,后面三个中最大支持16位,No. of digits 设置的多了的话前面会补零,少了的话有几个显示几个。