本帖最后由 湛只为无双 于 2016-1-19 21:35 编辑
感谢21IC网,希望大家在看帖子的同时能够给我投上一票,谢谢你们了,https://bbs.21ic.com/icview-1277786-1-1.html,
今天给大家介绍的是之前发布的帖子里面的第二个应用,一个简易的串口接收控制。
首先是主界面,图中的第二按钮,简易串口调试功能,当点击第二个按钮后,进可以进入到串口界面,界面的显示如下:
里面包含有波特率,校验位,数据位和停止位的选择,在选择的旁边是一个编辑框用于显示串口接收到的数据,实现了一个简单的串口接收,下面的按钮主要是打开串口,退出应用和清空数据接收区的。
然后可以选择合适的波特率等,当前只添加了几个常用的波特率,如果需要可以根据自己的需求来自由设定
选择到合适的波特率以后,就可以打开串口了,在打开串口以后就不能更改那几个下拉列表了,也就是显示灰色的图标,当关闭后下拉列表又可以重新使用。
一、程序的概述及介绍:
首先是看下软件的程序源码,通过资源列表建立一些资源数据:
/*********************************************************************
*
* Dialog resource
*
* This table conatins the info required to create the dialog.
* It has been created by ucGUIbuilder.
*/
static const GUI_WIDGET_CREATE_INFO _aDialogTwoCreate[] = {
{ FRAMEWIN_CreateIndirect, "串口调试助手", 0, 0, 0, 800,480,0,0},
{ TEXT_CreateIndirect, "波特率", GUI_ID_TEXT0, 1, 15, 56, 16, 0,0},
{ TEXT_CreateIndirect, "校验位", GUI_ID_TEXT1, 1, 45, 56, 16, 0,0},
{ TEXT_CreateIndirect, "数据位", GUI_ID_TEXT2, 1, 75, 56, 16, 0,0},
{ TEXT_CreateIndirect, "停止位", GUI_ID_TEXT3, 1, 105,56, 16, 0,0},
{ MULTIEDIT_CreateIndirect, "MULTIEDIT", GUI_ID_MULTIEDIT0, 154,12, 630,200,0,0},
{ DROPDOWN_CreateIndirect, "DROPDOWN", GUI_ID_DROPDOWN0, 63, 12, 85, 80, 0,0},
{ DROPDOWN_CreateIndirect, "DROPDOWN", GUI_ID_DROPDOWN1, 63, 42, 85, 80, 0,0},
{ DROPDOWN_CreateIndirect, "DROPDOWN", GUI_ID_DROPDOWN2, 63, 72, 85, 80, 0,0},
{ DROPDOWN_CreateIndirect, "DROPDOWN", GUI_ID_DROPDOWN3, 63, 102,85, 80, 0,0},
{ BUTTON_CreateIndirect, "打开", GUI_ID_BUTTON0, 19, 151,114,61, 0,0},
{ BUTTON_CreateIndirect, "退出", GUI_ID_BUTTON1, 19, 309,114,61, 0,0},
{ BUTTON_CreateIndirect, "清空", GUI_ID_BUTTON2, 19, 230,114,61, 0,0},
};
void DialogTwo(void)
{
if(SerialTaskHandle == NULL)
{
xTaskCreate(vDialogSerialTask,( signed portCHAR * )"Serial",512,NULL, tskIDLE_PRIORITY+6, &SerialTaskHandle);
}
GUI_CreateDialogBox(_aDialogTwoCreate, GUI_COUNTOF(_aDialogTwoCreate), &_cbDialogTwoCallback, 0, 0, 0);
}
其中包含了穿件串口接收任务xTaskCreate(vDialogSerialTask,( signed portCHAR * )"Serial",512,NULL, tskIDLE_PRIORITY+6, &SerialTaskHandle)
和界面显示GUI_CreateDialogBox(_aDialogTwoCreate, GUI_COUNTOF(_aDialogTwoCreate), &_cbDialogTwoCallback, 0, 0, 0);
并设置回调函数_aDialogTwoCreate。
在串口接收任务里面主要功能是周期性检测串口的接收标志位,但有数据来临时,就将新的数据添加至MultiEdit编辑框里面
void vDialogSerialTask( void *pvParameters )
{
while(1)
{
if(SerialOpen_flag==1 && hMultiEditRead!=0)
{
if(USART3_RX_STA & 0x8000)
{
USART3_RX_BUF[USART3_RX_STA&0x7fff]=0;
MULTIEDIT_AddText(hMultiEditRead,(const char *)USART3_RX_BUF);
USART3_RX_STA=0;
}
}
else if(hMultiEditRead == 0)
{
SerialTaskHandle = NULL;
vTaskDelete(NULL);
}
vTaskDelay(100);
}
}
二、与STemWin相关的回调函数
STemWin里面比较重要的是就是界面的回调函数机制,是否能够比价好的使用回调函数可以实现很好的界面设计。
首先看下回调函数的内容:
/*********************************************************************
*
* Dialog callback routine
*/
static void _cbDialogTwoCallback(WM_MESSAGE * pMsg)
{
int NCode, Id;
WM_HWIN hWin = pMsg->hWin;
switch (pMsg->MsgId)
{
case WM_INIT_DIALOG:
InitDialog(pMsg);
break;
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch(NCode)
{
case WM_NOTIFICATION_RELEASED:
switch(Id)
{
case GUI_ID_BUTTON0:
DialogTwoSerial_Init(hWin);
break;
case GUI_ID_BUTTON1:
hMultiEditRead = 0;
DialogTwoSerial_Close();
GUI_EndDialog(hWin,0);
break;
case GUI_ID_BUTTON2:
MULTIEDIT_SetText(hMultiEditRead,"");
break;
}
break;
}
break;
default:
WM_DefaultProc(pMsg);
}
}
在回调函数里面,获取到窗口的句柄,然后进行不同消息下系统的响应函数,使用到了switch和case结构,其中第一个case为初始化窗口的回调函数InitDialog(pMsg):/*****************************************************************
** FunctionName:void InitDialog(WM_MESSAGE * pMsg)
** Function: to initialize the Dialog items
**
** call this function in _cbCallback --> WM_INIT_DIALOG
*****************************************************************/
void InitDialog(WM_MESSAGE * pMsg)
{
WM_HWIN hWin = pMsg->hWin;
//
//GUI_ID_DROPDOWN0
//
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"9600");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"14400");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"19200");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"38400");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"56000");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"57600");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),"115200");
DROPDOWN_SetListHeight(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN0),128);
//
//GUI_ID_MULTIEDIT0
//
hMultiEditRead = WM_GetDialogItem(hWin,GUI_ID_MULTIEDIT0);
MULTIEDIT_SetFont(hMultiEditRead,&GUI_FontHZ16);
MULTIEDIT_SetAutoScrollV(hMultiEditRead,1);
MULTIEDIT_SetWrapChar(hMultiEditRead);
MULTIEDIT_SetFocussable(hMultiEditRead,0);
//
//GUI_ID_DROPDOWN1
//
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN1),"NONE");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN1),"EVEN");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN1),"ODD");
DROPDOWN_SetListHeight(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN1),64);
//
//GUI_ID_DROPDOWN2
//
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN2),"8B");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN2),"9B");
DROPDOWN_SetListHeight(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN2),48);
//
//GUI_ID_DROPDOWN3
//
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN3),"1");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN3),"0.5");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN3),"2");
DROPDOWN_AddString(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN3),"1.5");
DROPDOWN_SetListHeight(WM_GetDialogItem(hWin,GUI_ID_DROPDOWN3),80);
}
在初始化中分别添加了不同控件的初始条件,包含有下拉列表的每个选项,这样就实现了不同类型选项的添加。
然后当有按钮的消息发生的时候,就需要对按钮做出响应,这就使用到了WM_NOTIFY_PARENT和WM_NOTIFICATION_RELEASED,本次设计里面主要包含有打开串口和关闭串口,清空串口和退出串口。分别使用到的是不同函数调用,在工程文件里面使用到的是DialogTwoSerial.c这个文件,在这里需要注意的是,如果退出串口一定要关闭串口的接收中断,否则的话会出现死机的情况发生。具体的程序设计请看上一篇帖子上传的数据,里面有已经写好的内容。
工程文件在之前的第一篇帖子里面:【STM32F469I试用】+emWin实战应用①LED控制界面
|
|