一.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、miniGUI
2.C/S模式,采用一个XServer,所有的显示都以客户端的形式请求服务,如Nano-X
GUI在嵌入式系统或实时系统中的地位
越来越多的市场需求数据显示,包括 PDA、娱乐消费电子、机顶盒、DVD等影音设备、WAP 手机等高端电子产品得到广泛应用,原先仅在军工、工业控制等领域中使用的GUI图形系统,受到越来越多的关注。
对于轻量级 GUI 的系统而言,对 GUI 的要求相对较低,如传统51类型单片机这类系统一般不希望建立在庞大累赘的、非常消耗系统资源的操作系统和 GUI 之上,如 Windows 或 X Window。目前此类系统都直接使用原有编程手段,采用比较简单的手法实现 GUI。对于太过庞大和臃肿的GUI系统而言,μc/GUI这类可运用于此类资源较紧张的轻型 GUI 的需求更加突出
uc/GUI简介
μc/GUI是美国Micrium公司出品的一款针对嵌入式系统的优秀图形软件。它是为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器而设计的图形用户接口,它适用单任务或是多任务系统环境。并适用于任意LCD控制器和 CPU下任何尺寸的真实显示或虚拟显示.架构基于模块化设计,由不同的模块中的不同层组成。由一个LCD驱动层来包含所有对LCD的具体图形操作, UCGUI可以在任何的CPU上运行, 因为它是100%的标准C代码编写的. 模块包括液晶驱动模块,内存设备模块,窗口系统模块,窗口控件模块,反锯齿模块和触摸屏及外围模块。其主要特性包括丰富图形库,多窗口、多任务机制,窗口管理及丰富窗口控件类(按钮、检验框、单/多行编辑框、列表框、进度条、菜单等),多字符集和多字体支持,多种常见图像文件支持,鼠标、触摸屏支持,灵活自由配制等特性,ucGUI能够适应大多数的使用黑白或彩色LCD的应用, 它提供非常好的允许处理灰度的颜色管理.还提供一个可扩展的2D图形库及占用极少RAM的窗口管理体系. 在μc/GUI的最初典型配制可包括是否需要操作系统支持,是否需要内存设备支持,是否需要窗口支持,是否需要抗锯齿支持等众多选项,这对于GUI的定制和GUI的体积是非常重要的。小型系统需求RAM100bytes,堆栈500bytes,ROM10kbytes,完全满足资源非常紧张的系统之中.
μc/GUI和其他图形系统的比较
(1) μc/GUI优势在于其体积小,配制性强,运用领域非常之广泛。相对于众多嵌入式图形系统,如MicroWindows/NanoX, OpenGUI, Qt/Embedded, MiniGUI等,只要满足RAM100bytes,堆栈500bytes,ROM10kbytes的小型系统中都可以运行μc/GUI,而这个需求是其他图形系统所不及的,可以广泛运用到国内已经运用非常成熟的单片机系统内,增强系统性能。在资源丰富的大型系统中,也只需要RAM2-6Kb,堆栈 1200bytes,ROM30-60Kb就可以满足mc/GUI的各种功能。对比于其他图形系统最少几百K,动辄上M的系统而言是非常有优势的。其众多的配制,满足不同需求用户需要,方便灵活小巧,实用性大大增强。
(2) 平台的广泛性,移植方便。由于μc/GUI是100%C编写,适应绝大多数软硬平台,其适应性非常强,相对于众多具有软硬件针对性的图形系统而言,结构划分和模块划分非常清晰,分设专门的LCD驱动模块,移植简单方便。代码量相对较小,易操作可扩展性强,方便用户定制和自主更新完善满足个性需求。
S5U1C330G1S简介
S5U1C330G1S是为S1C33系列提供的图形处理中间件,可以基于S1C33芯片完成二维图形和GUI处理。所有这些功能以库函数形式提供,可以连接到目标程序中;而且上层提供的功能都有C编程接口,极大地方便了程序员。此外,还提供图形ROM数据创建工具——一套PC软件工具。
该中间件特别适合于开发蜂窝电话、PDA、电子文具和玩具等。它具有以下特点:
l支持带内置LCD控制器的S1C33系列MCU
l提供基本的画图功能,包括点、直线、圆、椭圆、矩形、弧以及填充等;
l显示和保存图象
l正文显示
l在GUI接口功能时,必须使用S5U1C330G1S库
l图形ROM数据生成工具
1.硬件资源
要使用S5U1C330G1S,需要一些基本的硬件支持。一般来讲,至少要有S1C33芯片、外部存储器和LCD等。另外,在S5U1C330G1S中,还要使用S1C33芯片上的一个16位可编程定时器信道。
GUI系统还应该包括以下硬件资源:
(1)K50~K54端口以及所有相关的寄存器
(2)16位可编程定时器(定时器3)以及相关寄存器
(3)操作时钟:对高速(OSC3)时钟频率,输入20MHz;使用PPL时,则加倍成40MHz;总线时钟频率为20MHz;对内置LCD控制器的时钟(CLK1),OSC3(20MHz)被设置成1/3周期以供使用。
(4)存储器和堆栈如下表
对象
代码(ROM)/KB
BSS(RAM)
堆栈
GPC相关功能
15
500字节
170字节
GUI相关功能
4.2
23
250字节
1字节字型
3
—
—
2字节字型
164
—
—
显示驱动
1
16字节
—
2.软件资源
S5U1C330G1S库是位于S1C33硬件和用户程序之间一个编程中间件,其主要目标是实现硬件之上的基本画图、图像显示和文本显示功能。通过调入以 C程序源码提供的高层函数或者链接这些顶层函数到用户程序,可以方便地进行图形处理,并不需要直接由用户程序调用其它的JPEG33基本库函数。
使用S5U1C330G1S开发图形时的应用程序的过程主要包括以下几步:
l使用S5U1C330G1S工具创建图像的ROM数据,并将其转换成C源程序
l创建用户应用:利用S5U1C330G1S库提供的GUI和图形函数进行图形处理,上一步创建的数据源文件可以包含在用户源文件中
l编译源程序,生成目标文件
l链接目标文件与S5U1C330G1S库,产生可执行文件
3.编程接口
为了便于应用编程,S5U1C330G1S提供了丰富的编程接口:一组srf33库格式的图像处理函数库。在使用前,该库必须链接到目标程序,通过目标程序调用来实时完成以下功能:
l基本画图功能:点、直线、圆、椭圆、矩形、弧以及填充
l显示与保存图形功能
l文本显示功能:既支持单字节字符,也支持双字节字符
lGUI功能:窗口、弹出窗口、控制按钮和图像按钮等。
l键盘与手表事件功能
二.ucGUI结构分析
1.ucGUI结构层次
核心层提供基本图形操作
应用程序接口
WM提供窗体管理接口和窗体消息机制,图形接口,建立在核心层之上
核心层建立在GAL之上,以进行实际图形操作,IAL接口提供用户输入接口
2.ucGUI的代码结构
Application中存放应用程序,Config中存放配置头文件,GUI目录下存放系统代码,Core存放GUI核心代码,Font存放字体文件,Widget存放一些窗体控件,WM存放窗口管理器代码,LCDDriver存放LCD驱动程序,其他部分为一些2D函数,包括颜色,管理系统和抗锯齿等
3.ucGUI的特性
ucGUI的设计目标是为使用LCD作为图形显示装置的应用提供高效的与LCD控制器独立及 处理器独立的图形用户接口. 它适合于单任务环境及多任务环境, 如私用的操作系统或是商业的RTOS(实时操作系统). UCGUI以C源码形式提供, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示.它包含以下特性:
(1)一般特性
适用任何8/16/32位CPU, 只要有相对应的标准C编译器;任何的控制器的LCD显示器(单色,灰度,颜色), 只要有适合的LCD驱动可用;在小模式显示时无须LCD控制器;所有接口支持使用宏进行配制;显示尺寸可定制;字符和位图可在LCD显示器上的任意起点显示,并不仅局限于偶数对齐的地址起点;程序在大小和速度上都进行了优化; 编译时允许进行不同的优化;对于缓慢一些的LCD控制器, LCD显存可以映射到内存当中, 从而减少访问次数到最小并达到更高的显示速度;清晰的设计架构;支持虚拟显示, 虚拟显示可以比实际尺寸大(即放大).
(2)图形库
支持不同颜色深度的位图;提供可用的位图转换工具;图形运算时绝对不含浮点运算; 快速画点/线(不含浮点运算);高速画圆及多边形;多种画图模式;按照不同的模式提供了色彩值到索引值之间的转换,实现调色板功能; 支持多级灰度,支持多种彩色模式,111,222,332,565等
(3)字体集
使用GUI_FONT来描述字体显示,支持unicode,每一种字符的显示图形,字符信息、编码范围等,字符显示的大小;为基础应用提供多种不同字体:4*6, 6*8, 6*9,8*8, 8*9, 8*16, 8*17, 8*18, 24*32, 以及8, 10, 13, 16等几种高度(象素单位)的均衡字体(proportional fonts);可以方便的加入及链接进自定义字体;只有应用程序中用到的字体被实际链接进最后的执行映象文件中, 因此保证占用最小数量的ROM;提供可用的字体转换工具.任何宿主系统(如微软windows系统)上的可用字体均可以经转换后使用.
(4)字符串/数值输出
支持数值的任何字体下的十进制/二进制/十六制显示;支持数值的任何字体下的十进制/二进制/十六制编辑输入.
(5)窗体管理器
齐全的窗口管理, 包括剪切, 在窗体客户区外;窗体可以移动及改变大小;支持窗口回调函数(可选功能);窗体占用最低RAM(每个窗体占用20个字节);这个模块对ucGUI来说并非必须,但用其可以方便地构建一个事件驱动系统
ucGUI的窗体消息机制与操作系统的消息机制没有关系,WM负责接收外部事件并调用相应的回调函数处理
(6)可选的类似PC机的窗体控件
可用的窗体控件(窗体对象, 也称作控件), 操作简便而且容易使用;控件本来就是一个窗体,所以使用空间必须使用WM,控件一般作为子窗口被创建,控件的特点在其
Paint和CallBack函数中体现出来
(7)触摸屏及鼠标支持
对于窗体控件如按钮, UCGUI提供触摸屏及鼠标支持.
(8)PC下的工具
模拟器及查看器;位图转器工具;字体转换工具.
(9)ucGUI多任务环境下的使用
多任务环境下以单任务运行;多任务环境下以多任务运行:以一个任务专门用于更新显示,一般界面最好只使用一个任务(单窗口显示),如果需要启动多任务,需要配置GUI
ucGUI多任务内核接口:ucGUI主要使用内核的资源保护功能,内核接口函数如下:
(10)输入设备抽象层IAL
基本用户输入设备:键盘(获取键值)、鼠标、触摸屏(获取坐标信息)。
ucGUI并非使用设备提供的接口函数,而是提供函数给驱动程序调用
鼠标和触摸屏属于光标指针输入设备
键盘驱动调用接口
(11)图形设备抽象层GAL
ucGUI需要被提供一个硬件驱动函数集,在系统中称为LCD_L0_XXX函数
硬件初始化及显示控制
物理绘制函数
设置函数
三.ucGUI移植过程
新建一个文件目录作为自己的工作目录,将前面的Start 目录下的Application 和Config以及GUI 目录拷贝到工作目录下,从前面的实验源代码中拷贝vector.c 和boot.c 两个文件到Application 目录中,包括相应的头文件。在GUI/LCDDriver 目录下添加一个LCD13XX.C 驱动文件,其中提供的函数参见PPT 中指出的驱动接口函数,另外从Sample/GUI_X 目录下拷贝GUI_X.c 文件到Application 下
各文件夹内容简介:
Application:应用程序涉及到的文件,触摸屏驱动程序,GUI和ucOS、TouchPanel的挂接程序,还有定时程序。
Config:配置文件。GUICONF.h---基本的GUI 预定义控制.GUITouchConf.h----关于触屏的控制预定义.LCDConf.h---有关LCD 液晶显示的参数控制.
Demo:存放cmd文件和生成的目标程序
Gui:包括七个文件夹:ConvertColor用于颜色转换,ConvertMono用于单色转换,Core囊括了GUI所需的大多数文件,Font为字体定义,LCDDriver里用到的LCD驱动是LCD13XX.c,Widget定义了控件的行为,WM是窗口管理器的相关文件
S1C33209:包括vector.c和boot.c等文件,这些文件是处理器工作时所必需的。
移植说明
(1) 首先定义GUIConf.h和LCDConf.h这两个文件,前者是μc/GUI功能模块和动态存储空间(用于内存设备和窗口对象)大小,默认字体设置等基本GUI预定义控制的定义。后者LCDConf.h为LCD大小,控制器类别,总线宽度,颜色选取等LCD参数控制文件。
GUI/CORE/LCD_ConfDefaults.h文件内可以找到所有囊括LCD 配制默认选项,包括LCD屏个数,控制器个数,调色板,屏幕反向设置等众多配制选项。如果配备触摸屏可以通过GUITouchConf.h进行配制,根据触摸屏及其控制芯片编制以下几个函数
void TOUCH_X_ActivateX (void);// 准备Y轴数据测量
void TOUCH_X_ActivateY (void);// 准备X轴数据测量
int TOUCH_X_MeasureX(void); // 根据AD转换结果返回X的值
int TOUCH_X_MeasureY(void); // 根据AD转换结果返回Y的值
以上几个函数在GUI_TOUCH_Exec()会被调用。
(2) 对于LCD自带控制器类别的液晶屏,通过LCDConf.h中的总线接口和寄存器接口进行硬件接口的配制和定义。对于片上集成LCD控制器平台而言,通过对片内LCD控制器寄存器的设置来配制LCD接口信号。在一般的LCD中需要配制的LCD接口信号包括VFRAME帧同步信号,VLINE线同步脉冲信号,VCLK象素时钟信号,VM信号和数据位不等的象素点数据输出信号。
(3) LCD驱动编程的实质是液晶屏上的点对应的显存编程,最底层调用函数为画点函数,用户可根据自身平台情况根据总线接口和寄存器接口或者LCD控制器寄存器进行操作。_SetPixel(),_GetPixel(),XorPixel()为最底层直接对显存操作函数。ucGUI提供部分控制器驱动,本实验中文件为GUI/LCDDriver/LCD13XX.c,因为我们所用的是LCD1376控制器。核心函数为LCD_Write(). _SetPixel()调用LCD_Write()写显存。
(4) 在SampleGUI_X文件夹内包括有与硬件联系紧密的文件,包括GUI_X.c,GUI_X_embOS.c, GUI_X_uCOS.c等文件, GUI_X.c包括大部分与硬件的关联函数,如定时器的初始化和触摸屏相关函数。mc/GUI与操作系统挂接的核心是定时器的设置和挂接。μc/GUI是通过延时函数GUI_Delay()调用GUI_X_Delay,再调用GUI_Exec()处理窗口部件中的回调函数进行重绘。在任何一款嵌入式操作系统中都需要定时器的心脏跳动作用,支持OS的μc/GUI可以通过定时器的设置达到嵌入式操作系统和图形系统的实时和同步操作。在 GUI_X_uCos.c中通过μc/os中的延时程序同μc/GUI挂接实现整合。
(5) 经过移植之后,GUI应用程序开发通过μc/GUI而变得非常容易,在调用GUI_Init()后,用户可以根据需要正确配制μc/GUI后,可使用其强大的库函数和丰富的GUI资源进行编程。在GUI编程过程中,可以打开抗锯齿功能减小图形失真,得到高质量的图形和字体效果。采用内存设备能有效克服闪烁现象,获得更快的显示速度,但它和抗锯齿功能一样需要额外的内存开销。
四.基于ucGUI的应用程序编写过程
本应用程序实现在触摸屏上利用按钮来移动一个位图的简单功能。在文件DIALOG_SliderColor.c中是主要的程序,这是基于原来该文件中的内容改写的。其内容及其说明如下:
#include "button.h"
#include
#include "GUI.H"
#include "DIALOG.h"
extern const GUI_BITMAP bm62;//使用外部位图
int xx,yy;
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "yangguisen", 0, 240, 40, 70, 190, 0, 0 },
//创建窗体
{ BUTTON_CreateIndirect,"up",GUI_ID_up,7, 10,50, 30 },
{ BUTTON_CreateIndirect,"down", GUI_ID_down,7, 50,50, 30 },
{ BUTTON_CreateIndirect,"left", GUI_ID_left,7, 90,50,30 },
{ BUTTON_CreateIndirect,"right", GUI_ID_right, 7, 130, 50, 30 }
//创建4个按钮上、下、左、右,用来控制位图的移动
static void _cbCallback(WM_MESSAGE * pMsg) {
int NCode, Id;
WM_HWIN hListBox;
WM_HWIN hWin = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
SCROLLBAR_CreateAttached(hListBox, SCROLLBAR_CF_VERTICAL);
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 (NCode) {
case WM_NOTIFICATION_RELEASED:
if (Id == GUI_ID_up) {
if(yy>=40){
GUI_ClearRect(xx, yy, 240, 240);
yy=yy-10;GUI_DrawBitmap(&bm62,xx,yy);}
}
if (Id == GUI_ID_down) {
if(yy<=190){
GUI_ClearRect(xx, yy, 240, 240);
yy=yy 10;GUI_DrawBitmap(&bm62,xx,yy);}
}
if (Id == GUI_ID_left) {
if(xx>=10){
GUI_ClearRect(xx, yy, 240, 240);
xx=xx-10;GUI_DrawBitmap(&bm62,xx,yy);}
}
if (Id == GUI_ID_right) {
if(xx<=190){
GUI_ClearRect(xx, yy, 240, 240);
xx=xx 10;GUI_DrawBitmap(&bm62,xx,yy);}
if(xx==120&&yy==120){GUI_ClearRect(xx, yy, 240, 30); GUI_DispStringHCenterAt("Welcome to USTC!", 160, 5);}
}
break;
}
break;
default:
WM_DefaultProc(pMsg);
}
}
void MainTask(void) {
xx=40;
yy=40;
GUI_Init();
GUI_SetBkColor(GUI_BLUE);
GUI_Clear();
GUI_SetColor(GUI_WHITE);
GUI_SetFont(&GUI_Font24_ASCII);
GUI_DispStringHCenterAt("where are you going?", 160, 5);
GUI_DispStringHCenterAt("USTC", 120, 120);
GUI_DrawBitmapMag(&bm62,xx,yy,1,1);
WM_SetCreateFlags(WM_CF_MEMDEV);
GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
}
控制流从appmain.c文件进入,MainTask(void)通过以下路径得到执行:main()àTaskStart()àTaskGui()àMainTask(void)