【第3版emWin教程】第11章 GUIBuilder6.X的使用方法
教程不斷更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第11章 GUIBuilder6.X的使用方法
本小節主要帶領大家學習GUIBuilder6.x的使用,很好的利用這個軟體,能使得emWin介面設計事半功倍。
11.1 初學者重要提示
11.2GUIBuilder6.x的使用步驟
11.3emWin6.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的安裝目錄中,路徑\Keil\MDK-Middleware\7.12.0\emWin\Tool (版本不同,紅色數值不同)裡面:
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的使用方法,以及將其移植到開發板和模擬器上的方法,初學者務必要多練習並將其掌握。