自定义的小型调试器,类似于printf(基于emwin),通过屏幕显示
可供外部使用的函数有
Hide_Debug()
Show_Debug()
GUI_Printf(const char*,…)
程序代码
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "GUI.h"
#include "WM.h"
//需要中文字库的支持才可以打印中文信息
//仅需要在需要调试信息的部分调用GUI_Printf(const char* fmt,...)进行显示
//与printf的用法一致
//通过调用Show_debug()创建调试窗口
//通过调用Hide_debug()删除窗口
#define MAX_BUF 1024*4
#define ID_FRAMEWIN_0 (GUI_ID_USER+0)
#define ID_MULTIEDIT_0 (GUI_ID_USER+1)
static WM_HWIN error_hwin;
static WM_HTIMER hTimer;
static char debug_infomation[MAX_BUF];
struct __Debug_Ctrl
{
const uint32_t DEBUG_MAX_BUF;
char* const Debug_Buffer;
bool fresh_flag;
}Debug_Ctrl;
struct __Debug_Ctrl Debug_Ctrl=
{
.DEBUG_MAX_BUF=MAX_BUF,
.Debug_Buffer=debug_infomation,
.fresh_flag=false
};
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 300, 300, 300, 0, 0x0, 0 },
{ MULTIEDIT_CreateIndirect, "Multipage", ID_MULTIEDIT_0, 0, 0, 290, 280, 0, 0x0, 0 },
// USER START (Optionally insert additional widgets)
// USER END
};
static void _cbDialog(WM_MESSAGE * pMsg)
{
WM_HWIN hItem;
switch (pMsg->MsgId)
{
case WM_PRE_PAINT:
GUI_MULTIBUF_Begin();
break;
case WM_POST_PAINT:
GUI_MULTIBUF_End();
break;
case WM_INIT_DIALOG:
//
// Initialization of 'Framewin'
//
hItem = pMsg->hWin;
FRAMEWIN_SetFont(hItem, &GUI_FontHZ16);
FRAMEWIN_SetText(hItem,"调试信息");
//
// Initialization of 'Multipage'
//
hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
MULTIEDIT_SetFont(hItem, &GUI_FontHZ16);
MULTIEDIT_SetAutoScrollV(hItem,1);
MULTIEDIT_SetAutoScrollH(hItem,1);
MULTIEDIT_SetMaxNumChars(hItem,Debug_Ctrl.DEBUG_MAX_BUF);
MULTIEDIT_SetBufferSize(hItem,Debug_Ctrl.DEBUG_MAX_BUF);
MULTIEDIT_SetText(hItem,Debug_Ctrl.Debug_Buffer);
MULTIEDIT_SetFocussable(hItem,0);
break;
case WM_NOTIFY_PARENT:
break;
case WM_TIMER:
if(Debug_Ctrl.fresh_flag==true)
{
hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
MULTIEDIT_SetText(hItem,Debug_Ctrl.Debug_Buffer);
Debug_Ctrl.fresh_flag=false;
}
WM_RestartTimer(hTimer,200);
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
void Hide_debug(void)
{
WM_DeleteWindow(error_hwin);
}
void Show_debug(void)
{
WM_HWIN hwin;
error_hwin=GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
WM_SetStayOnTop(error_hwin,1);
hwin=WM_GetClientWindow(error_hwin);
hTimer=WM_CreateTimer(hwin,0,200,0);
}
void GUI_Printf(const char* fmt,...)
{
static uint16_t Debug_num=0;
va_list args;
if(Debug_Ctrl.DEBUG_MAX_BUF-Debug_num<64)//预留出64字节的缓冲区,因此单次使用GUI_Printf不能超过64个字节
{
memset(Debug_Ctrl.Debug_Buffer,'\0',Debug_Ctrl.DEBUG_MAX_BUF);
Debug_num=0;
}
va_start(args,fmt); //取出可变参数
Debug_num+=vsprintf(&Debug_Ctrl.Debug_Buffer[Debug_num],fmt,args);
va_end(args); //恢复堆栈的数据
Debug_Ctrl.Debug_Buffer[Debug_num]='\n'; //向末尾添加换行符
Debug_num++;
Debug_Ctrl.fresh_flag=true;
}