emWin专题——emWin简介及模拟器的使用

一、emWin简介

1、emWin和ucGUI的关系

记得刚上大学的时候接触到单片机领域的一个图形界面叫ucGUI,也是跑在STM32上的,后来过了没多久网上查资料发现大家都是用的emWIn了,了解了一下它们之间的关系,其实是同一个东西。emWIn是在ucGUI的基础上发展起来的,两者同属一家公司(SEEGER)开发,没错就是咱买的JLINK调试器的那家公司,以前旧版本的ucGUI是开源的,后来emWin发展到5.0版本后进行了很大的更新,特别是底层驱动方面。但是emWIn5.xx版本向下完全的兼容低版本,也包括ucGUI5.xx以下的版本。emWIn5.xx以后的版本只有库没有源码,所以想要了解底层实现的话可以看早起的版本。

2、emWIn和STemWIn的关系

SEEGER公司授权给ST、NXP、Energy Micro等公司的处理器可以免费使用emWin。跑在ST处理器上的emWin我们称之为STemWin,STemWIn对ST的控制器做了专门的优化。出于一定的保护措施,STemWin的库是不能在其他芯片厂商的处理器上跑的,因为在STemWin初始化前要使能CRC校验。如果没有使能,STemWIn则启动不起来,KEIL MDK安装目录也带有emWIn的软件包,需要注册RL-ARM才可以使用。

 

二、模拟器的使用

1、emWin模拟器

按照正常的思路,我们应该是在KEIL上写好了代码,然后再对工程进行编译,将程序下载到开发板上查看现象,但是对于嵌入式来说这样的调试方式还是太慢了,如果能在PC上直接仿真运行就可以省去下载代码和开发板上调试的时间了,而且仿真的编译速度也比KEIL更加的快。

目前emWIn已经更新到V6.10版本了,大家可以在官网(SEEGER官网)下载到不同版本的emWIn模拟器以及相关的手册资料,下载之前需要注册一个账号,因为外网原因下载速度可能比较慢。本文最后的资料链接里也附有这个文件。下面我用的是V5.32版本的来展示。目录结构如下:

emWin专题——emWin简介及模拟器的使用_第1张图片

我电脑上装的是VS2013直接双击sln文件就可以打开工程了,如果提示升级什么组件的话直接点确定。

emWin专题——emWin简介及模拟器的使用_第2张图片

 然后直接点调试运行就可以看到运行的官方demo了。

emWin专题——emWin简介及模拟器的使用_第3张图片

 2、emWin + uCosIII模拟器

这是我在网上找到的资料,看到有人把uCosIII和emWin模拟器移植到了一起,个人感觉挺好的,因为我们有时候可能把嵌入式操作系统和图形界面一起用上,而且emWin也是支持操作系统的。这个资源会在本文最后面给出。VS编译的时候可能会报错:错误    206    error LNK1281: 无法生成 SAFESEH 映像。    解决方法是:选中项目,右键菜单->属性->链接器->命令行,在“附加选项”框中 输入 /SAFESEH:NO ,然后点击应用。

 

三、GUIBuilder的使用

有了PC端的模拟器其实还不够方便,因为这只是在运行阶段给我们提供了方便,而在代码的编写阶段能不能够一样给我们提供方便呢?就像QT、C#等等界面开发软件一样,支持用户拖拽控件生成代码的功能。GUIBuilder就是要完成这个功能。这个工具在KEIL的安装目录下就有,具体路径见下图。

emWin专题——emWin简介及模拟器的使用_第4张图片

 双击GUIBuilder.exe看到编辑界面。

emWin专题——emWin简介及模拟器的使用_第5张图片

随便拖几个控件上去练练手:

emWin专题——emWin简介及模拟器的使用_第6张图片

 完成后选择左上角的File->Save可以看到在当前目录下生成了一个.c文件FramewinDLG.c:

emWin专题——emWin简介及模拟器的使用_第7张图片

 里面的代码如下:

/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.24                          *
*        Compiled Jan 27 2014, 11:28:24                              *
*        (c) 2013 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: [email protected]       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x02)
#define ID_CHECKBOX_0 (GUI_ID_USER + 0x03)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)


// 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, 320, 240, 0, 0x64, 0 },
  { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 96, 24, 80, 20, 0, 0x0, 0 },
  { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 97, 53, 80, 20, 0, 0x0, 0 },
  { DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 104, 90, 80, 19, 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_SetText(hItem, "HelloWorld");
    FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
    //
    // Initialization of 'Checkbox'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
    CHECKBOX_SetText(hItem, "Check");
    // 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_CHECKBOX_0: // Notifications sent by 'Checkbox'
      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_DROPDOWN_0: // Notifications sent by 'Dropdown'
      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_SEL_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;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/

代码里面写好了生成界面的代码,只需要在运行时调用最后的CreateFramewin函数就可以生成界面了。接下来我们看看模拟器的代码,是在GUIDEMO_Start.c这个文件里调用GUI_Init()和生成界面的函数的,想要运行我们刚刚的界面就需要在这个函数里调用CreateFramewin函数而不去调用官方的demo界面。GUIDEMO_Start.c内容如下:

/*********************************************************************
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*        (c) 1996 - 2015  SEGGER Microcontroller GmbH & Co. KG       *
*                                                                    *
*        Internet: www.segger.com    Support:  [email protected]    *
*                                                                    *
**********************************************************************

** emWin V5.32 - Graphical user interface for embedded applications **
emWin is protected by international copyright laws.   Knowledge of the
source code may not be used to write a similar product.  This file may
only  be used  in accordance  with  a license  and should  not be  re-
distributed in any way. We appreciate your understanding and fairness.
----------------------------------------------------------------------
File        : GUIDEMO_Start.c
Purpose     : GUIDEMO initialization
----------------------------------------------------------------------
*/

#include "GUIDEMO.h"

/*********************************************************************
*
*       MainTask
*/
void MainTask(void) {
  #if GUI_WINSUPPORT
    WM_SetCreateFlags(WM_CF_MEMDEV);
  #endif
  GUI_Init();
  #if GUI_WINSUPPORT
    WM_MULTIBUF_Enable(1);
  #endif
  GUIDEMO_Main();
}

/*************************** End of file ****************************/

 我们把除了MainTask函数以上的部分全部删除,替换为FramewinDLG.c文件里的内容,再对MainTask函数进行适当修改,如下:

/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.24                          *
*        Compiled Jan 27 2014, 11:28:24                              *
*        (c) 2013 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: [email protected]       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x02)
#define ID_CHECKBOX_0 (GUI_ID_USER + 0x03)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)


// 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, 320, 240, 0, 0x64, 0 },
	{ BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 96, 24, 80, 20, 0, 0x0, 0 },
	{ CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 97, 53, 80, 20, 0, 0x0, 0 },
	{ DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 104, 90, 80, 19, 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_SetText(hItem, "HelloWorld");
		FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
		//
		// Initialization of 'Checkbox'
		//
		hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
		CHECKBOX_SetText(hItem, "Check");
		// 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_CHECKBOX_0: // Notifications sent by 'Checkbox'
			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_DROPDOWN_0: // Notifications sent by 'Dropdown'
			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_SEL_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;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/


/*********************************************************************
*
*       MainTask
*/
void MainTask(void) {
  #if GUI_WINSUPPORT
    WM_SetCreateFlags(WM_CF_MEMDEV);
  #endif
  GUI_Init();
  #if GUI_WINSUPPORT
    WM_MULTIBUF_Enable(1);
  #endif
  //GUIDEMO_Main();
	CreateFramewin();
	while (1)
	{
		GUI_Delay(10);
	}
}

/*************************** End of file ****************************/

修改后运行就可以得到如下的结果了,是我们在GUIBuilder中设计的界面。 

emWin专题——emWin简介及模拟器的使用_第8张图片

 

四、emWin查看器的使用

 emWIn查看器和GUIBuilder都是在同一个目录下的,叫emWinView.exe,运行界面如下图所示:

emWin专题——emWin简介及模拟器的使用_第9张图片

 无论我们emWin模拟器是先运行还是后运行,emWin查看器都可以捕捉到模拟器的运行画面。查看器上面有很多的功能可以使用,有助于调试,在多层显示的时候比较有用。

 

五、本文资料汇总

链接:https://pan.baidu.com/s/1L6EZrFFqEyOFIoCrkOVpaQ 提取码:zi6r

 

你可能感兴趣的:(emWin专题)