1, About emWin
1. The relationship between emWin and ucGUI
I remember that when I first went to university, I came into contact with a graphic interface in the field of single-chip microcomputer called ucGUI, which was also running on STM32. After a while, I found that we all used emwi on the Internet. I learned about the relationship between them, which is actually the same thing. EMWIN is developed on the basis of ucGUI. Both of them are developed by a company (SEEGER). That's right. It's the company that bought the JLINK debugger. Before, the old version of ucGUI was open-source. Later, EMWIN developed to version 5.0 and made a lot of updates, especially the bottom driver. However, emWIn5.xx is fully compatible with the lower version, including ucGUI5.xx. After emWIn5.xx, only the library has no source code, so if you want to understand the underlying implementation, you can see the early version.
2. The relationship between emwi and stemwi
Processors authorized by SEEGER to ST, NXP, Energy Micro and other companies can use EMWIN free of charge. EMWIN running on ST processor is called stemwin, which optimizes the controller of ST. For certain protection measures, the library of stemwin cannot run on the processor of other chip manufacturers, because CRC verification should be enabled before initialization of stemwin. If it is not enabled, smemwin cannot be started. The KEIL MDK installation directory also contains the software package of EMWIN. You need to register RL-ARM to use it.
2, Use of simulator
1. emWin simulator
According to the normal thinking, we should write the code on KEIL, then compile the project, download the program to the development board to check the phenomenon, but for the embedded system, this debugging method is too slow. If we can directly simulate the running on PC, we can save the time of downloading the code and debugging on the development board, and the compiling speed of simulation is faster than keil Add fast.
At present, emwi has been updated to version 6.10, which can be found on the official website( SEEGER official website )Download to different versions of emwi simulator and related manuals. Before downloading, you need to register an account. Because of the Internet, the download speed may be slow. This document is also included in the link to the final materials. Now I use V5.32 to show it. The directory structure is as follows:
My computer is installed with VS2013. Double click the sln file directly to open the project. If you are prompted to upgrade any components, click OK.
Then you can see the official demo running by directly debugging.
2. emWin + uCosIII simulator
This is the information I found on the Internet. I saw that someone transplanted UCOS III and emWin simulator together. I feel very good. Because sometimes we may use embedded operating system and graphical interface together, and emWin also supports operating system. This resource will be given at the end of this article. Errors may be reported during VS compilation: error 206 error LNK1281: unable to generate SAFESEH image. The solution is: select an item, right-click menu - > properties - > linker - > command line, enter / SAFESEH:NO in the "additional options" box, and then click apply.
3, The use of GUIBuilder
It's not convenient to have a PC simulator, because it's only convenient for us in the run-time phase, and can it provide us the same convenience in the code writing phase? Just like QT, C ා and other interface development software, it supports the function of user drag control to generate code. GUIBuilder is to complete this function. This tool is available in the installation directory of KEIL. See the following figure for the specific path.
Double click GUIBuilder.exe to see the editing interface.
Drag a few controls to practice:
Select File - > save in the upper left corner to see that a. c file FramewinDLG.c is generated in the current directory:
The code is as follows:
/********************************************************************* * * * 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: support@segger.com * * * ********************************************************************** */ // 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 ****************************/
In the code, the code to generate the interface is written. Only the last CreateFramewin function needs to be called at runtime to generate the interface. Next, let's look at the code of the simulator. It calls the GUI init() and the function to generate the interface in the guidemo start. C file. To run the interface we just created, we need to call the CreateFramewin function in this function instead of the official demo interface. GUIDEMO_Start.c is as follows:
/********************************************************************* * SEGGER Microcontroller GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1996 - 2015 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: www.segger.com Support: support@segger.com * * * ********************************************************************** ** 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 ****************************/
We delete all the parts above the MainTask function, replace them with the contents in the FramewinDLG.c file, and then modify the MainTask function as follows:
/********************************************************************* * * * 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: support@segger.com * * * ********************************************************************** */ // 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 ****************************/
After modification and operation, we can get the following results, which is the interface we designed in GUIBuilder.
4, Use of emWin viewer
emWIn viewer and GUIBuilder are in the same directory, called emWinView.exe. The running interface is as follows:
Whether we run the emWin simulator first or later, the emWin viewer can capture the running picture of the simulator. There are many functions on the viewer that can be used, which is helpful for debugging and is more useful in multi-layer display.
5, Data summary
Link: https://pan.baidu.com/s/1L6EZrFFqEyOFIoCrkOVpaQ extraction code: zi6r