【emWin实战教程V2.0】第6章 GUIBuilder5.32的使用方法
完整65章+12章附件教程下载地址:
http://bbs.armfly.com/read.php?tid=19834
第6章 GUIBuilder5.32的使用方法
本小节主要带领大家学习GUIBuilder5.32的使用,很好的利用这个软件,能使得STemWin界面设计事半功倍。
6.1 初学者重要提示
6.2 GUIBuilder5.32的使用步骤
6.3 emWin5.32模拟器上运行GUIBuilder5.32生成的代码
6.4 移植GUIBuilder5.32生成的代码到开发板
6.5 实验例程说明(RTOS)
6.6 实验例程说明(裸机)
6.7 总结
6.1 初学者重要提示
1、 模拟器使用的emWin是5.32版本,如果SEGGER官网以后有更高版本的推出,使用方法是一样的。另外,开发板用的STemWin版本也是5.32,如果STemWin有升级版发布,使用方法也是相同的。
2、 模拟器的运行是采用的VC6.0精简版,大小仅16MB,支持XP系统,WIN7的32位和64位系统,WIN8和WIN10不支持,下载地址提供下:http://bbs.armfly.com/read.php?tid=10428。实际测试比较好用。默认情况下,本教程运行模拟器,全部用的是此软件。
如果用的是VS2013,参照这里的方法设置:http://bbs.armfly.com/read.php?tid=10656。
3、 对于初学者来说,务必要掌握GUIBuilder的使用方法,以及将其生成的代码移植到模拟器和开发板的方法。具体用到的emWin功能会在后面的章节中逐一讲解,本章节主要是学习使用方法。
6.2 GUIBuilder5.32的使用步骤
首先需要大家按照第2章2.3.4小节的说明下载STemWin的软件包,其中GUIBuilder5.32位于路径:STM32Cube_FW_F4_V1.13.0\Middlewares\ST\STemWin\Software里面
6.2.1 第一步:建立一个对话框
1、 找到GUIBuilder后,打开这个软件,并按照如下方式建立一个对话框。
2、 修改对话框大小为800*480。
3、 下面设置对话框标题的字体,对齐方式,和显示的文本。首先,在建立的对话框上面右击鼠标,选择Set font。
弹出如下界面,并选择字体GUI_FONT_32B_ASCII,点击OK。
设置好字体以后再设置对齐方式,还是右击鼠标,选择Set text alignment,并选择居中。
配置完成后,上面的字体Framewin字体会居中显示,然后还是鼠标右击,选择Set title text,并更改Framewin为armfly,修改的地方在左下角:
设置好以后,对话框就算建立完毕。
6.2.2 第二步:在对话框上面建立按钮
按钮的建立方法和上面的对话框是一样的。按钮上面的字体大小和显示内容,大家可以任意设置。按钮上的文本不支持对齐方式设置,默认是居中显示,这里是显示字符armfly,字体GUI_FONT_24B_ASCII,建立后的效果如下所示:
对于建立的按钮控件,用户可以任意拖动,并通过鼠标调整其大小,调整方法如下:先左击选中相应控件,会出现绿色的边框,在边框的地方拖动鼠标即可修改大小
6.2.3 第三步:在对话框上面建立滚动条
同样的方法,添加滚动条后的效果如下所示:
6.2.4 第四步:在对话框上面建立滑动条
同样的方法,添加滑动条后显示效果如下:
6.2.5 第五步:建立好后点击File->save
保存方法如下:
保存后生成的文件在GUIBuilder5.32软件所在的文件夹里面:
6.3 emWin5.32模拟器上运行GUIBuilder5.32生成的代码
这里为大家讲解emWin5.32上面运行GUIBuilder5.32所生成代码的方法。另外,很多没有用过VC6.0的初学者不知道怎么使用,这里就简单的啰嗦下。
首先,按照第2章的2.3.3小节所讲述的方法,将模拟器下载下来,然后解压模拟器软件包,VC6.0要打开的工程文件名是如下这个文件(先将VC6.0打开,然后将这个文件拖动到VC6.0上即可):
VC6.0打开emWin5.32模拟器后,左侧栏是这样的:
展开上面截图的‘+’后就可以看到:
然后再展开Application文件分组:
这里打开GUIDEMO_Start.c,将此文件里面的内容全部删掉,然后将本章节6.2.5小节里面生成的FramewinDLG.c文件里的所有内容复制到GUIDEMO_Start.c文件里,仅这样程序还是不能够运行的,需要在GUIDEMO_Start.c文件的内容末尾再加入如下代码就可以运行了。
void MainTask(void)
{
WM_SetCreateFlags(WM_CF_MEMDEV);
GUI_Init();
CreateFramewin();
while(1)
{
GUI_Delay(10);
}
}
GUIDEMO_Start.c文件中完整的内容如下:
// USER START (Optionally insertadditional includes)
// USER END
#include "DIALOG.h"
#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 insertadditional defines)
// USER END
// USER START (Optionally insertadditional static data)
// USER END
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 },
// USERSTART (Optionally insert additional widgets)
// USEREND
};
// USER START (Optionally insertadditional static code)
// USER END
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWINhItem;
int NCode;
int Id;
// USER START (Optionally insert additional variables)
// USER END
switch(pMsg->MsgId) {
caseWM_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;
caseWM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode =pMsg->Data.v;
switch(Id) {
caseID_BUTTON_0: // Notifications sent by 'Button'
switch(NCode) {
caseWM_NOTIFICATION_CLICKED:
// USER START (Optionally insert code for reacting on notificationmessage)
// USER END
break;
caseWM_NOTIFICATION_RELEASED:
// USER START(Optionally insert code for reacting on notification message)
// USER END
break;
// USER START (Optionally insert additional code for furthernotification handling)
// USER END
}
break;
caseID_SCROLLBAR_0: // Notifications sent by 'Scrollbar'
switch(NCode) {
caseWM_NOTIFICATION_CLICKED:
// USER START(Optionally insert code for reacting on notification message)
// USER END
break;
caseWM_NOTIFICATION_RELEASED:
// USER START (Optionally insert code for reacting on notificationmessage)
// USER END
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
// USER START (Optionally insert code for reacting on notificationmessage)
// USER END
break;
// USER START (Optionally insert additional code for furthernotification handling)
// USER END
}
break;
caseID_SLIDER_0: // Notifications sent by 'Slider'
switch(NCode) {
caseWM_NOTIFICATION_CLICKED:
// USER START (Optionally insert code for reacting on notificationmessage)
// USER END
break;
caseWM_NOTIFICATION_RELEASED:
// USER START(Optionally insert code for reacting on notification message)
// USER END
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
// USER START (Optionally insert code for reacting on notificationmessage)
// 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;
}
}
WM_HWIN CreateFramewin(void);
WM_HWIN CreateFramewin(void) {
WM_HWINhWin;
hWin =GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog,WM_HBKWIN, 0, 0);
returnhWin;
}
void MainTask(void)
{
WM_SetCreateFlags(WM_CF_MEMDEV);
GUI_Init();
CreateFramewin();
while(1)
{
GUI_Delay(10);
}
}
点击这里进行编译和运行:
实际显示效果如下:
此处初学者会有疑问,我们设置界面分辨率不是800*480吗,怎么显示的不全?这是因为默认的界面分辨率是320*240。第8章跟大家讲emWin模拟器的使用方法时,再详细讲解如何修改显示分辨率。
6.4 移植GUIBuilder5.32生成的代码到开发板
移植到模拟器跟移植到开发板上的方法是一样的,先将本章节6.2.5小节里面生成的FramewinDLG.c文件里的所有内容复制到MDK或者IAR工程模板的MainTask.c文件里(这里以带RTOS的emWin模板为例进行截图,裸机版本是一样的,也是这个文件):
仅这样程序还是不能够运行的,需要在MainTask.c文件的内容末尾再加入如下代码就可以运行了。
void MainTask(void)
{
WM_SetCreateFlags(WM_CF_MEMDEV);
GUI_Init();
CreateFramewin();
while(1)
{
GUI_Delay(10);
}
}
本章6.5小节和6.6小节讲解的实验例程都是用的这个代码,不过修改了注释使其更加规范并修改了MainTask函数,使emWin在STM32F429/439的运行性能发挥到最佳,修改后的代码如下:
void MainTask(void)
{
GUI_Init();
WM_MULTIBUF_Enable(1);
//TOUCH_Calibration();
CreateFramewin();
while(1)
{
GUI_Delay(10);
}
}
6.5 实验例程说明(RTOS)
配套例子:
V6-502_STemWin实验_GUIBuilder的使用(RTOS)
实验目的:
1. 学习GUIBuilder的使用。
2. emWin功能的实现在MainTask.c文件里面。
实验内容:
1. K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
2. K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
3. 各个任务实现的功能如下:
App Task Start 任务:实现按键和触摸扫描。
App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
App Task UserIF 任务:按键消息处理。
App Task COM 任务:暂未使用。
App Task GUI 任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
STemWin界面显示效果:
800*480分辨率界面效果,小分辨率显示屏仅可以显示一部分。
STemWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1
#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*8)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
LCDConf_Lin_Template.c文件中共12项emWin配置:
#define emWin_Optimize 0
#define XSIZE_PHYS 800
#define YSIZE_PHYS 480
#define NUM_BUFFERS 3
#define NUM_VSCREENS 1
#define BK_COLOR GUI_DARKBLUE
#undef GUI_NUM_LAYERS
#define GUI_NUM_LAYERS 1
#define LCD_LAYER0_FRAME_BUFFER EXT_SDRAM_ADDR
#define LCD_LAYER1_FRAME_BUFFER (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS *YSIZE_PHYS * 4 * NUM_VSCREENS *
NUM_BUFFERS)
#define_CM_ARGB8888 1
#define _CM_RGB888 2
#define _CM_RGB565 3
#define _CM_ARGB1555 4
#define _CM_ARGB4444 5
#define _CM_L8 6
#define _CM_AL44 7
#define _CM_AL88 8
#define COLOR_MODE_0 _CM_RGB565
#define XSIZE_0 XSIZE_PHYS
#define YSIZE_0 YSIZE_PHYS
#define COLOR_MODE_1 _CM_RGB565
#define XSIZE_1 XSIZE_PHYS
#define YSIZE_1 YSIZE_PHYS
#if (COLOR_MODE_0 == _CM_ARGB8888)
#defineCOLOR_CONVERSION_0 GUICC_M8888I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_32
#elif (COLOR_MODE_0 == _CM_RGB888)
#defineCOLOR_CONVERSION_0 GUICC_M888
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_24
#elif (COLOR_MODE_0 == _CM_RGB565)
#defineCOLOR_CONVERSION_0 GUICC_M565
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_ARGB1555)
#defineCOLOR_CONVERSION_0 GUICC_M1555I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_ARGB4444)
#defineCOLOR_CONVERSION_0 GUICC_M4444I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_L8)
#defineCOLOR_CONVERSION_0 GUICC_8666
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_8
#elif (COLOR_MODE_0 == _CM_AL44)
#defineCOLOR_CONVERSION_0 GUICC_1616I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_8
#elif (COLOR_MODE_0 == _CM_AL88)
#defineCOLOR_CONVERSION_0 GUICC_88666I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#else
#errorIllegal color mode 0!
#endif
#if (GUI_NUM_LAYERS > 1)
#if (COLOR_MODE_1 == _CM_ARGB8888)
#defineCOLOR_CONVERSION_1 GUICC_M8888I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_32
#elif (COLOR_MODE_1 == _CM_RGB888)
#defineCOLOR_CONVERSION_1 GUICC_M888
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_24
#elif (COLOR_MODE_1 == _CM_RGB565)
#defineCOLOR_CONVERSION_1 GUICC_M565
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_ARGB1555)
#defineCOLOR_CONVERSION_1 GUICC_M1555I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_ARGB4444)
#defineCOLOR_CONVERSION_1 GUICC_M4444I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_L8)
#defineCOLOR_CONVERSION_1 GUICC_8666
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_8
#elif (COLOR_MODE_1 == _CM_AL44)
#defineCOLOR_CONVERSION_1 GUICC_1616I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_8
#elif (COLOR_MODE_1 == _CM_AL88)
#defineCOLOR_CONVERSION_1 GUICC_88666I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#else
#errorIllegal color mode 1!
#endif
#else
#undef XSIZE_0
#undef YSIZE_0
#define XSIZE_0 XSIZE_PHYS
#define YSIZE_0 YSIZE_PHYS
#endif
#ifndef XSIZE_PHYS
#errorPhysical X size of display is not defined!
#endif
#ifndef YSIZE_PHYS
#errorPhysical Y size of display is not defined!
#endif
#ifndef NUM_VSCREENS
#defineNUM_VSCREENS 1
#else
#if(NUM_VSCREENS <= 0)
#errorAt least one screeen needs to be defined!
#endif
#endif
#if (NUM_VSCREENS > 1)&& (NUM_BUFFERS> 1)
#errorVirtual screens and multiple buffers are not allowed!
#endif
对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
任务栈大小分配:
μCOS-III任务栈大小在os_cfg.h文件中配置:
#define APP_CFG_TASK_START_STK_SIZE 512u
#define APP_CFG_TASK_MsgPro_STK_SIZE 512u
#define APP_CFG_TASK_COM_STK_SIZE 512u
#define APP_CFG_TASK_USER_IF_STK_SIZE 512u
#define APP_CFG_TASK_GUI_STK_SIZE 1024u
任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start 任务:2048字节。
App Task MspPro任务 :2048字节。
App Task UserIF 任务:2048字节。
App Task COM 任务:2048字节。
App Task GUI 任务:4096字节。
系统栈大小分配:
μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
#define OS_CFG_ISR_STK_SIZE 512u
系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB。
μCOS-III初始化:
int main(void)
{
OS_ERR err;
OSInit(&err);
OSTaskCreate((OS_TCB *)&AppTaskStartTCB,
(CPU_CHAR *)"App TaskStart",
(OS_TASK_PTR )AppTaskStart,
(void *)0,
(OS_PRIO )APP_CFG_TASK_START_PRIO,
(CPU_STK *)&AppTaskStartStk[0],
(CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE / 10,
(CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSStart(&err);
(void)&err;
return(0);
}
硬件外设初始化
硬件外设的初始化是在bsp.c文件实现:
void bsp_Init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
SystemCoreClockUpdate();
bsp_InitUart();
bsp_InitKey();
bsp_InitExtIO();
bsp_InitLed();
bsp_InitI2C();
bsp_InitExtSDRAM();
bsp_DetectLcdType();
TOUCH_InitHard();
LCD_ConfigLTDC();
result =f_mount(&fs, "0:/", 0);
}
五个μCOS-III任务的实现:
static void AppTaskStart (void *p_arg)
{
OS_ERR err;
uint8_t ucCount = 0;
uint8_t ucCount1 = 0;
(void)p_arg;
CPU_Init();
bsp_Init();
BSP_Tick_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err);
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
AppTaskCreate();
AppObjCreate();
while(1)
{
if(g_tTP.Enable== 1)
{
TOUCH_Scan();
ucCount++;
if(ucCount== 10)
{
ucCount= 0;
bsp_KeyScan();
}
OSTimeDly(1, OS_OPT_TIME_DLY,& err);
}
if(g_GT811.Enable== 1)
{
bsp_KeyScan();
ucCount1++;
if(ucCount1== 2)
{
ucCount1= 0;
GT811_OnePiontScan();
}
OSTimeDly(10, OS_OPT_TIME_DLY,& err);
}
if(g_tFT5X06.Enable== 1)
{
bsp_KeyScan();
FT5X06_OnePiontScan();
OSTimeDly(10, OS_OPT_TIME_DLY, &err);
}
}
}
static void AppTaskMsgPro(void *p_arg)
{
uint32_tulStart, ulEnd;
OS_ERR err;
uint8_t Pic_Name = 0;
charbuf[20];
(void)p_arg;
while(1)
{
OSSemPend((OS_SEM*)&SEM_SYNCH,
(OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(CPU_TS )0,
(OS_ERR *)&err);
if(err== OS_ERR_NONE)
{
sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
ulStart= OSTimeGet(&err);
OSSchedLock(&err);
result= f_mkdir("0:/PicSave");
result= f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
GUI_BMP_Serialize(_WriteByte2File,&file);
result = f_close(&file);
OSSchedUnlock(&err);
ulEnd= OSTimeGet(&err);
ulEnd-= ulStart;
App_Printf("截图完成,耗时 = %dms\r\n", ulEnd);
Pic_Name++;
}
}
}
static void AppTaskUserIF(void *p_arg)
{
OS_ERR err;
uint8_t ucKeyCode;
(void)p_arg;
while(1)
{
ucKeyCode= bsp_GetKey();
if(ucKeyCode != KEY_NONE)
{
switch(ucKeyCode)
{
caseKEY_DOWN_K1:
DispTaskInfo();
break;
caseKEY_DOWN_K2:
OSSemPost((OS_SEM*)&SEM_SYNCH,
(OS_OPT )OS_OPT_POST_1,
(OS_ERR *)&err);
break;
default:
break;
}
}
OSTimeDly(20,OS_OPT_TIME_DLY, &err);
}
}
static void AppTaskCOM(void *p_arg)
{
OS_ERR err;
(void)p_arg;
while(1)
{
OSTimeDly(500, OS_OPT_TIME_DLY, &err);
}
}
static void AppTaskGUI(void *p_arg)
{
(void)p_arg;
while(1)
{
MainTask();
}
}
emWin任务的具体实现(在MainTask.c文件里面):
#include "MainTask.h"
#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)
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 },
};
static void _cbDialog(WM_MESSAGE * pMsg)
{
WM_HWINhItem;
int NCode;
int Id;
switch(pMsg->MsgId)
{
caseWM_INIT_DIALOG:
//
//初始化 'Framewin'
//
hItem= pMsg->hWin;
FRAMEWIN_SetFont(hItem,GUI_FONT_32B_ASCII);
FRAMEWIN_SetTextAlign(hItem,GUI_TA_HCENTER | GUI_TA_VCENTER);
FRAMEWIN_SetText(hItem,"armfly");
//
//初始化 'Button'
//
hItem= WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetFont(hItem,GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem,"armfly");
break;
caseWM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode= pMsg->Data.v;
switch(Id)
{
caseID_BUTTON_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
}
break;
caseID_SCROLLBAR_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
break;
}
break;
caseID_SLIDER_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
break;
}
break;
}
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
WM_HWIN CreateFramewin(void)
{
WM_HWINhWin;
hWin =GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog,WM_HBKWIN, 0, 0);
returnhWin;
}
void MainTask(void)
{
GUI_Init();
WM_MULTIBUF_Enable(1);
//TOUCH_Calibration();
CreateFramewin();
while(1)
{
GUI_Delay(10);
}
}
6.6 实验例程说明(裸机)
配套例子:
V6-503_STemWin实验_GUIBuilder的使用(裸机)
实验目的:
1. 学习GUIBuilder的使用。
2. emWin功能的实现在MainTask.c文件里面。
STemWin界面显示效果:
800*480分辨率界面效果,小分辨率显示屏仅可以显示一部分。
STemWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1
#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*8)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
LCDConf_Lin_Template.c文件中共12项emWin配置:
#define emWin_Optimize 0
#define XSIZE_PHYS 800
#define YSIZE_PHYS 480
#define NUM_BUFFERS 3
#define NUM_VSCREENS 1
#define BK_COLOR GUI_DARKBLUE
#undef GUI_NUM_LAYERS
#define GUI_NUM_LAYERS 1
#define LCD_LAYER0_FRAME_BUFFER EXT_SDRAM_ADDR
#define LCD_LAYER1_FRAME_BUFFER (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS *YSIZE_PHYS * 4 * NUM_VSCREENS *
NUM_BUFFERS)
#define_CM_ARGB8888 1
#define _CM_RGB888 2
#define _CM_RGB565 3
#define _CM_ARGB1555 4
#define _CM_ARGB4444 5
#define _CM_L8 6
#define _CM_AL44 7
#define _CM_AL88 8
#define COLOR_MODE_0 _CM_RGB565
#define XSIZE_0 XSIZE_PHYS
#define YSIZE_0 YSIZE_PHYS
#define COLOR_MODE_1 _CM_RGB565
#define XSIZE_1 XSIZE_PHYS
#define YSIZE_1 YSIZE_PHYS
#if (COLOR_MODE_0 == _CM_ARGB8888)
#defineCOLOR_CONVERSION_0 GUICC_M8888I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_32
#elif (COLOR_MODE_0 == _CM_RGB888)
#defineCOLOR_CONVERSION_0 GUICC_M888
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_24
#elif (COLOR_MODE_0 == _CM_RGB565)
#defineCOLOR_CONVERSION_0 GUICC_M565
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_ARGB1555)
#defineCOLOR_CONVERSION_0 GUICC_M1555I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_ARGB4444)
#defineCOLOR_CONVERSION_0 GUICC_M4444I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#elif (COLOR_MODE_0 == _CM_L8)
#defineCOLOR_CONVERSION_0 GUICC_8666
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_8
#elif (COLOR_MODE_0 == _CM_AL44)
#defineCOLOR_CONVERSION_0 GUICC_1616I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_8
#elif (COLOR_MODE_0 == _CM_AL88)
#defineCOLOR_CONVERSION_0 GUICC_88666I
#defineDISPLAY_DRIVER_0 GUIDRV_LIN_16
#else
#errorIllegal color mode 0!
#endif
#if (GUI_NUM_LAYERS > 1)
#if (COLOR_MODE_1 == _CM_ARGB8888)
#defineCOLOR_CONVERSION_1 GUICC_M8888I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_32
#elif (COLOR_MODE_1 == _CM_RGB888)
#defineCOLOR_CONVERSION_1 GUICC_M888
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_24
#elif (COLOR_MODE_1 == _CM_RGB565)
#defineCOLOR_CONVERSION_1 GUICC_M565
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_ARGB1555)
#defineCOLOR_CONVERSION_1 GUICC_M1555I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_ARGB4444)
#defineCOLOR_CONVERSION_1 GUICC_M4444I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#elif (COLOR_MODE_1 == _CM_L8)
#defineCOLOR_CONVERSION_1 GUICC_8666
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_8
#elif (COLOR_MODE_1 == _CM_AL44)
#defineCOLOR_CONVERSION_1 GUICC_1616I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_8
#elif (COLOR_MODE_1 == _CM_AL88)
#defineCOLOR_CONVERSION_1 GUICC_88666I
#defineDISPLAY_DRIVER_1 GUIDRV_LIN_16
#else
#errorIllegal color mode 1!
#endif
#else
#undef XSIZE_0
#undef YSIZE_0
#define XSIZE_0 XSIZE_PHYS
#define YSIZE_0 YSIZE_PHYS
#endif
#ifndef XSIZE_PHYS
#errorPhysical X size of display is not defined!
#endif
#ifndef YSIZE_PHYS
#errorPhysical Y size of display is not defined!
#endif
#ifndef NUM_VSCREENS
#defineNUM_VSCREENS 1
#else
#if(NUM_VSCREENS <= 0)
#errorAt least one screeen needs to be defined!
#endif
#endif
#if (NUM_VSCREENS > 1)&& (NUM_BUFFERS> 1)
#errorVirtual screens and multiple buffers are not allowed!
#endif
对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
栈大小分配:
系统栈大小在startup_stm32f429_439xx.s文件中配置:
栈大小的单位是字节,那么这里配置的系统栈大小就是8192字节。
主函数初始化:
int main (void)
{
bsp_Init();
MainTask();
}
硬件外设初始化
硬件外设的初始化是在bsp.c文件实现:
void bsp_Init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
SystemCoreClockUpdate();
bsp_InitUart();
bsp_InitKey();
bsp_InitExtIO();
bsp_InitLed();
bsp_InitI2C();
bsp_InitExtSDRAM();
bsp_DetectLcdType();
TOUCH_InitHard();
LCD_ConfigLTDC();
result =f_mount(&fs, "0:/", 0);
}
emWin功能的具体实现(在MainTask.c文件里面):
#include "MainTask.h"
#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)
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 },
};
static void _cbDialog(WM_MESSAGE * pMsg)
{
WM_HWINhItem;
int NCode;
int Id;
switch(pMsg->MsgId)
{
caseWM_INIT_DIALOG:
//
// 初始化'Framewin'
//
hItem= pMsg->hWin;
FRAMEWIN_SetFont(hItem,GUI_FONT_32B_ASCII);
FRAMEWIN_SetTextAlign(hItem,GUI_TA_HCENTER | GUI_TA_VCENTER);
FRAMEWIN_SetText(hItem,"armfly");
//
//初始化 'Button'
//
hItem= WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetFont(hItem,GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem,"armfly");
break;
caseWM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode= pMsg->Data.v;
switch(Id)
{
caseID_BUTTON_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
}
break;
caseID_SCROLLBAR_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
break;
}
break;
caseID_SLIDER_0:
switch(NCode)
{
caseWM_NOTIFICATION_CLICKED:
break;
caseWM_NOTIFICATION_RELEASED:
break;
caseWM_NOTIFICATION_VALUE_CHANGED:
break;
}
break;
}
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
WM_HWIN CreateFramewin(void)
{
WM_HWINhWin;
hWin =GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog,WM_HBKWIN, 0, 0);
returnhWin;
}
void MainTask(void)
{
GUI_Init();
WM_MULTIBUF_Enable(1);
//TOUCH_Calibration();
CreateFramewin();
while(1)
{
GUI_Delay(500);
}
}
6.7 总结
本章节为大家讲解了GUIBuilder的使用方法,以及将其移植到开发板和模拟器上的方法,初学者务必要多练习并将其掌握。
评论
重要提示:警惕虚假中奖信息