1. 程式人生 > 其它 >【第3版emWin教程】第11章 GUIBuilder6.X的使用方法

【第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 初學者重要提示

  1. 模擬器使用的emWin是6.16版本,如果SEGGER官網以後有更高版本的推出,使用方法是一樣的。另外,開發板用的emWin版本也是6.10,如果emWin有升級版釋出,使用方法也是相同的。
  2. emWin模擬器可以採用VC6.0或者VS2019執行,如果採用的VC6.0精簡版,大小僅16MB,支援XP系統,WIN7,WIN10均支援,下載地址提供下:http://www.armbbs.cn/forum.php?mod=viewthread&tid=10428 。實際測試比較好用。
  3. 對於初學者來說,務必要掌握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)

實驗目的:

  1. 學習GUIBuilder的使用。
  2. 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的使用(裸機)

實驗目的:

  1. 學習GUIBuilder的使用。
  2. 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的使用方法,以及將其移植到開發板和模擬器上的方法,初學者務必要多練習並將其掌握。