首页资源分类嵌入式处理器其它 > ucGUI移植经验总结

ucGUI移植经验总结

已有 445122个资源

下载专区

文档信息举报收藏

标    签:ucGUI

分    享:

文档简介

ucGUI移植经验总结

文档预览

UCGUI 移植经验总结 BY:机长 如果没有找到 ucGUI 没有提供你所使用的 LCD 驱动,看完本文章,定有大收获。 本教程是将 ucGUI 移植到 STM32 单片机。LCD 驱动器为 HX8347。为了教程有更大的 通用性,LCD 驱动程序未采用 ucGUI 官方提供。编译环境为 5.4。 本教程可作为其它单片机、LCD、编译环境的参考。 不足之处,敬请指出。 1 解压“ucGUI-V3-90a----非常好用.rar” 这个版本的优点:需要改动的地方少;编译时不会由于在 Linux 环境下编辑源代码,然 后又拿回 IAR 环境编译造成大量“Warning[Pa050]: ……”;LCD 底层驱动获取方便,不依 赖于 ucGUI 官方驱动。 顺次打开“uCGUI-V3-90a → UCGUI390a → Start”。将 Start 文件夹下的 Config 和 GUI 文件夹复制的自己所建立工程文件夹。 然后打开 IAR,在 Workspace 中添加 Config 和 GUI 文件夹内容。添加完后,如下图所 示。其中“FWLib”是我的工程中所需要的,属于多余项。 然后 右击工程 ,打开 Options ,选 择左侧的 “ C/C++ Compiler ”。然 后在右侧 选 择 Preprocessor。在“Additional include directories”下填写工程中 Config 和 GUI 文件夹路径。 Ex: $PROJ_DIR$\..\gui $PROJ_DIR$\..\gui\AntiAlias $PROJ_DIR$\..\gui\ConvertColor $PROJ_DIR$\..\gui\COnvertMono $PROJ_DIR$\..\gui\core $PROJ_DIR$\..\gui\Font $PROJ_DIR$\..\gui\JPEG $PROJ_DIR$\..\gui\LCDDriver $PROJ_DIR$\..\gui\MemDev $PROJ_DIR$\..\gui\MultiLayer $PROJ_DIR$\..\gui\Touch $PROJ_DIR$\..\gui\Widget $PROJ_DIR$\..\gui\WM $PROJ_DIR$\..\Config 截图 -1- 官方网站:www.zhanying.tk QQ 群:166578859 2 配置 GUIConf.h PS:一下配置,配置为“1”,启用;配置为“0”,不启用 #define GUI_OS (0) /*是否加载操作系统*/ #define GUI_SUPPORT_TOUCH (0) /*是否启用触屏支持*/ #define GUI_SUPPORT_UNICODE (1) /*是否启用混合型 ASCII/UNICODE 编码 */ #define GUI_DEFAULT_FONT &GUI_Font8x16 /*字体大小配置,参见手册 */ #define GUI_ALLOC_SIZE 500 /*应用于 GUI 的动态内存字节配置,不建议 低于 500;也不要配置太高,导致内存溢出*/ /********************************************************************* * * Configuration of available packages */ #define GUI_WINSUPPORT 0 /* 窗口管理数据包支持 */ #define GUI_SUPPORT_MEMDEV 0 /* 存储设备支持 */ #define GUI_SUPPORT_AA 1 /* 抗锯齿。启用会提高画质,但降低执行 效率 */ 3 配置 GUITouchconf.h 由于在第 2 步未启用触屏,所以这里不需要配置 4 配置 LCDConf.h #define LCD_XSIZE (240) /*LCD 屏 X 轴像素 */ #define LCD_YSIZE (320) /* LCD 屏 Y 轴像素 */ #define LCD_BITSPERPIXEL (16) /*LCD 屏,像素位数*/ #define LCD_CONTROLLER -1 /*LCD 驱动器号。如果未找到 ucGUI 提供的 对应 LCD 驱动程序,此处填-1,然后解压“ucGUI-V3-90a----非常好用.rar”,打开 GUI 文件 夹下的 LCDDriver 文件夹,打开 LCDDummy.c 文件进一步配置,具体配置在第 5 步讲*/ #define LCD_FIXEDPALETTE 565 /*定义颜色查询表,此处选择与 LCD 有关, 具体参数查看 LCD 资料,查询颜色格式。然后打开 GUI 文件夹下的 ConvertColor 文件夹, 查找对应文件进行配置*/ #define LCD_SWAP_RB 1 /*激活红、蓝基色的交换。此处建议首先配置 为 0。待所有配置完成后,运行程序,设定全屏显示为蓝色。如果显示为红色,改为 1,即 可正常显示*/ #define LCD_INIT_CONTROLLER() LCD_InitPanel() /*LCD_InitPanel() 是 之 前 已 经编写好的 LCD 初始化程序,非 ucGUI 自带*/ 如果说 LCD 自带的驱动程序已经对寄存器进行了配置,那么以下寄存器配置语句,请 注释掉,否则在程序运行时可能会出现错误。 LCD_WRITE_REGLH(0x00>>1,LCD_REG0,LCD_REG1); \ LCD_WRITE_REGLH(0x02>>1,LCD_REG2,LCD_REG3); \ LCD_WRITE_REGLH(0x04>>1,LCD_REG4,LCD_REG5); \ -2- 官方网站:www.zhanying.tk QQ 群:166578859 LCD_WRITE_REGLH(0x06>>1,LCD_REG6,LCD_REG7); \ LCD_WRITE_REGLH(0x08>>1,LCD_REG8,LCD_REG9); \ LCD_WRITE_REGLH(0x0a>>1,LCD_REGA,LCD_REGB); \ LCD_WRITE_REGLH(0x0c>>1,LCD_REGC,LCD_REGD); \ LCD_WRITE_REG (0x0e>>1,0x00); /* 0, screen 2 start l*/ \ LCD_WRITE_REG (0x10>>1,0x00); /* screen 2 start h */ \ LCD_WRITE_REGLH(0x12>>1,LCD_REG12, LCD_REG13); /* mem adr. offset, screen 1 vsize(lsb)*/ \ LCD_WRITE_REGLH(0x14>>1,LCD_REG14,0); LCD_WRITE_REGLH(0x1a>>1,0,LCD_REG1B); \ LCD_WRITE_REGLH(0x1c>>1,LCD_REG1C, 0) 5 配置 LCD 驱动 第 4 步的 LCD_CONTROLLER 值,通过查找上表填写。然后打开 GUI 文件夹下的 LCDDriver 文件夹,查看是否有对应的 LCD 驱动 C 文件。如果没有,即使填写了正确的 LCD_CONTROLLER 值,程序也不能正常运行。此时需要将 LCD_CONTROLLER 值填写为 -1,加载自己的 LCD 驱动程序。个人建议配置 LCD_CONTROLLER 值为-1,加载 LCD 厂 商提供的驱动。 打 开 对 应 的 ucGUI 的 LCDDriver 文 件 夹 下 的 LCD 驱 动 程 序 C 文 件 。 如 果 LCD_CONTROLLER 值为-1,打开的 LCDDriver 文件夹下的 LCDDummy.c,配置驱动。 一下是配置文件 -3- 官方网站:www.zhanying.tk QQ 群:166578859 #ifndef LCD_INIT_CONTROLLER #define LCD_INIT_CONTROLLER() LCD_InitPanel() /*LCD_InitPanel() 是 之 前 已 经编写好的 LCD 初始化程序,非 ucGUI 自带*/ #endif 找到 void LCD_L0_SetPixelIndex 函数,在其留空处(如下所示) /* Write into hardware ... Adapt to your system */ { /* ... */ } 删掉“/* ... */”,调用 LCD 在(x,y)处以某一颜色画点函数。需要注意的是,传递的 参数 x、y,需要更改为 xPhys、yPhys 。这是由于 ucGUI 的宏定义中定义了屏幕 xy 翻转, 以及 x、y 轴镜像翻转。具体原因请看下方的宏定义代码。 #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y int xPhys = LOG2PHYS_X(x, y); int yPhys = LOG2PHYS_Y(x, y); #else 同理,找到 void LCD_L0_GetPixelIndex 函数,在其留空处,调用 LCD 在获取(x,y) 处以某一颜色的函数。 通过以上几步,ucGUI 移植基本完成。接下来所要做的就是,编写测试函数,然后将整 个程序进行编译。有错误,该错误。如果遇到 ucGUI 的变量没有定义,则在出现的错误文 件开头加入 ucGUI 对应的头文件。 Ex: 调用 GUI_SetColor(GUI_BLACK); 编译时,出现错误,提示 GUI_BLACK 没有定义。则只需在出现错误的 C 文件开头加 上“#include "GUI.h"”,即可解决。 6 底层配置优化 如果 ucGUI 已经移植成功,并通过测试,那么请继续看这一节。如果没有,请跳过。 在测试 ucGUI 时,我发现,在刷屏(将 LCD 屏幕全部填充为某一颜色)时,调用 ucGUI 的刷屏函数,远不如 LCD 的刷屏函数执行速度快。通过测试,ucGUI 的刷屏速度不及 LCD 的 20 分之 1。 通过查看 ucGUI 的底层文件,我找到了 ucGUI 刷屏速度慢的原因。 ucGUI 的画图机制是找到某一个点,然后对其进行颜色填充;然后再找下一个点对其进 行颜色填充。我们通常所用的 LCD 驱动器,如果说所画图像,某一区域颜色单一,在设定 绘图区域后,顺次进行颜色填充,无需找一个点画一个点。这就是 ucGUI 画图时不如 LCD 速度快的原因。 优化的方法很简单: 打 开对 应的 ucGUI 的 LCDDriver 文 件夹 下的 LCD 驱 动程 序 C 文 件。 找到 “void LCD_L0_DrawHLine (int x0, int y, int x1) ” 函 数 。 将 “ else ” 语 句 下 的 “LCD_L0_SetPixelIndex(x0, y, LCD_COLORINDEX);”改写为 LCD 颜色填充函数。比如说, 我将其改为了“LCD_WriteRAM(LCD_COLORINDEX)”。这样的话,不再找一个点画一个 点。大大加快了 ucGUI 的画图执行速率。 本节小结:此种优化方法并不适用于所有的 LCD 驱动器。ucGUI 画图时采取找一个点 画一个点的方法,应该是出于程序通用性的考虑。如果 ucGUI 移植完成后,刷屏效果可以 接受,为了程序稳定性考虑,不建议进行优化。 常见问题解决: 如果移植后,显示的画面进行了横竖翻转,或者镜像翻转。只需要在 LCDConf.h 文件 中,加入以下语句 -4- 官方网站:www.zhanying.tk QQ 群:166578859 #define LCD_SWAP_XY 1 #define LCD_MIRROR_X 1 #define LCD_MIRROR_Y 1 具体是“1”还是“0”,需要经过自己调试配置。 如果说通过以上过程已经 ucGui 成功移植,那么接下来进行触摸屏移植。 7 触摸屏移植 1)修改 config 文件中的宏定义#define GUI_SUPPORT_TOUCH (1) 使系统支持触摸屏。 2)编写好触摸屏的 AD 转换驱动程序。 3).在 AD 转换驱动程序中加入如下函数 //触摸屏相关函数 void GUI_TOUCH_X_ActivateX() //准备 X 轴的测量 {} void GUI_TOUCH_X_ActivateY() //准备 Y 轴的测量 {} int GUI_TOUCH_X_MeasureX(void) //返回 A/D 转换器 X 轴的结果 {} int GUI_TOUCH_X_MeasureY(void) //返回 A/D 转换器 Y 轴的结果 {} 以上 4 个函数,需要根据使用的触摸屏控制器,自己写。 其中 void GUI_TOUCH_X_ActivateX(),void GUI_TOUCH_X_ActivateY()。有的触摸驱 动器可以不写这两个函数,但是要给这两个函数留空。也就是大括号中不写内容。 还有几点需要注意: 1 屏幕 xy 轴是否翻转,需要通过在 LCDConfig.h 中宏定义 #define LCD_SWAP_XY (1) 运行程序,若发现 x 或 y 轴镜像显示,需要再添加宏定义 #define LCD_MIRROR_X 1 #define LCD_MIRROR_Y 1 以上两个宏定义不需要全部添加。按照屏幕显示,只需要添加其中一个即可。如有需要 也可全部添加。 添加完上述宏定义,要注意 X、Y 轴像素值需要对调。Ex: #define LCD_XSIZE (320) /* X-resolution of LCD, Logical coor. */ #define LCD_YSIZE (240) /* Y-resolution of LCD, Logical coor. */ 2 常见问题解决 编译时,找不到 GUI_GetTime()或 GUI_X_GetTime()或 GUI_Delay()或 GUI_X_Init()时, 查看 GUI 文件夹下的 CORE 文件夹中是否缺失了 GUI_X.C 文件 -5- 官方网站:www.zhanying.tk QQ 群:166578859 对于彩色液晶的主控芯片是 HX8347 芯片,应注意颜色读取 对于有些液晶来说,无论是何种颜色制式(如下表所示) 在液晶控制器的内部会转换为 RGB24 位颜色。R,G,B 分别占八位。在通过 HX8347 读 取某一点液晶颜色时,根据官方文件,第一次读取的是错误值。如果单片机与液晶控制器的 传输数据格式是每次读取 16 位数据,那么需要在读取两次。得到 32 位数据。液晶是说,在 读取液晶颜色的时候,需要连续读取液晶次。同时,对于后两次得到的数据需要进行数据处 理。 举个例子来说:我对彩色液晶控制时,采用的是 16 位数据传输,颜色制式采用 565。 对于颜色制式,颜色的顺序是 RGB(ucGUI 中,默认的是 RBG,也就是红绿蓝,因此,在 LCDConf.h 中需要加入#define LCD_SWAP_RB 1,激活红蓝反色),5 位红色,6 位绿色,5 位蓝色。当单片机将 565 颜色数据传入到液晶内部时,颜色数据自动转换成了 888,也就是 说 RGB 颜色中 R、G、B 每一个占用 8 位,采用 24 位显示。当从液晶读取数据时,由于采 用的是 16 位数据传输,因此需要对液晶读取数据两次,得到 32 为数据。 比如说我传递给液晶的 565 颜色数据是 0x7BEF,也就是 0111 1011 1110 1111,即 16 进 制下 R 为 F,G 为 1F,B 为 F。在液晶内部颜色转化为了 888,也就是 0x787C7878。需要 说明的是,0x787C7878 中第一个 78 与最后一个 78 所代表的 RGB 位相同。对于我所使用的 液晶,第一个 78 与最后一个 78 都代表 R 值。对 787C7878 摒弃最后一个 78,对其进行译 码,就得到了 0111 1000 0111 1100 0111 1000。R→78 对应 0111 1000,G→7C 对应 0111 1100, B→78 对应 0111 10000。 以 R 为例,由于 565 颜色中 R 只有 5 位。液晶在内部将 R 值转化为 8 位。即译码方式 为:0 1111 → 0111 1000。将 565 制式中的 0111 译成 888 制式的 0111 1000。在通过 HX8347 读取到 0111 1000,对于这个二进制数只有从左往右数前五位有效,第六位数据与第一位数 据相同,第七位与第八位数据为 0(可以直接将第七位与第八位数据摒弃不用)。R 与 B 值 之所以在液晶内部这样处理的原因在于补足 RB 位,在液晶内部实现颜色 666 显示。 结合以上结论,以传输给液晶的 565 颜色数据是 0x93AF 为例。液晶的数据读取液晶某 点颜色时,需要对液晶读数三次。第一次是错误值,不用。第二次和第三次读出的 16 位数 据分别为 temp1 和 temp2。tmp1= 0x9474,temp2=0x7894。对于 temp1 和 temp2 进行数据处 理得到 565 颜色值 RGB_Code=(temp1&0xF800) | ((temp1&0x00FC)<<3) | ((temp2&0xF800)>>11) -6- 官方网站:www.zhanying.tk QQ 群:166578859 最后 565 结果:RGB_Code=0x93AF。 用图表显示以上过程如下: 第一步:传递 565 颜色制式数据 0x93AF 0x93AF 1001 0011 1010 1111 RGB 编码:1001 0011 1010 1111 第二步:液晶内部译码为 888 颜色制式数据 0x947478 0x947478 1001 0100 RGB 编码:1001 0100 0111 0111 0100 0111 0100 0111 1000 1000 第三步:读取液晶某点颜色 连续读取液晶某点颜色数据三次 第一次读取错误数据,这一步必须做,详见官方手册 第二次读取 16 位数据 temp1=0x9474 0x9474 1001 0100 0111 0100 RGB 编码:1001 0100 0111 0100 第三次读取 16 位数据 temp2=0x7894 0x7894 0111 1000 1001 0100 RGB 编码:0111 1000 1001 0100 二进制数据中黑色二进制数据无用。对于 R 值和 B 值读取的二进制数据从左往右数第 6 位数据与第一位数据相同。temp2 中后一个 78 是读取的颜色 R 值,与 temp1 中的第一个 78 相同。 第四步:对 temp1 和 temp2 进行数据处理,转化为 565 颜色制式 RGB_Code=(temp1&0xF800) | ((temp1&0x00FC)<<3) | ((temp2&0xF800)>>11) 数据处理 16 进制按位与 2 进制按位与 结果 移位处理 R temp1&0xF800 0x9474 & 0xF800 1001 0100 0111 0100 & 1111 1000 0000 0000 1001 0000 0000 0000 无移位 1001 0000 0000 0000 temp1&0x00F G C 0x9474 & 0x00FC 1001 0100 0111 0100 & 0000 0000 1111 1100 0000 0000 0111 0100 (temp1&0x00FC)<<3 左移 3 位 0000 0011 1010 0000 B Temp2&0xF80 0x7894 & 0111 1000 1001 0100 (temp2&0xF800)>>11 & 0111 1000 1001 0100 右移 11 位 0xF800 1111 1000 0000 0000 0000 0000 0000 1111 最后按位或处理 1001 0000 0000 0000 0000 0011 1010 0000 0000 0000 0000 1111 1001 0011 1010 1111 最后结果 RGB_Code=0x93AF 颜色读取过程结束。 -7- 官方网站:www.zhanying.tk QQ 群:166578859

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