教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第11章 GUIBuilder6.X的使用方法
本小节主要带领大家学习GUIBuilder6.x的使用,很好的利用这个软件,能使得emWin界面设计事半功倍。
11.1 初学者重要提示
11.2 GUIBuilder6.x的使用步骤
11.3 emWin6.x模拟器上运行GUIBuilder6.x生成的代码
11.4 移植GUIBuilder6.x生成的代码到开发板
11.5 实验例程说明(RTOS)
11.6 实验例程说明(裸机)
11.7 总结
11.1 初学者重要提示
- 模拟器使用的emWin是6.16版本,如果SEGGER官网以后有更高版本的推出,使用方法是一样的。另外,开发板用的emWin版本也是6.10,如果emWin有升级版发布,使用方法也是相同的。
- emWin模拟器可以采用VC6.0或者VS2019运行,如果采用的VC6.0精简版,大小仅16MB,支持XP系统,WIN7,WIN10均支持,下载地址提供下:http://www.armbbs.cn/forum.php?mod=viewthread&tid=10428 。实际测试比较好用。
- 对于初学者来说,务必要掌握GUIBuilder的使用方法,以及将其生成的代码移植到模拟器和开发板的方法。具体用到的emWin功能会在后面的章节中逐一讲解,本章节主要是学习使用方法。
11.2 GUIBuilder6.X的使用步骤
GUIBuilder在MDK5.X的安装目录中,路径KeilMDK-Middleware7.12.0emWinTool (版本不同,红色数值不同)里面:
11.2.1 第一步:建立一个对话框
- 找到GUIBuilder后,打开这个软件,并按照如下方式建立一个对话框。
- 修改对话框大小为800*480。
- 下面设置对话框标题的字体,对齐方式,和显示的文本。首先,在建立的对话框上面右击鼠标,选择Set font。
弹出如下界面,并选择字体GUI_FONT_32B_ASCII,点击OK。
设置好字体以后再设置对齐方式,还是右击鼠标,选择Set text alignment,并选择居中。
配置完成后,上面的字体Framewin字体会居中显示,然后还是鼠标右击,选择Set title text,并更改Framewin为armfly,修改的地方在左下角:
设置好以后,对话框就算建立完毕。
11.2.2 第二步:在对话框上面建立按钮
按钮的建立方法和上面的对话框是一样的。按钮上面的字体大小和显示内容,大家可以任意设置。按钮上的文本不支持对齐方式设置,默认是居中显示,这里是显示字符armfly,字体GUI_FONT_24B_ASCII,建立后的效果如下所示:
对于建立的按钮控件,用户可以任意拖动,并通过鼠标调整其大小,调整方法如下:先左击选中相应控件,会出现绿色的边框,在边框的地方拖动鼠标即可修改大小
11.2.3 第三步:在对话框上面建立滚动条
同样的方法,添加滚动条后的效果如下所示:
11.2.4 第四步:在对话框上面建立滑动条
同样的方法,添加滑动条后显示效果如下:
11.2.5 第五步:建立好后点击File->save
保存方法如下:
保存后生成的文件在GUIBuilder软件所在的文件夹里面:
11.3 emWin6.x模拟器上运行GUIBuilder6.x生成的代码
这里为大家讲解emWin上面运行GUIBuilder所生成代码的方法。使用方法在第9和第10章有详细说明。然后再展开Application文件分组(VC6.0和VS2019打开的文件是一样的):
这里打开SWIPELIST_Demo.c,将此文件里面的内容全部删掉,然后将生成的FramewinDLG.c文件里的所有内容复制到SWIPELIST_Demo.c文件里,仅这样程序还是不能够运行的,需要在SWIPELIST_Demo.c文件的内容末尾再加入如下代码就可以运行了。
/********************************************************************* * * MainTask */ void MainTask(void) { /* 窗口自动使用存储设备 */ WM_SetCreateFlags(WM_CF_MEMDEV); /* 初始化 */ GUI_Init(); /* 创建对话框,使用GUIBulder5.28生成的对话框创建函数 */ CreateFramewin(); while(1) { GUI_Delay(10); } }
SWIPELIST_Demo.c文件中完整的内容如下:
#include "DIALOG.h" /********************************************************************* * * Defines * ********************************************************************** */ #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00) #define ID_BUTTON_0 (GUI_ID_USER + 0x01) #define ID_SCROLLBAR_0 (GUI_ID_USER + 0x02) #define ID_SLIDER_0 (GUI_ID_USER + 0x03) // USER START (Optionally insert additional defines) // USER END /********************************************************************* * * Static data * ********************************************************************** */ // USER START (Optionally insert additional static data) // USER END /********************************************************************* * * _aDialogCreate */ static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 }, { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 130, 28, 147, 35, 0, 0x0, 0 }, { SCROLLBAR_CreateIndirect, "Scrollbar", ID_SCROLLBAR_0, 129, 74, 147, 28, 0, 0x0, 0 }, { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 133, 118, 137, 25, 0, 0x0, 0 }, // USER START (Optionally insert additional widgets) // USER END }; /********************************************************************* * * Static code * ********************************************************************** */ // USER START (Optionally insert additional static code) // USER END /********************************************************************* * * _cbDialog */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int NCode; int Id; // USER START (Optionally insert additional variables) // USER END switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // Initialization of 'Framewin' // hItem = pMsg->hWin; FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII); FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); FRAMEWIN_SetText(hItem, "armfly"); // // Initialization of 'Button' // hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); BUTTON_SetText(hItem, "armfly"); // USER START (Optionally insert additional code for further widget initialization) // USER END break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch(Id) { case ID_BUTTON_0: // Notifications sent by 'Button' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; case ID_SCROLLBAR_0: // Notifications sent by 'Scrollbar' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_VALUE_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; case ID_SLIDER_0: // Notifications sent by 'Slider' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_VALUE_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; // USER START (Optionally insert additional code for further Ids) // USER END } break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * CreateFramewin */ WM_HWIN CreateFramewin(void); WM_HWIN CreateFramewin(void) { WM_HWIN hWin; hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0); return hWin; } /********************************************************************* * * MainTask */ void MainTask(void) { /* 窗口自动使用存储设备 */ WM_SetCreateFlags(WM_CF_MEMDEV); /* 初始化 */ GUI_Init(); /* 创建对话框,使用GUIBulder5.28生成的对话框创建函数 */ CreateFramewin(); while(1) { GUI_Delay(10); } } /*************************** End of file ****************************/
点击这里进行编译和运行:
VC6.0
VS2019
实际显示效果如下:
11.4 移植GUIBuilder6.x生成的代码到开发板
移植到模拟器跟移植到开发板上的方法是一样的,将前面生成的FramewinDLG.c文件里的所有内容复制到MDK工程模板的MainTask.c文件里(这里以带RTOS的emWin模板为例进行截图,裸机版本是一样的,也是这个文件):
仅这样程序还是不能够运行的,需要在MainTask.c文件的内容末尾再加入如下代码就可以运行了。
/********************************************************************* * * MainTask */ void MainTask(void) { /* 窗口自动使用存储设备 */ WM_SetCreateFlags(WM_CF_MEMDEV); /* 初始化 */ GUI_Init(); /* 创建对话框,使用GUIBuilder5.28生成的对话框创建函数 */ CreateFramewin(); while(1) { GUI_Delay(10); } }
不过修改了注释使其更加规范并修改了MainTask函数,使emWin在STM32的运行性能发挥到最佳,修改后的代码如下:
/* ********************************************************************************************************* * 函 数 名: MainTask * 功能说明: GUI主函数 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void MainTask(void) { /* 初始化 */ GUI_Init(); /* 关于多缓冲和窗口内存设备的设置说明 1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效: WM_MULTIBUF_Enable(1); 2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV); 3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用 STM32H7 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂 感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。 4. 所有emWin例子默认是开启三缓冲。 */ WM_MULTIBUF_Enable(1); /* 触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行 此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。 TOUCH_Calibration(2); 参数为2表示两点校准 TOUCH_Calibration(4); 参数为4表示四点校准 */ #if 0 LCD_SetBackLight(255); TOUCH_Calibration(2); #endif /* 设置桌面窗口的背景色是白色,并且支持重绘 */ WM_SetDesktopColor(GUI_BLUE); /* 创建对话框 */ GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0); /* 屏幕显示后点亮,有效防止瞬间高亮 */ GUI_Delay(200); LCD_SetBackLight(255); while(1) { GUI_Delay(10); } }
11.5 实验例程说明(RTOS)
配套例子:
V7-507_emWin6.x实验_GUIBuilder的使用(RTOS)
实验目的:
- 学习GUIBuilder的使用。
- emWin功能的实现在MainTask.c文件里面。
实验内容:
1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。
2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。
(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。
3、默认上电是通过串口打印信息,如果使用RTT打印信息:
MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可
#define Enable_RTTViewer 1
4、各个任务实现的功能如下:
App Task Start 任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理,这里用作LED闪烁。
App Task UserIF 任务 :按键消息处理。
App Task COM 任务 :暂未使用。
App Task GUI 任务 :GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
RTT 打印信息方式:
程序设计:
任务栈大小分配:
μCOS-III任务栈大小在app_cfg.h文件中配置:
#define APP_CFG_TASK_START_STK_SIZE 512u
#define APP_CFG_TASK_MsgPro_STK_SIZE 2048u
#define APP_CFG_TASK_COM_STK_SIZE 512u
#define APP_CFG_TASK_USER_IF_STK_SIZE 512u
#define APP_CFG_TASK_GUI_STK_SIZE 2048u
任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start 任务 :2048字节。
App Task MspPro任务 :8192字节。
App Task UserIF 任务 :2048字节。
App Task COM 任务 :2048字节。
App Task GUI 任务 :8192字节。
系统栈大小分配:
μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
#define OS_CFG_ISR_STK_SIZE 512u
系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB
emWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */ #if EX_SRAM #define GUI_NUMBYTES (1024*1024*24) #else #define GUI_NUMBYTES (100*1024) #endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
emWin界面显示效果:
800*480分辨率界面效果,小分辨率显示屏仅可以显示一部分。
11.6 实验例程说明(裸机)
配套例子:
V6-503_STemWin实验_GUIBuilder的使用(裸机)
实验目的:
- 学习GUIBuilder的使用。
- emWin功能的实现在MainTask.c文件里面。
emWin界面显示效果:
800*480分辨率界面效果,小分辨率显示屏仅可以显示一部分。
emWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */ #if EX_SRAM #define GUI_NUMBYTES (1024*1024*24) #else #define GUI_NUMBYTES (100*1024) #endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
11.7 总结
本章节为大家讲解了GUIBuilder的使用方法,以及将其移植到开发板和模拟器上的方法,初学者务必要多练习并将其掌握。