首页资源分类嵌入式系统 > uC GUI3.32 入门教程(详细)

uC GUI3.32 入门教程(详细)

已有 445110个资源

下载专区

上传者其他资源

    文档信息举报收藏

    标    签:ucgui

    分    享:

    文档简介

    uC GUI3.32  入门教程

    文档预览

    源地址:http://bbs.ednchina.com/?url=http://bbs.ednchina.com/ShowTopic.aspx?id=18675 看贴要回帖,做人要厚道! 这是前些日子在使用 uc/GUI 的时候即下来的一些东西原来发布在 EDACN 的 bbs 上面。现在不知道沉到 哪里去了。现在把它重新整理发布在这里。随后在明年过年的时候把后续的几个高级主题整理出来。 下面开始我的笔记! 有兴趣的兄弟们可以来看看。 step1. 下载 uC/GUI 的代码。(废话没有源代码移植个鸟) 我下载的时 uC/GUI3.32 这是能得到的源代码中最全的一个版本。 看看里面都有些什么东西。由于这里的发间大小的限制的问题不能上传源代码。很是郁闷。有需要的同志 可以联系我。Email:william7447@gmail.com 首先看看所有名叫 Simulation 的东西这是 uC/GUI 在 VC 中仿真的 VC 工程,他的仿真功能非常的实用可 以在没有具体硬件的情况下先行开发软件,而丝毫不影响软件的兼容性。但是有一个问题比较郁闷,就是 速度的问题。大家知道嵌入式系统的 CPU 运算能力有限,而电脑的 cpu.........我的整个项目的 gui 是在电 脑上完成的。拿到目标系统上面编译.......通过。 经过紧张的下载..................... 运行..........显示出了第一个画面,无比的兴奋。但测试发现极其郁闷而几乎无法解决的问题......目标系统的 处理能力只有 100mips 而我的电脑的 cpu 是 P4 3.0。速度的差别太大了。解决这个问题几乎成了我后半段 工作的主题。 GUI 文件夹存放全部 uC/GUI 源代码的地方 看看它的属性有多达 390 个文件,全部是.c 和.h。可以看出 GUI 系统是一个庞大复杂的东西。我在调试系 统的时候跟踪过完整的消息循环再进入了 60 多个子函数调用后还没有看到希望,就彻底的放弃了跟踪的想 法。下来会具体说明这里面都有些什么东西。 config 文件夹 uC/GUI 的配置文件夹。里面存放的是 uC/GUI 的配置头文件。改动里面的相应的就可以改动 uC/GUI 的配置。 这个 GUI 功能十分强大。我也在探索之中。 这几天刚刚入门,只能说我自己的移植过程,以后陆续添上它的使用。有什么不对的地方大家请指出来。 uC/GUI3.32 应用笔记连载之二 uC/GUI 移植之准备工作。 先来看看吧 uC/GUI 移植到 NIOS II 都要准备些什么东西。 首先就是要了解 uC/GUI 的源代码包括了一些什么东西。 前面提到了这个 gui 有两个文件夹一个 GUI 存放 gui 的核心文件,一个 config 为 gui 提供配置信息。 先看 core 里面有什么东西。 GUI\AntiAlias 抗锯齿支持,看上去挺牛的。 根据对抗锯齿的使用发现,uC/GUI 的抗锯齿的效果好坏主要取决于系统的发色数,即系统的色彩表现能力, 例如系统仅有灰度显示能力的时候,uC/GUI 在对一条直线进行处理的时候它是在直线的两侧添加颜色较浅 的点来实现抗锯齿的。效果十分明显。 GUI\ConvertMono (b/w)和灰度显示的色彩转换支持。 GUI\ConvertColor 彩色显示的色彩转换支持 实际上就是色彩空间变换,为什么需要色彩转换呢? 在 gui 内部定义了一套调色板及色彩的数据格式,但是有的控制器的色彩数据格式和 gui 内部定义的并不 一样,甚至色彩的数量(即 lcd 的发色数)也不同,这样就需要将两种不同的数据格式进行转换。这样才 能在 lcd 上看到正常的颜色。 GUI\Core µC/GUI 核心文件,提供了 GUI 基本的功能,比如画点,画线,为图之类的东西。什么窗口,窗 口控件都是基于这些基本功能的。 GUI\Font 不用多说了 GUI\LCDDriver LCD 控制器。下面会说这个东西。 GUI\MemDev Memory device 支持。这个东西可用在很多情况下,但最主要的功能是防止在项目重叠时, 防止屏幕的闪烁。如果没有 Memory device 的支持数据会直接写到控制器中去,这样当进行各种屏幕跟新 的时候就会出现闪烁现象。如果有 Memory device 支持,就会避免这种现象。具体的还没有测试,不过看 说明是蛮牛的。关于这个东西会有一个较详细的测试。 GUI\Touch Touch-panel 支持。虽然说是支持,甚至连鼠标都支持,但是底层驱动程序的四个函数是空的 需要用户自己添加内容,我们使用 mxb7843 这个四线电阻触摸屏控制器。班子还没有做好,做好就测试。 GUI\Widget 窗体控件库,功能强大,提供诸如按钮,文本框之类的复杂的功能。 GUI\WM 窗口库。 widget wm 配合 memory device 使用功能强大。 下面看看 CONFIG 文件夹 三个文件: GUIConf.h GUITouchConf.h LCDConf.h 看名字也知道干什么的了。 下面一个一个说。 #ifndef GUICONF_H #define GUICONF_H #define GUI_OS (1) /* 多任务支持,如果使用 rtos 就打开这个选项,除了自家的 ucos, 别的 rtos 也支持*/ #define GUI_SUPPORT_TOUCH (1) /* 支持触摸屏*/ #define GUI_SUPPORT_UNICODE (1) /*unicode 字符串支持,能显示中文的哦,只要能把字库放 进来,现在的问题我把字库放不进来,文件太大了,编译器限制,郁闷!*/ #define GUI_DEFAULT_FONT #define GUI_ALLOC_SIZE &GUI_Font6x8/*默认字体*/ 12500 /* WM 和 memory devices 分配的动态内存*/ /********************************************************************* * * Configuration of available packages */ #define GUI_WINSUPPORT #define GUI_SUPPORT_MEMDEV #define GUI_SUPPORT_AA 这三个不用说了吧! #endif /* Avoid multiple inclusion */ 1 /* Window manager package available */ 1 /* Memory devices available */ 1 /* Anti aliasing available */ GUITouchConf.h 这个文件........由于硬件不到位没有深入研究触摸这块还不太理解,日后补上。 LCDConf.h 这个文件比较特别,随着控制器的不同,内容而不同。 如果针对的是硬件控制器,就会在这个文件里面定义控制器的基地址,所有的寄存器,显示内存的地址镜 像关系,等等一系列硬件控制器的特征信息。当然了还会定义 lcd 的尺寸,调色板,等一些重要的信息。 还有救治针对不同的 lcd 的设置,配置不同的控制器初始化代码。 还有一种就是 MEM 控制器。就是没有硬件控制器在内存里面申请一个和 LCD 物理象素点一一对应的内存 区域作为显示缓冲区,然后由用户想办法把数据送到 LCD 上去。他给的例子里面是用定时中断来模拟 LCD 控制的控制时序,将数据流送到 LCD 上。在该模式下如果是一个很小 lcd 该方法很好节省了硬件成本。但 是大量占用 CPU 刷新率低。如果 lcd 象素很高,那就是个问题了。但是在某些应用中不得不使用这种方式。 在我的工程里面就使用了这种方式。 我的屏 640*480*3bit。 这里有关硬件的控制器是一个大问题,即底层的驱动程序怎么办?uC/GUI 提供了很多的芯片的驱动程序, 但是如果选用的芯片没有怎么办?或者屏的参数比较奇怪怎么办?比如我用的屏 640*480*3bit,就是 8 色 的那种,一般的屏都是 16 色。我打算在过年的时候开一个有关驱动程序的专题,讨论这些问题。还有驱动 程序的效率对整个 gui 的效率影响很大。 准备就这么多该说说移植了。 uC/GUI3.32 应用笔记连载之三 该移植了! 首先弄个 NIOS II 系统。 然后打开 NIOS II IDE 创建一个工程。 什么都可以!我使用的 Hello World 这个工程。使用例子的好处省心。 然后找到这个工程的在硬盘中的物理位置,将下载的代码中的两个文件夹 GUI 和 config 拷贝进去该软件工 程的目录里面。 由于前一段的工作是基于 Altera Fpga 的用的就是 NIOS II 处理器,后面我会专门针对 arm 来讨论相关的 问题,最近的项目是基于 arm9 的。 图中就是 copy 好的目录。 然后回到 NIOS II IDE refresh 工程就能看到 ide 自动将这两个文件加添加进了工程,还有里面所有的文件。 但是不是所有的文件都是有用的,nios II 的编译器会把所有的文件编译,这样在链接的时候就出问题了, 因为有的文件是针对不同的配置写的。但是所有的都被编译了,这样子就导致大量的链接错误,无数重复 定义。这就需要将无用的文件从工程中清除。一个地方就是 LCDDrivers 由于底层的绘图函数是在 drivers 里面定义的所以有多少个 drivers 就会有多少个同样名称的函数。这里就需要将无用的 driver 清除。还有一 个地方就是 gui/core 里面 GUI_DrawBMP.c 和 GUI_DrawBitmap.c 着两个文件内容一模一样,一字不差! 所以要清除一个!还有一个重要问题是文件的包含路径。nios ide 不是自动添加文件包含路径的,用惯了 ads 的人特不习惯。而且在 5.1 包含路径设置位置比较难找!在这里添加四个路径: E:\FPGA\Lcd\software\hello_world_0\Config E:\FPGA\Lcd\software\hello_world_0\gui\Core E:\FPGA\Lcd\software\hello_world_0\gui\WM E:\FPGA\Lcd\software\hello_world_0\gui\Widget 还有就是要在系统库中加上 ucos。uC/GUIi 默认打开多任务支持。 包含好了路径就可以编译了。 但是提示还有链接错误! 非常郁闷,怎么看也看不出来怎么回事。提示一个字体未定义! 关键还是默认字体! 经过仔细察看发现一个问题!!!!大家看看图就明白了! NIOS II IDE 使用 java 开发的,java 大小写敏感!这点还是 Windows 作的好。 还有一个问题就是优化级别的问题,我发现在 NIOS II 系统里面 most 级别的优化和 none 的优化(就是不 优化)执行速度能差 2~3 倍。特别是一些计算密集型的代码例如:crc 和 gui 应用。 这回编译就没有错误了!GUI 初步移植成功,下来测试一下!由于没有硬件支持只能看看软件的。调试工 程用内存查看器,就看到了 uC/GUI 的运行的结果。 执行下面的语句: int main() { LCD_Part = 0; alt_irq_register ( LCM_0_IRQ, (void*)0, LCD_isr); alt_irq_enable(LCM_0_IRQ); GUI_Init(); GUI_DispChar('A'); /*显示一个 A*/ printf("Hello from Nios II!\n"); while(1) { } return 0; } 我用的是 MEMC 驱动程序,即把 GUI 执行的结果保存到内存中。这样子才有了直接察看内存来看结果 BT 方法。 可以在内存查看器中看到数据的变化(由于数据量巨大,只列出头几列的数据) 1f f0 00 ... e0 0e 00 ... e0 0e 00 .. ff fe 00 ... e0 0e 00 .. e0 0e 00 .. e0 0e 00 .. 00 00 00 ... 转化为二进制 000111111111000000 111000000000111000 111000000000111000 111111111111111000 111000000000111000 111000000000111000 111000000000111000 000000000000000000 我的屏是 RGB 三色屏共有 8 种颜色,0 表示该点灭,1 表示亮。3 位表示一个彩色的象素点。能看出来由 1 组成了一个 A 吗? GUI 初步抑制成功,下面将探索它的各种功能。(这部分着在摸索,每天弄一点,跟新可能会很慢!) 使用 MEMC 是因为这种方式的移植最简单根本不牵扯硬件,而且因为项目经费紧张,不可能买一个独立的 控制器,特别是体现不出来 FPGA 的优势。这里的控制器是一个自己写的小东西,实现的对 LCD 的控制, 这部分正在测试,测试好了也会拿出来给大家共享的。 下来的几天主要测试 uC/GUI 的复杂应用。包括 widget, wm 这些东西。 uC/GUI3.32 应用笔记连载之四 uC/GUI Simulation 的应用 uC/GUI 提供了一格功能是强大的工具,即 Simulation 工具他可以在 windows 环境下模拟 uC/GUI 的运行 结果,为 GUI 应用程序的开发体供了极大的方便,在模拟器上开发 GUI 应用程序代码可以几乎无修改的直 接应用于目标硬件。 这个模拟器的原理是 GUI 程序运行后产生一个实时更新的 BMP 图片然后由 gui 模拟程序显示出来。这个 功能作得太好了,这样子 gui 程序的开发简直是无敌了。 在下载的 uC/GUI 源代码中,解压后就能看到一个名叫 Simulation 的 VC6Workspace 和 project。 在顶楼的图中可以清楚地看到这两个文件。这是 uC/GUI 的开发人员帮我们做好的。直接打开这个工程就 可以在 VC6 中开发 GUI 应用程序,uC/GUI 高度抽象,应用程序与底层很好的分离,这样为 GUI 应用程序 的开发提供了极大的方便。 下面打开这工程看看里面有什么东西。我使用的 VS.Net。没有什么区别,个人认为 VS.Net 的功能较 VC6 强大许多。是一个优秀的集成开发环境。 打开工程后我们看看里面都有些什么东西。 config 和 gui 文件加我们前面都说过了,里面放的就是 Gui 的配置文件和 gui 的源代码。 这里面多了几个文件夹。 Application 文件夹,用户存放应用程序文件的地方。 Simulation 文件夹模拟器提供初始化和一些配置信息,我们根本不用改动这些东西。 System 文件夹,大家知道每个 C 程序都有一个 main 函数,这里面就放了这一个东西。 还有一个地方,就是 LCD_Driver 这个文件夹里面放的是 LCDWIN.c 这样无论你怎么修改 GUI 的配置,模 拟器都会使用这个驱动程序来实现 GUI 程序运行结果的正确的显示。 LCDWin.c 就是基于 windows 模拟器的驱动程序,就是通过这个驱动生成模拟器里显示的 bmp 图片。 弄清楚这些东西,就可以开始 uC/GUI 编程了。 打开 MainTask.c 这个文件我们就在这里面编写我们的 GUI 应用程序。 #include "GUI.h" extern const GUI_BITMAP bmMicriumLogo; extern const GUI_BITMAP bmMicriumLogo_1bpp; 下面是自带的一段示例代码。 我们来看看她都干了些什么东西。 /* ******************************************************************* * * main() * ******************************************************************* */ void MainTask(void) { int Cnt =0; int i,YPos; int LCDXSize = LCD_GET_XSIZE(); int LCDYSize = LCD_GET_YSIZE(); /*取得 lcd 物理尺寸,这个参数是在 lcdconf.h 里面定义的*/ const GUI_BITMAP *pBitmap; /*一个指向预显示的位图的指针,在这里位图是在.c 文件里面存储的 ps:.c 的体积大的吹牛*/ GUI_Init(); /*初始化 GUI,这谁痘看得出来*/ /*这里面除了初始了在 guiconf.h 里面定义的时用的 GUI 的所 有功能,包括 widget,wm 等功能的初始化,当然还有 lcd 的控制器的初始化*/ GUI_SetBkColor(GUI_RED); GUI_Clear(); /*设置背景颜色为 RED,其结果如图*//* /*说明一下这个模拟器的窗口,最大的那个窗口显示的就是 GUI 程序的运行结果。标题里显示的是当前 LCD 的配置参数,colors 显示的当前 gui 系统能显示的所有的颜色,即调色板。log 是 gui 的日志,这个功能会 在后面说明*/ GUI_Delay(1000); /*延迟 1000 个时钟节拍,这里我们的 gui 是应用在 ucos rtos 上面,这里的时钟节拍 就是 ucos 的时钟节拍*/ GUI_SetBkColor(GUI_BLUE); /*背景设为 BLUE*/ GUI_Clear(); /*清除当前的 window,没有窗口就清理 整个屏幕*/ GUI_Delay(1000); GUI_SetColor(GUI_WHITE); for (i="0"; i<1000; i+=10) { GUI_DrawHLine(i,0,100); GUI_DispStringAt("Line ",0,i); GUI_DispDecMin(i); } /*这段代码的功能就是每隔 10 行显示文字 line 和一条直线。*/ GUI_Delay(1000); GUI_SetColor(0x0); //设置显示颜色为黑色!?黑色对着呢!1 时点亮 0 是熄灭你看看是不黑色。 GUI_SetBkColor(0xffffff); for (i="0"; i<160; i++) { int len = (i<80) ? i : 160-i; GUI_DrawHLine(i,20,len+20); } //显示一个三角形 GUI_Clear(); if (LCD_GET_YSIZE()>(100+bmMicriumLogo_1bpp.YSize)) { pBitmap=&bmMicriumLogo; //设置要显示的位图为 MicriumLogo } else { GUI_SetColor(GUI_BLUE); pBitmap=&bmMicriumLogo_1bpp; } GUI_DrawBitmap(pBitmap,(LCDXSize-pBitmap->XSize)/2,10); YPos="20"+pBitmap->YSize; //显示位图 MicriumLogo GUI_SetFont(&GUI_FontComic24B_1); GUI_DispStringHCenterAt("www.micrium.com",LCDXSize/2,YPos); //在指定位置以 FontComic24B_1 字 体显示文字 www.micrium.com GUI_Delay(1000); GUI_SetColor(GUI_RED); GUI_DispStringHCenterAt("?2002\n", LCDXSize/2,YPos+30); GUI_SetFont(&GUI_Font10S_1); GUI_DispStringHCenterAt("Micri 祄 Inc.",LCDXSize/2,YPos+60);; //在指定位置以 Font10S_1 字体显示 文字 Micri 祄 Inc GUI_Delay(1000); } 截图 一个完整的 gui 应用程序的例子就出来了。接下来将是 gui 应用程序的开发。 从最简单的文字到 window 到复杂的控件。 一步一步来,我也在学习。 在硬件控制器彻底搞定之前都将使用这个东西开发应用程序。 uC/GUI3.32 应用笔记连载之五 uC/GUI NIOSII 移植之 Text 显示 今天研究了 uC/GUI 的文字显示系统。 这个系统的功能相当强大,提供了一下几个函数。 GUI_DispChar() 显示一个字符 GUI_DispCharAt() 在某个位置显示一个字符 GUI_DispChars() 显示 n 个设定的字符 GUI_DispString() 显示一个字符串 GUI_DispStringAt() 在某个位置显示一个字符串 还有好大一堆函数,不过这几个是最基本的。 先看一段有关这些代码的事例程序: void MainTask(void) { unsigned int i; GUI_Init(); 初始化,设置的默认字体是 6*8 的一种字体,具体叫什么忘了 GUI_SetColor(GUI_YELLOW); 设置显示颜色为 YELLOW,这里指的是字符的颜色 GUI_DispChars('*', 108); 从当前坐标起显示 108 个*,就是截图里面的最上面的那排* for(i = 0; i < 480; i+=8) { GUI_DispCharAt('*', 1, i); } 在第一列显示一列* GUI_DispChars('*', 108); 在最下面一行显示一排* for(i = 0; i <= 480; i+=8) { GUI_DispCharAt('*', 634, i); } 在最右边的一列显示一列* GUI_SetColor(GUI_GREEN); 设置显示的颜色为 GREEN GUI_SetFont(&GUI_Font8x10_ASCII); 设置字体为 GUI_Font8*10_ASCII GUI_DispCharAt('A', 100, 100); 在坐标 100,100 处显示一个 A GUI_DispString("! Hello World! "); 显示 Hello World!大家注意这是紧跟着 A 显示出来的,即它 是在当前光标处显示字符的 GUI_SetFont(&GUI_Font32_ASCII); 设置字体 GUI_SetColor(GUI_YELLOW); 设置显示颜色为 YELLOW,下面代码显示的字符都是黄 色的 GUI_DispChars('*', 15); 显示 15 个* GUI_SetBkColor(GUI_BLUE); 设置背景颜色为 BLUE,大家注意这个背景颜色,是衬在字 下面的,而不是整个的背景 GUI_DispCharAt('B', 600, 400); GUI_SetFont(&GUI_Font32B_ASCII); GUI_SetColor(GUI_RED); GUI_DispStringAt("Hello World!", 1, 200); 在 1,100 这个地方显示字符串,注意覆盖掉了原先显示出来的* GUI_Delay(1000); } 效果图 这样基本的字符显示函数就完了。大家都会使用了。 在前提到这个 GUI 支持 UNICODE。 既然支持 UNICODE 那就应该能显示中文才对啊! 当然能显示中文,但关键问题是字体! 这里就讲一讲有关字体的提取。 首先要用到一个字体转换工具,因为我们得到的 uC/GUI 代码基本上都是 D 版的,里面所附的字体转换工 具都是 DOME 版,根本转换不出来正常的字体.c 文件。在这里要用到另外一个程序。 声明:该程序转载自 www.ucgui.com,所有权归原作者 ucgui 所有,这里只是转载。仅上船该程序的可执 行文件 声明:在这里特便感谢原作者做出的贡献! 首先运行程序,看到如图的程序界面,相当的简单。 然后点击选择字体。按扭出现新的对话框,我选择的字体如图所示。 确定后回到主界面,点击 看到这个对话框文件就转换好了! 直接加载进模拟器工程就可以享受中文字体带来喜悦了! 在这里上传两个转换好的字体宋体(5 号字)和 Times new roman(5 号字)两个字体,供大家参考,其 中 Times 字体去掉了除 ascii 码之外所有的其他字模。 说一下这里的 5 号字对应的就是 16*16 的汉字字体。 该附件被下载次数 41 宋体那个文件体积巨大 3Mb 多,如果是大字体的话就有十几 MB 了! 我们现在运行下面的程序,体验一下中文的喜悦! #include "GUI.h" extern GUI_FLASH const GUI_FONT GUI_FontHZ_FangSong_GB2312_14; extern GUI_FLASH const GUI_FONT GUI_FontHZ_Times_New_Roman_14; extern GUI_FLASH const GUI_FONT GUI_Font8x10_ASCII; extern GUI_FLASH const GUI_FONT GUI_Font32_ASCII; extern GUI_FLASH const GUI_FONT GUI_Font32B_ASCII; /*这几行一定要有,声明从外部引用这个数据 结构,建议大家将所有的字体的定义弄成一个头文件,这样子比较方便!*/void MainTask(void) { unsigned int i; GUI_Init(); GUI_SetColor(GUI_YELLOW); GUI_DispChars('*', 108); for(i = 0; i < 480; i+=8) { GUI_DispCharAt('*', 1, i); } GUI_DispChars('*', 108); for(i = 0; i <= 480; i+=8) { GUI_DispCharAt('*', 634, i); } GUI_SetColor(GUI_GREEN); GUI_SetFont(&GUI_FontHZ_Times_New_Roman_14); GUI_DispCharAt('A', 100, 100); GUI_DispString("! Hello World! "); /*仔细看这里的字体已经是 Times new roman 了和上面的是不一 样的*/ GUI_SetFont(&GUI_Font32_ASCII); GUI_SetColor(GUI_YELLOW); GUI_DispChars('*', 15); GUI_SetBkColor(GUI_BLUE); GUI_DispCharAt('B', 600, 400); GUI_SetFont(&GUI_FontHZ_FangSong_GB2312_14); GUI_SetColor(GUI_RED); GUI_DispStringAt("大家好这里是中文显示演示程序!", 1, 200); /*将上面程序中的 Hello World 替换成 了中文!*/ GUI_Delay(10000); } 还有一个郁闷的问题,文件太大了有的编译器有限制!例如 VC.NET 的编译器。好在 NIOS II 编译器没有 这个限制。 看看图: 实际测试不影响使用,我们测试了 4000 多个汉字没有发现什么问题。 uC/GUI3.32 应用笔记连载之六 uC/GUI NIOSII 移植之 2D 图形库 今天继续昨天的话题。 来看 2D 图形库。这里面 uC/GUI 提供了强大的功能。先看看有什么函数。 里面有不少东西,这是截的图懒的一个一个把他们敲上来了。 先看第一个函数,GUI_SetDrawMode();设置 GUI 的绘图模式。靠上去好像很高深。这个函数就有一个参 数 mode。 mode 又两个选项 GUI_DRAWMODE_NORMAL 和 GUI_DRAWMODE_XOR。 先看一个例子大家就明白这个 MODE 是什么意思了。 void MainTask(void) { unsigned int i; GUI_Init(); GUI_SetFont(&GUI_FontHZ_Times_New_Roman_14); GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);设置为 GUI_DRAWMODE_NORMAL GUI_SetBkColor(GUI_YELLOW); GUI_Clear(); //这句话比较有意思,执行了之后他会将整 个窗口填充为 Bk 设置的颜色,要不只有在在绘制的图形的下面才有 Bk 色。 GUI_SetColor(GUI_RED); GUI_FillCircle(300, 200, 130); //画第一个园,红色的,显眼一点。 GUI_SetColor(GUI_GREEN); //设置绘图颜色为 GREEN GUI_FillCircle(140, 200, 130); //以 NORMAL 方式画第二个圆 GUI_SetDrawMode(GUI_DRAWMODE_XOR); //设置绘图方式为 XOR GUI_FillCircle(460, 200, 130); //以 XOR 方式绘制第三个圆,这里大家仔细看看 同样绘制了一 GREEN 颜色的圆,为什么不是 GREEN 的?XOR 惹的祸。这个函数在黑白显示里面尤为重 要! GUI_SetColor(GUI_BLUE); GUI_DispStringAt("First Circle", 300, 340); GUI_DispStringAt("Seconde Circle", 140, 340); GUI_DispStringAt("Third Circle", 460, 340); //这些是为了观察方便添上去的 GUI_SetColor(GUI_BLACK); GUI_SetDrawMode(GUI_DRAWMODE_NORMAL); GUI_FillCircle(300, 200, 3); GUI_FillCircle(140, 200, 3); GUI_FillCircle(460, 200, 3); GUI_DrawCircle(300, 200, 131); //画圆,但是画出来的只有轮廓,上面调用的函数 GUI_FillCircle()是将这员填充颜色的。uC/GUI 里面所有的在封闭图形比如说圆和长方形的绘图函数 Fill 和 Draw 都有类似的关系 GUI_Delay(5000); } 效果图 接下来就应该显示位图了及 BMP 文件。但是大多数的嵌入式系统不支持文件系统那该怎么办? uC/GUI 提供了一个解决方案,把位图转化为.C 文件。 这个工具就叫 uC-GUI-BitmapConvert.exe 执行这个工具,打开一个我事先准备好的位图文件。 然后如图选择转换该文件。 其实在这里选择把位图转换成多少色的都没有关系,gui 会自动适佩目标系统的颜色。 之所以这么选择是为了节省存储空间,毕竟嵌入式系统容量有限。 转换好了以后立即就能看到效果。 在界面的最上方显示的是这个位图的大小这里可看到是 419*490。 下面显示的就是调色板,即这个位图所有能显示出来的颜色。 线面就是预览了。难看的不行了。 然后选择另存为,就出现了.c 文件这个选项。 这是转换好的位图.c 文件和位图原文件。 uC/GUI 还支持位图文件的压缩。在保存的时候选择 就可以了。 比较一下文件可以看到两个文件的大小相差了一倍。 为压缩的 600 多 k,压缩的才 300。按照他文档的说明,可以提供 2 的压缩率。 来看看他们都有什么不同。 这是为压缩的: #include "stdlib.h" #include "GUI.H" /* Palette The following are the entries of the palette table. Every entry is a 32-bit value (of which 24 bits are actually used) the lower 8 bits represent the Red component, the middle 8 bits represent the Green component, the highest 8 bits (of the 24 bits used) represent the Blue component as follows: 0xBBGGRR */ const GUI_COLOR Colors3[] = { 0x000000,0x0000FF,0x00FF00,0x00FFFF ,0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF }; /*这个位图的调色板可以看出来里面有 8 种颜色*/ const GUI_LOGPALETTE Pal3 = { 8, /* number of entries */ 0, /* No transparency */ &Colors3[0] }; const unsigned char ac3[] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /*这里面存放的就是 bitmap 的数据太多了就被我精简了,只显示一行。有兴趣的去下载附件看看。*/ }; const GUI_BITMAP bm3 = { 419, /* XSize */ 490, /* YSize */ 210, /* BytesPerLine */ 4, /* BitsPerPixel */ ac3, /* Pointer to picture data (indices) */ &Pal3 /* Pointer to palette */ }; 下面是压缩的: #include "stdlib.h" #include "GUI.H" /* Palette The following are the entries of the palette table. Every entry is a 32-bit value (of which 24 bits are actually used) the lower 8 bits represent the Red component, the middle 8 bits represent the Green component, the highest 8 bits (of the 24 bits used) represent the Blue component as follows: 0xBBGGRR */ const GUI_COLOR Colors3_compressed_with_palette[] = { 0x000000,0x0000FF,0x00FF00,0x00FFFF ,0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF }; const GUI_LOGPALETTE Pal3_compressed_with_palette = { 8, /* number of entries */ 0, /* No transparency */ &Colors3_compressed_with_palette[0] }; const unsigned char ac3_compressed_with_palette[] = { /* RLE: 418 Pixels @ 000,000*/ 254, 0x07, 164, 0x07, /* RLE: 001 Pixels @ 418,000*/ 1, 0x00, /* RLE: 418 Pixels @ 000,001*/ 254, 0x07, 164, 0x07, /*同上砍掉了很多东西,有兴趣的看附件*/}; const GUI_BITMAP bm3_compressed_with_palette = { 419, /* XSize */ 490, /* YSize */ 210, /* BytesPerLine */ GUI_COMPRESS_RLE4, /* BitsPerPixel */ ac3_compressed_with_palette, /* Pointer to picture data (indices) */ &Pal3_compressed_with_palette /* Pointer to palette */ ,GUI_DRAW_RLE4 }; 看看有什么区别,根据我的理解,压缩就是把有信息的象素点标出来。黑色的就不标记。 不过在显示效果上没有任何区别!但是显示压缩的位图明显能感觉到速度较慢。 这是测试用的代码: extern const GUI_BITMAP bm3; extern const GUI_LOGPALETTE Pal3; extern const unsigned char ac3[]; extern const GUI_BITMAP bm3_compressed_with_palette; //这是一些要用到的外部变量声明 GUI_SetDrawMode(GUI_DRAWMODE_NORMAL); GUI_SetBkColor(GUI_BLACK); GUI_SetColor(GUI_WHITE); GUI_Clear(); /*清理桌面,变成黑的*/ GUI_DrawBitmap(&bm3, 10,10); /*在左上角为起始点的 10,10 座标为圆点显示位图*/ GUI_Delay(5000); GUI_Clear(); GUI_Delay(1000); GUI_DrawBitmap(&bm3_compressed_with_palette, 50, 10); /*在左上角为起始点的 50,10 座标为圆 点显示位图,效果上没有区别,但是速度明显的慢*/ GUI_Delay(5000); 直接添加到上段代码的后面就行了。 超出显示范围的内容就被自动砍掉了。这是第一个显示的截图,第二个由于效果上没却别,就不浪费论坛 空间了。 再来看看 GUI_DrawBitmapExp();这个函数,这个函数有多达十个参数。 void GUI_DrawBitmapExp(int x0, int y0, //显示位图的起始座标(指的是在 LCD 上的位置) int XSize, int YSize, //这个两参数的含义是在待显示的位图中选取一个 XSize*YSize 大小的范围来显示,从 0,0 座标开始。取值范围 1~~255 int XMul, int YMul, //比例因数,即放大比率!议会就能看到这个参数的效果 int BitsPerPixel, //位图的每个象素的位数,可以在 bm3 这个结构体中找 到 int BytesPerLine, //待显示位图每行的字节数,可以在 bm3 这个结构体中 找到 const U8* pData, //指向位图,实际存储数据变量的指针。 const GUI_LOGPALETTE* pPal); //指向 GUI_LOGPALETTE 数据结构的指针 GUI_Clear(); GUI_Delay(1000); GUI_DrawBitmapExp(10, 10, 255, 255, 1, 1, bm3.BitsPerPixel, bm3.BytesPerLine, &ac3, &Pal3); //看 看这段代码的含义,特别注意 pData 的取值是指向 ac3 的指针 这句的效果 GUI_Delay(5000); GUI_DrawBitmapExp(10, 10, 255, 255, 2, 2, bm3.BitsPerPixel, bm3.BytesPerLine, &ac3, &Pal3); 这句的效果,图片被放大了! GUI_Delay(5000); GUI_Clear(); GUI_DrawBitmapMag(&bm3 ,10, 10, 2, 2); GUI_Delay(5000); 也是放大显示一个图像!效果和上面的是一样的。 没有什么区别。 下来在演示一个 polygons 的例子。 static const GUI_POINT _aPointArrow[] = { { 0, 0}, {-40, -30}, {-10, -20}, {-10, -70}, { 10, -70}, { 10, -20}, { 40, -30}, }; //定义一个多变性所有的顶点 GUI_Clear(); GUI_SetColor(GUI_BLUE); GUI_FillPolygon (&_aPointArrow[0], 7, 260, 180); //填充颜色 GUI_DrawPolygon(&_aPointStar, 7, 460, 200); 仅有边框 //7 表着个要 Fill 的多变性有几个顶点 GUI_Delay(5000); 效果如图: 今天用到的 main 函数。 今天就到此为止!明天继续!有兴趣的朋友还请关注。 uC/GUI3.32 应用笔记连载之七 uC/GUI NIOSII 移植之 Window Manager(窗口管理器) 昨天太晚了没有时间更新了。今天继续。 今天来看看 Window manager,窗口管理器。 先来看一个小例子。 #define MSG_CHANGE_TEXT WM_USER+0 #ifndef NULL #define NULL 0 #endif typedef struct { int x; int y; int xHere, yHere; const GUI_BITMAP* pBitmap; } tDrawContext; extern GUI_FLASH const GUI_FONT GUI_FontHZ_FangSong_GB2312_14; extern GUI_FLASH const GUI_FONT GUI_FontHZ_Times_New_Roman_14; extern GUI_FLASH const GUI_FONT GUI_Font8x10_ASCII; extern GUI_FLASH const GUI_FONT GUI_Font32_ASCII; extern GUI_FLASH const GUI_FONT GUI_Font32B_ASCII; extern const GUI_BITMAP bm3; extern const GUI_LOGPALETTE Pal3; extern const unsigned char ac3[]; extern const GUI_BITMAP bm3_compressed_with_palette; extern const GUI_BITMAP bmmap; 有字体*/ /*以上全部是外部变量声明,有位图, static WM_CALLBACK* _cbBkWindowOld; function),后面会具体说明这个 Call back 是干什么的*/ static char _acInfoText[40]; /*声明背景窗口的回调函数(Call back /*要在背景窗口中显示的文字*/ static WM_HWIN _hWindow2; /*窗口 2*/ static void _cbWindow2(WM_MESSAGE* pMsg) { /*窗口 2 的 call back*/ int x, y; switch (pMsg->MsgId) { /*pMsg 这个参数用来告诉这个回 调函数发生了什么事件的!这里列出了系统已经定义好的所有的事件*/ case WM_CREATE: /*to do add code here*/ break; case WM_DELETE: /*to do add code here*/ break; case WM_HIDE: /*to do add code here*/ break; case WM_MOVE: /*to do add code here*/ break; case WM_NOTIFY_PARENT: /*to do add code here*/ break; case WM_PAINT: /*这个 Paint 事件,准确地翻译我不知道,但他的功能主 要就是自动重绘窗口,这十分重要,有了自动重绘你只要在这个 CB 里面告诉 GUI 你想绘什么东西就行了, GUI 会自动在适当的时机重绘*/ GUI_SetBkColor(GUI_RED); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_SetFont(&GUI_Font24_ASCII); x= WM_GetWindowSizeX(pMsg->hWin); y= WM_GetWindowSizeY(pMsg->hWin); GUI_DispStringHCenterAt("Test Window No.2", x / 2, 1); /*在这里面你可以调用上面贴子中所有 出现过的内容,但不是在整个屏幕上绘图了,而是在这个窗口中绘图*/ break; case WM_SHOW: /*to do add code here*/ break; case WM_SIZE: /*to do add code here*/ break; case WM_TOUCH: /*to do add code here*/ break; default: WM_DefaultProc(pMsg); /*在回调函数中还有很多其他系统定义的事件,例如 WM_SIZE 你可 以在发生了该事件后改变窗口的内容。有了这个回调函数就可以实现很多的功能*/ } } static void _ChangeInfoText(char* pStr) { /*将要在背景窗口中显示的文字放到一个全局变量里面去, 再由 Bk 窗口的回调函数自动刷新*/ WM_MESSAGE Message; Message.MsgId = MSG_CHANGE_TEXT; Message.Data.p = pStr; WM_SendMessage(WM_HBKWIN, &Message); /*发送一个消息告诉 Bk 的 cb 发生了文字改变的事件*/ WM_InvalidateWindow(WM_HBKWIN); } static void _cbBkWindow(WM_MESSAGE* pMsg) { /*Bk 窗口的 CB 函数,在这里可以更清楚地看到 cb 是怎么工作的*/ switch (pMsg->MsgId) { case MSG_CHANGE_TEXT: /*发生了 MSG change 设个事件,将待显示的文本拷贝的 变量中去*/ strcpy(_acInfoText, pMsg->Data.p); /*这里有点小小的编程技巧,在这里没有使用 break,而是直接执行 下面的 case 里面的内容这样就直接刷新的 Bk 窗口*/ case WM_PAINT: GUI_SetBkColor(GUI_CYAN); GUI_Clear(); GUI_SetColor(GUI_RED); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5); GUI_SetFont(&GUI_FontHZ_FangSong_GB2312_14); GUI_DispStringAt(_acInfoText, 5, 40); /*在这里就可以看到桌面是怎么来的了,这里的图片和 lcd 的大 小不一样,如果一样就是桌面了*/ GUI_DrawBitmap(&bm3, 50, 60); break; /*这里就看到了 Bk 窗口里面发生的一切*/ default: WM_DefaultProc(pMsg); } } /* ******************************************************************* * * main() * ******************************************************************* */ void MainTask(void) { unsigned int i; WM_HWIN hClient; GUI_Init(); _cbBkWindowOld = WM_SetCallback(WM_HBKWIN, _cbBkWindow); GUI_Delay(1000); _ChangeInfoText("uC/GUI 演示程序!"); _hWindow2 = WM_CreateWindow(330, 130, 300, 300, WM_CF_SHOW | WM_CF_FGND, _cbWindow2, 0); GUI_Delay(2000); } 这段代码就比较复杂了,可以看出来想把 GUI 用好不是一件容易的事情! 那如果不使用 call back 机制呢。一样可以实现相同的功能。但是屏幕的刷新可就是你的责任了。 用户就需要调用相关的函数来实现屏幕内容的刷新。 可能有很多人还不理解这个 cb 机制。我也说不太清。 在前几天的所有例子中都是用户控制刷屏的。就直在调用 GUI_Delay()的时候内容才会改变! 单步运行就知道了。 下面看看队窗口的操作 WM_ResizeWindow(_hWindow2, -100, -100); WM_MoveTo(_hWindow2, 50, 100); 执行这两句,窗口就变了样了。 当然了你还可以一次让它移动 1 个像素,这样看上去就是平滑移动的! 窗口管理还有很多的内容,以后慢慢再贴出来。 这些东西决的原创,欢迎大家提意见,随意转载,但请注明出处和作者。

    Top_arrow
    回到顶部
    EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。