Day4-STemWin图形界面库

1.主界面设计

GUI builder 设计

  1. 放置window控件
    1. 放置window控件
    2. 调整window控件尺寸为480*272
    3. 设置背景色

1565077085659

  1. 放置button控件

    1. 根据项目需求放置6个button控件

    2. 选中其中一个button控件,调整参数

      1. 调整button位置,把6个button均匀分布到window中
      2. 设置button尺寸为80*80,便于放置图片

1565077504630

  1. 生成C代码

    1. 点击file/save,保存文件
    2. C代码分析
// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"

/*********************************************************************
*
*       Defines   emwin为每一个控件分配一个ID号,之后针对控件的操作,都是针对这个		           ID进行操作!
*
**********************************************************************
*/
#define ID_WINDOW_0             (GUI_ID_USER + 0x00)
#define ID_BUTTON_0             (GUI_ID_USER + 0x07)
#define ID_BUTTON_1             (GUI_ID_USER + 0x08)
#define ID_BUTTON_2             (GUI_ID_USER + 0x09)
#define ID_BUTTON_3             (GUI_ID_USER + 0x0A)
#define ID_BUTTON_4             (GUI_ID_USER + 0x0B)
#define ID_BUTTON_5             (GUI_ID_USER + 0x0C)
/*********************************************************************
*
*       窗口控件列表  
*/
/* 控件描述结构体
struct GUI_WIDGET_CREATE_INFO_struct {
  GUI_WIDGET_CREATE_FUNC * pfCreateIndirect;	//控件创建类型句柄
  const char             * pName;            // 控件名称,会显示到控件上
  I16                      Id;               // 控件ID号
  I16                      x0;               // 控件X轴位置
  I16                      y0;               // 控件Y轴位置
  I16                      xSize;            // 控件X长度
  I16                      ySize;            // 控件y长度
  U16                      Flags;            // 指定空间标志
  I32                      Para;             // 指定控件参数
  U32                      NumExtraBytes;    // 扩展字节数
};
一般都由gui builder 自动创建,特殊情况下,自行修改
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 480, 272, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_0, 30, 25, 100, 100, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_1, 190, 25, 100, 100, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_2, 350, 25, 100, 100, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_3, 30, 150, 100, 100, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_4, 190, 150, 100, 100, 0, 0x0, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_5, 350, 150, 100, 100, 0, 0x0, 0 },
};
/*********************************************************************
*
*       _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  WM_HWIN hItem;
  int     NCode;
  int     Id;
  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG://初始化对话框事件
    //
    // 初始化窗口
    //
    hItem = pMsg->hWin;
    //设置窗口背景色
    WINDOW_SetBkColor(hItem, GUI_MAKE_COLOR(0x004F2102));
    break;
  case WM_NOTIFY_PARENT://子窗口变化事件
    Id    = WM_GetId(pMsg->hWinSrc);//获取子窗口ID
    NCode = pMsg->Data.v;//获取事件消息
    switch(Id) {//遍历窗口ID
    case ID_BUTTON_0: // Notifications sent by ''
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED://按键按下
        break;
      case WM_NOTIFICATION_RELEASED://按键释放
        break;
      }
      break;
    case ID_BUTTON_1: // Notifications sent by ''
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
        break;
      case WM_NOTIFICATION_RELEASED:
        break;
      }
      break;
    case ID_BUTTON_2: // Notifications sent by ''
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
        break;
      case WM_NOTIFICATION_RELEASED:
        break;
      }
      break;
    case ID_BUTTON_3: // Notifications sent by ''
      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_BUTTON_4: // Notifications sent by ''
      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_BUTTON_5: // Notifications sent by ''
      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;
    // 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
*
**********************************************************************
*/
/*********************************************************************
*
*       创建窗口
*/
WM_HWIN CreateWindow(void);
WM_HWIN CreateWindow(void) {
  WM_HWIN hWin;
  /*
    创建对话框   
  	参数
  	1:定义对话框中所要包含的小工具的资源表的指针
    2:对话框中所包含的小工具的总数
    3:应用程序特定回调函数 (对话框过程函数)的指针。
    4:父窗口的句柄 ( 0 表示没有父窗口)。
    5:对话框相对于父窗口的 X 轴位置。
    6:对话框相对于父窗口的 Y 轴位置
  */
  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 ****************************/

功能实现-window环境

下载emwin仿真和模拟器

仿真模拟器是在window开发环境下的C工程,可以通过VC6或者codeblockd IDE环境下进行开发仿真

  1. 下载地址
    https://www.segger.com/downloads/emwin/

根据自己使用的STemwin库,进行下载,我们采用V5.44版本

1565258572757

  1. 添加工程到codeblockd
    1. 打开外部工程
    2. 选择.cbp文件

1565259493557

  1. 添加工程到codeblockd
    1. 点击编译运行按钮
    2. 生成模拟器

1565259639422

修改模拟器原始工程
  1. 把无用的代码移除工程

1565259773607

  1. 添加WindowDLG.c到工程中
    1. 首先复制WindowDLG.c到SeggerEval_WIN32_MSVC_MinGW_GUI_V544\Application目录下

    2. 添加WindowDLG.c到工程中

    3. 选择Application工程目录,新建mainTask.c
      1565260425405

    4. 在mainTask.c添加代码


#include "dialog.h"//包含window对话框 头文件
void MainTask(void)

{

    GUI_Init();                     //初始化emWin/ucGUI
    CreateWindow();                 //创建窗体,父窗体是桌面背景
    while(1) {GUI_Delay(20);}       //调用GUI_Delay函数延时20MS(最终目的是调用GUI_Exec()函数)

}


  1. 点击编译运行
    1565260549963
按钮添加效果图
搜索像素100x100图片,尽量为png格式
  1. 搜索温度、湿度、风扇、LED、光照、蜂鸣器图片
  2. 统一把图片修改为100x100像素

1565260852666

把图片修改为位图格式
  1. 选择位图生成工具

1565261186439

  1. 进行位图生成

    1. File->Open 打开图片
    2. Image->Convert to-> 16Bit color 565 把图片转换为RGB565格式(跟开发板LCD屏幕匹配)
    3. File->Save as 保存文件
![1565261433306](https://img-blog.csdnimg.cn/img_convert/5666e97095edaec6e59734db56c8d67c.png)

1565261457087

  1. 把生成的位图代码添加到工程中
    1. 复制位图文件到工程文件中
    2. 添加位图文件到工程里
功能代码修改
  1. 在WindowDLG.c里声明位图全局变量(每一幅图片都生成了一个位图结构体)

/*********************************************************************
*
*       Static data
*
**********************************************************************
*/

// USER START (Optionally insert additional static data)

extern GUI_CONST_STORAGE GUI_BITMAP bmalarm;
extern GUI_CONST_STORAGE GUI_BITMAP bmfan;
extern GUI_CONST_STORAGE GUI_BITMAP bmhum;
extern GUI_CONST_STORAGE GUI_BITMAP bmled;
extern GUI_CONST_STORAGE GUI_BITMAP bmlinght;
extern GUI_CONST_STORAGE GUI_BITMAP bmtemp;
// USER END


  1. 在对话框初始化中添加按钮位图转换
// USER START (Optionally insert additional code for further widget initialization)
	//根据空间ID,获取空间句柄
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
    //设置按钮未按下时,显示温度图片
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmtemp);
    //
    // Initialization of 'Button_fan'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmfan);
    //
    // Initialization of 'Button_hum'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmhum);
    //
    // Initialization of 'Button_led'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmled);
    //
    // Initialization of 'Button_alarm'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_4);
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmalarm);
    //
    // Initialization of 'Button_light'
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_5);
    BUTTON_SetBitmap(hItem, BUTTON_BI_UNPRESSED, &bmlinght);

    // USER END
  1. 点击编译运行

1565262348010

为按钮添加点击效果
  1. 生成颜色为蓝色的位图文件 blue.c
  2. 在对话框初始化中添加按钮位图转换
 BUTTON_SetBitmap(hItem, BUTTON_BI_PRESSED, &bmblue);

功能实现开发板环境

代码移植
  1. 复制Application文件夹到SmartClassRoom\Middlewares\Third_Party\STemWin目录下

2.图形界面(GUI)编程介绍

GUI开发流程

image-20200415112229887

emWin-GUI库

emWin应用场景

image-20200415135902244

emWin介绍

image-20200415135956781

STemWin

image-20200415140145692

emWin开发流程

image-20200415140407709

LCD怎么驱动

常见的TFT-LCD屏

image-20200415140509693

两种TFT-LCD驱动接口

image-20200415140531408

LCD驱动程序

#ifndef __LCD_H__
#define __LCD_H__   
#include "stm32f4xx_hal.h"
void lcd_clear(uint16_t Color);
void lcd_init(void);
void write_data_Prepare(void);
unsigned short lcd_read_gram(unsigned int x,unsigned int y);
void LCD_DrawPoint(uint16_t xsta, uint16_t ysta, uint16_t color);
void LCD_ShowString(uint16_t x0, uint16_t y0, uint8_t *pcStr, uint16_t PenColor, uint16_t BackColor);
void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t colour);
#endif

3.emWin移植上

STemWin结构框架

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CRC开启

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SRAM 写操作要使能

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

获取STemWin源码文件

STemWin默认在STM32CUBEMX文档下

例如C:\Users\Think\STM32Cube\Repository\STM32Cube_FW_F4_V1.24.1\Middlewares\ST\STemWin

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

emWin移植到项目工程

  1. 复制STemWin源码到项目工程中
    工程目录:SmartClassRoom\Middlewares\Third_Party\STemWin

  2. 在keil工程中添加相关文件

    1. 新建工作组:Middlewares/STemWin
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    2. 添加需要编译的C和库文件

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文件名称文件描述
GUI_X_OS.cOS支持文件,不需要修改
GUIConf.cGUI配置文件,主要用于GUI内存块初始化
GUIDRV_Template.cGUI驱动模块,主要针对LCD操作接口
LCDConf_FlexColor_Template.cGUI显示配置文件,主要用于LCD参数配置,初始化
GUI_X_Touch_Analog.c需要自己单独定义,用于触摸笔驱动
STemWin_CM4_OS_wc16_ot.a基于Cortex-M4驱动库,STemWin源码不开放
  1. 修改库文件格式(keil默认不识别.a文件格式,需要我们手动配置)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

移植lcd和touch驱动文件

  1. 添加lcd.c和Touch.c到Src目录下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 添加lcd.h和Touch.h到Inc目录下
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.emWin移植下

emWin LCD驱动适配

修改GUIConf.c

#include "GUI.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES    (512*1024)		 //定义外部存储器大小
#define GUI_BLOCKSUZE   (0X80)			//定义最小内存库操作大小
#define SRAM_BANK_ADDR  ((U32)0x68000000)	//定义外部存储器首地址

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   available memory for the GUI.
*/
void GUI_X_Config(void) {
  //
  // 32 bit aligned memory area
  //
	volatile U32* aMemory = (volatile U32*)(SRAM_BANK_ADDR);
  //
  // Assign memory to emWin
  //分配GUI存储器首地址及最小操作内存块大小
  GUI_ALLOC_AssignMemory((void *)aMemory, GUI_NUMBYTES);
  GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSUZE);
  //
  // Set default font
  //
  GUI_SetDefaultFont(GUI_FONT_32_1);
}

修改GUIDRV_Template.c

只需要完成画点和读取点操作即可

/*********************************************************************
*
*       _SetPixelIndex
*
* Purpose:
*   Sets the index of the given pixel. The upper layers
*   calling this routine make sure that the coordinates are in range, so
*   that no check on the parameters needs to be performed.
*/
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    GUI_USE_PARA(PixelIndex);
    {
      //
      // Write into hardware ... Adapt to your system
      //添加lcd画点接口
      LCD_DrawPoint(x,y,PixelIndex);
      // TBD by customer...
      //
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
}
/*********************************************************************
*
*       _GetPixelIndex
*
* Purpose:
*   Returns the index of the given pixel. The upper layers
*   calling this routine make sure that the coordinates are in range, so
*   that no check on the parameters needs to be performed.
*/
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
  unsigned int PixelIndex;
    //
    // Convert logical into physical coordinates (Dep. on LCDConf.h)
    //
    #if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
      int xPhys, yPhys;

      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
    #else
      #define xPhys x
      #define yPhys y
    #endif
    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    {
      //
      // Write into hardware ... Adapt to your system
      //添加lcd读取点接口
      PixelIndex = lcd_read_gram(x,y);
      
      // TBD by customer...
      //
      PixelIndex = 0;
    }
    #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
      #undef xPhys
      #undef yPhys
    #endif
  return PixelIndex;
}

修改LCDConf_FlexColor_Template.c

  1. 定义显示尺寸 480*272
  2. 定义触摸笔X,Y AD测量值(需要自己测量获得)
  3. 添加触摸笔校准函数
  4. 添加lcd初始化函数

#include "GUI.h"
#include "GUIDRV_FlexColor.h"
#include "lcd.h"

/*********************************************************************
*
*       Layer configuration (to be modified)
*
**********************************************************************
*/

//
// Physical display size
//
#define XSIZE_PHYS  480 //  屏幕X坐标长度
#define YSIZE_PHYS  272 //  屏幕Y坐标长度


#define GUI_TOUCH_AD_Y_TOP 170		// 屏幕X0点坐标AD值
#define GUI_TOUCH_AD_Y_BOTTOM 1900	// 屏幕X480点坐标AD值
#define GUI_TOUCH_AD_X_LEFT 100		// 屏幕Y0点坐标AD值
#define GUI_TOUCH_AD_X_RIGHT 1930	// 屏幕Y272点坐标AD值

/*********************************************************************
*
*       Configuration checking
*
**********************************************************************
*/
#ifndef   VXSIZE_PHYS
  #define VXSIZE_PHYS XSIZE_PHYS
#endif
#ifndef   VYSIZE_PHYS
  #define VYSIZE_PHYS YSIZE_PHYS
#endif
#ifndef   XSIZE_PHYS
  #error Physical X size of display is not defined!
#endif
#ifndef   YSIZE_PHYS
  #error Physical Y size of display is not defined!
#endif
#ifndef   GUICC_565
  #error Color conversion not defined!
#endif
#ifndef   GUIDRV_FLEXCOLOR
  #error No display driver defined!
#endif

/*********************************************************************
*
*       Public functions
*
**********************************************************************
*/
/*********************************************************************
*
*       LCD_X_Config
*
* Function description:
*   Called during the initialization process in order to set up the
*   display driver configuration.
*
*/
void LCD_X_Config(void) {
  //
  // 配置GUI LCD驱动以及颜色显示方式
  //
  GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
  //
  // 显示尺寸配置
  //
  LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
  LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
	
  //触摸笔校准
  GUI_TOUCH_Calibrate(GUI_COORD_X, 0, 480, GUI_TOUCH_AD_X_LEFT , GUI_TOUCH_AD_X_RIGHT);
  GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, 272, GUI_TOUCH_AD_Y_TOP, GUI_TOUCH_AD_Y_BOTTOM);
  //
  // Orientation
  //
  //
  // Set controller and operation mode
  //
}

/*********************************************************************
*
*       LCD_X_DisplayDriver
*
* Function description:
*   This function is called by the display driver for several purposes.
*   To support the according task the routine needs to be adapted to
*   the display controller. Please note that the commands marked with
*   'optional' are not cogently required and should only be adapted if
*   the display controller supports these features.
*
* Parameter:
*   LayerIndex - Index of layer to be configured
*   Cmd        - Please refer to the details in the switch statement below
*   pData      - Pointer to a LCD_X_DATA structure
*
* Return Value:
*   < -1 - Error
*     -1 - Command not handled
*      0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;
  (void) LayerIndex;
  (void) pData;
  
  switch (Cmd) {
  case LCD_X_INITCONTROLLER: {
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    // ...
		//添加lcd初始化
		lcd_init();
    return 0;
  }
  default:
    r = -1;
  }
  return r;
}

添加GUI_X_Touch_Analog.c

#include "GUI.h"
#include "Touch.h"


void GUI_TOUCH_X_ActivateX(void) 
{

}

void GUI_TOUCH_X_ActivateY(void)
{

}

//获取X坐标AD值
int  GUI_TOUCH_X_MeasureX(void) 
{
	return XPT_Read_XY(CMD_RDX);
}

//获取Y坐标AD值
int  GUI_TOUCH_X_MeasureY(void) 
{	
	return XPT_Read_XY(CMD_RDY);
}

emWin测试程序编写

测试程序编写

/* USER CODE BEGIN Header_Touch_Task */
/**
  * @brief  Function implementing the TouchTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_Touch_Task */
void Touch_Task(void const * argument)
{

	GUI_PID_STATE State;    
                 
//  /* init code for FATFS */
//  MX_FATFS_Init();

//  /* init code for LWIP */
//  MX_LWIP_Init();


  GUI_Init();
  GUI_SetBkColor(GUI_BLUE);
  GUI_SetFont(GUI_FONT_32_1);
  GUI_SetColor(GUI_YELLOW);
  GUI_Clear();	
  /* Infinite loop */
  for(;;)
  {			
  		//执行触摸笔检测
		GUI_TOUCH_Exec();	
        //获取触摸笔状态值
		GUI_TOUCH_GetState(&State);
		//是否按下
		if(State.Pressed){
			//打印触摸笔坐标信息
			GUI_DispStringAt("X:",0,0);
			GUI_DispDecAt(State.x,32,0,4);
			GUI_DispStringAt("Y:",0,24);
			GUI_DispDecAt(State.y,32,24,4);			
		}
		osDelay(10);
	}
  /* USER CODE END Touch_Task */
}

测试结果

当触摸笔按下时,显示X(0-480)和Y(0-272)坐标信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.emWin开发环境搭建

开发环境介绍

CodeBlocks

image-20200416102002472

GUIBuilder

image-20200416102158672

Simulation(模拟器)

image-20200416102355147

emwin Simulation (模拟器)

仿真模拟器是在window开发环境下的C工程,可以通过VC6或者codeblockd IDE环境下进行开发仿真

  1. 下载地址
    https://www.segger.com/downloads/emwin/

根据自己使用的STemwin库,进行下载,我们采用V5.44版本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 添加工程到codeblockd
    1. 打开外部工程
    2. 选择.cbp文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 添加工程到codeblockd
    1. 点击编译运行按钮
    2. 生成模拟器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GUIBuilder 制作界面

Created with Raphaël 2.3.0 放置窗口 放置按钮 放置文本 生成代码

image-20200416110044077

界面添加到模拟器

修改模拟器原始工程

  1. 把无用的代码移除工程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 添加WindowDLG.c到工程中
    1. 首先复制WindowDLG.c到SeggerEval_WIN32_MSVC_MinGW_GUI_V544\Application目录下

    2. 添加WindowDLG.c到工程中

    3. 选择Application工程目录,新建mainTask.c
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    4. 在mainTask.c添加代码


#include "dialog.h"//包含window对话框 头文件
void MainTask(void)

{

    GUI_Init();                     //初始化emWin
    CreateWindow();                 //创建窗体,父窗体是桌面背景
    while(1) {GUI_Delay(20);}       //调用GUI_Delay函数延时20MS(最终目的是调用GUI_Exec()函数)

}

6.emWin运行原理分析

emWin使用说明书

image-20200424145208980

emWin初始化

image-20200424144757569

执行模型

image-20200424145236433

单任务使用注意事项

我们在操作系统下使用emwin,必须要创建一个任务,用来调用emWin函数,并且官方说,此任务的优先级配置为最低
    
 emWin函数指的是什么???

image-20200503154628494

时间调度

emWin运行原理image-20200424145301956

指针输入设备

image-20200424150913387

7.emWin应用编程方法

GUIBuilder

image-20200502012318327

对话框

image-20200502012355310

资源表

资源:我们这个对话框内部的小工具(小窗口)------- window 按钮 文本 图片

image-20200503170039928

窗口管理器

image-20200424174546626

窗口消息

image-20200503170738357

窗口对象

image-20200424174611197

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值