STM32F1xx + uGUI的页面栈管理
源码下载链接: STM32F1xx + uGUI的页面栈管理
一、页面管理相关的结构体
typedef void(* CallbackFunction)(void);
typedef void(* EventFunction)(void * obj, int event);
#pragma pack(1)
typedef struct xUserCallbackFunct
{
CallbackFunction CreatCallback; /* 页面创建回调 */
CallbackFunction RunCallback; /* 页面运行回调 */
CallbackFunction ExitCallback; /* 页面退出回调 */
EventFunction EventCallback; /* 页面事件回调 */
}PageList_Typedef, * PageList_Typedef_t;
typedef struct xUserPageManager
{
u8 OldPage, NewPage, CurPage; /* 旧页面 新页面 当前页面 */
u8 IsPageSta; /* 页面状态 */
u8 MaxPage; /* 最大页面 */
PageList_Typedef * PageList; /* 页面列表基地址 */
u8 * PageStack; /* 页面栈基地址 */
u8 PageStackSize; /* 页面栈大小 */
u8 PageStackTop; /* 页面栈顶 */
u8 (* PageRegister)(struct xUserPageManager * pageManager,
u8 pageID,
CallbackFunction CreatCallback,
CallbackFunction RunCallback,
CallbackFunction ExitCallback,
EventFunction EventCallback); /* 注册页面 */
u8 (* PageClear)(struct xUserPageManager * pageManager, u8 pageID); /* 清空页面 */
u8 (* PagePush)(struct xUserPageManager * pageManager, u8 pageID); /* 页面入栈 */
u8 (* PagePop)(struct xUserPageManager * pageManager); /* 页面出栈 */
void (* PageEventTransmit)(struct xUserPageManager * pageManager, void * obj, int event); /* 页面事件发送 */
void (* PageJump)(struct xUserPageManager * pageManager, u8 pageID); /* 跳转到页面 */
void (* PageManagerRunning)(struct xUserPageManager * pageManager); /* 运行页面管理器 */
void (* PageStackClear)(struct xUserPageManager * pageManager); /* 清空页面栈 */
}PageManager_Typedef, * PageManager_Typedef_t;
#pragma pack()
二、页面是否有效
/* 页面是否有效 */
static u8 ubIsPage_Active(PageManager_Typedef * pageManager, u8 pageID)
{
if (pageID < pageManager->MaxPage)
{
return 1;
}
else
{
return 0;
}
}
三、注册页面
/* 注册页面 */
static u8 ubPageRegister(PageManager_Typedef * pageManager,
u8 pageID,
CallbackFunction creatCallback,
CallbackFunction runCallback,
CallbackFunction exitCallback,
EventFunction eventCallback)
{
/* 页面无效 */
if (!ubIsPage_Active(pageManager, pageID))
{
return 1;
}
/* 注册页面事件 */
pageManager->PageList[pageID].CreatCallback = creatCallback;
pageManager->PageList[pageID].EventCallback = eventCallback;
pageManager->PageList[pageID].ExitCallback = exitCallback;
pageManager->PageList[pageID].RunCallback = runCallback;
return 0;
}
四、清空页面
/* 清空页面 */
static u8 ubPageClear(PageManager_Typedef * pageManager, u8 pageID)
{
/* 页面无效 */
if (!ubIsPage_Active(pageManager, pageID))
{
return 1;
}
/* 清空页面事件 */
pageManager->PageList[pageID].CreatCallback = NULL;
pageManager->PageList[pageID].EventCallback = NULL;
pageManager->PageList[pageID].ExitCallback = NULL;
pageManager->PageList[pageID].RunCallback = NULL;
return 0;
}
五、页面入栈
/* 页面入栈 跳转到该页面 */
static u8 ubPagePush(PageManager_Typedef * pageManager, u8 pageID)
{
/* 页面忙 */
if (pageManager->IsPageSta)
{
return 1;
}
/* 页面无效 */
if (!ubIsPage_Active(pageManager, pageID))
{
return 2;
}
/* 防止栈溢出 栈顶指针大于栈大小 */
if (pageManager->PageStackTop >= (pageManager->PageStackSize - 1))
{
return 3;
}
/* 栈顶指针上移 */
pageManager->PageStackTop++;
/* 页面入栈 */
pageManager->PageStack[pageManager->PageStackTop] = pageID;
/* 跳转到栈顶页面 */
pageManager->PageJump(pageManager, pageManager->PageStack[pageManager->PageStackTop]);
return 0;
}
六、页面出栈
/* 页面出栈 跳转到上一个页面 */
static u8 ubPagePop(PageManager_Typedef * pageManager)
{
/* 页面忙 */
if (pageManager->IsPageSta)
{
return 1;
}
/* 防止栈溢出 */
if (!pageManager->PageStackTop)
{
return 2;
}
/* 清空栈顶页面 */
pageManager->PageStack[pageManager->PageStackTop] = 0;
/* 栈顶指针下移 */
pageManager->PageStackTop--;
/* 跳转到栈顶页面 */
pageManager->PageJump(pageManager, pageManager->PageStack[pageManager->PageStackTop]);
return 0;
}
七、页面事件发送
/* 页面事件发送 */
static void vPageEventTransmit(PageManager_Typedef * pageManager, void * obj, int event)
{
/* 当前页面存在事件回调 */
if(ubIsPage_Active(pageManager, pageManager->CurPage) && (NULL != pageManager->PageList[pageManager->CurPage].EventCallback))
{
/* 将事件发送到当前页面上 */
pageManager->PageList[pageManager->CurPage].EventCallback(obj, event);
}
}
八、跳转到页面
/* 跳转到页面 */
static void vPageJump(PageManager_Typedef * pageManager, u8 pageID)
{
/* 页面忙 */
if(pageManager->IsPageSta)
{
return;
}
/* 页面无效 */
if (!ubIsPage_Active(pageManager, pageID))
{
return;
}
/* 更新页面 */
pageManager->NewPage = pageID;
/* 标记页面忙 */
pageManager->IsPageSta = 1;
}
九、清空页面栈
/* 清空页面栈 */
static void vPageStackClear(PageManager_Typedef * pageManager)
{
u8 i = 0;
/* 页面忙 */
if(pageManager->IsPageSta)
{
return;
}
/* 清空页面栈的所有数据 */
for (i = 0; i < pageManager->PageStackSize; i++)
{
pageManager->PageStack[i] = 0;
}
/* 复位页面栈顶指针 */
pageManager->PageStackTop = 0;
}
十、运行页面管理器
/* 运行页面管理器 */
static void vPageManagerRunning(PageManager_Typedef * pageManager)
{
/* 有新页面加入 */
if(pageManager->NewPage != pageManager->OldPage)
{
/* 标记页面不忙 */
if(!pageManager->IsPageSta)
{
pageManager->IsPageSta = 1;
}
/* 旧页面退出事件 */
if(ubIsPage_Active(pageManager, pageManager->OldPage) && (NULL != pageManager->PageList[pageManager->OldPage].ExitCallback))
{
pageManager->PageList[pageManager->OldPage].ExitCallback();
}
/* 新页面创建事件 */
if(ubIsPage_Active(pageManager, pageManager->NewPage) && (NULL != pageManager->PageList[pageManager->NewPage].CreatCallback))
{
pageManager->PageList[pageManager->NewPage].CreatCallback();
}
/* 更新页面 */
pageManager->CurPage = pageManager->OldPage = pageManager->NewPage;
}
else
{
/* 标记页面不忙 */
if (pageManager->IsPageSta)
{
pageManager->IsPageSta = 0;
}
/* 当前页面运行事件 */
if(ubIsPage_Active(pageManager, pageManager->CurPage) && (NULL != pageManager->PageList[pageManager->CurPage].RunCallback))
{
pageManager->PageList[pageManager->CurPage].RunCallback();
}
}
}
十一、初始化页面管理器
/* 初始化页面栈和列表 */
static void vInit_PageStackList(PageManager_Typedef * pageManager, u8 * pageStackBasicAddr, PageList_Typedef * pageListBasicAddr)
{
pageManager->PageStack = pageStackBasicAddr;
pageManager->PageList = pageListBasicAddr;
}
/* 初始化页面管理 */
static void vInit_PageManager(PageManager_Typedef * pageManager, u8 maxPage, u8 pageStackSize)
{
u8 page = 0;
/* 初始化页面管理事件 */
pageManager->PageEventTransmit = vPageEventTransmit;
pageManager->PageRegister = ubPageRegister;
pageManager->PageManagerRunning = vPageManagerRunning;
pageManager->PageClear = ubPageClear;
pageManager->PagePush = ubPagePush;
pageManager->PageJump = vPageJump;
pageManager->PagePop = ubPagePop;
pageManager->PageStackClear = vPageStackClear;
pageManager->MaxPage = maxPage;
pageManager->NewPage = pageManager->OldPage = NULL;
pageManager->PageStackSize = pageStackSize;
pageManager->IsPageSta = 0;
/* 清空页面事件 */
for (page = 0; page < pageManager->MaxPage; page++)
{
pageManager->PageClear(pageManager, page);
}
/* 清空页面栈 */
pageManager->PageStackClear(pageManager);
}
/* 初始化页面管理器 */
void vInitPageManager(PageManager_Typedef * pageManager, u8 pageMax, u8 pageStackSize, u8 * pageStack, PageList_Typedef * pageList)
{
vInit_PageStackList(pageManager, pageStack, pageList);
vInit_PageManager(pageManager, pageMax, pageStackSize);
}
十二、需要注册的页面
/* 用户页面 */
typedef enum
{
/* 保留 */
PAGE_NONE = 0,
/* 用户页面 */
Page_HomeMenu,
Page_SetMenu,
Page_AboutMenu,
/* 保留 */
USER_PAGE_MAX
}eUserPage;
extern PageManager_Typedef xSuperPageManager;
十三、注册页面
static UG_WINDOW App_Windows[USER_PAGE_MAX] = {0};/* 页面句柄 */
PageManager_Typedef xSuperPageManager = {0};/* 页面管理对象 */
static PageList_Typedef PageListBasicAddr[USER_PAGE_MAX] = {0}; /* 页面事件列表 */
static u8 PageStackBasicAddr[USER_PAGE_MAX - 1] = {0}; /* 页面管理栈地址 */
/* 获取页面句柄 */
UG_WINDOW * pstuGet_Application_Window(u8 pageID)
{
return (pageID < USER_PAGE_MAX) ? &(App_Windows[pageID]) : NULL;
}
/* 页面注册器 */
#define XUSER_PAGE_REG(name)\
do{\
extern void vPageRegister_##name(u8 pageID);\
vPageRegister_##name(Page_##name);\
}while(0)
/* 初始化页面注册 */
void vInit_Page_Register(void)
{
vInitPageManager(&xSuperPageManager, USER_PAGE_MAX, (USER_PAGE_MAX - 1), PageStackBasicAddr, PageListBasicAddr);
XUSER_PAGE_REG(HomeMenu);
XUSER_PAGE_REG(SetMenu);
XUSER_PAGE_REG(AboutMenu);
xSuperPageManager.PagePush(&xSuperPageManager, Page_HomeMenu);
}
十四、首页面
/* 页面窗口 */
static UG_WINDOW * AppHomeWindow = {0};
/* 页面元素 */
#define HOME_WINDOW_OBJ_SIZE (3) /* 界面元素大小 */
UG_OBJECT HomeWindow_OBJ[HOME_WINDOW_OBJ_SIZE] = {0}; /* 元素 */
/* 页面消息处理回调 */
void vHomeWindow_CallBack(UG_MESSAGE * msg)
{
if (msg->type == MSG_TYPE_OBJECT)
{
if (msg->id == OBJ_TYPE_BUTTON)
{
switch(msg->sub_id)
{
case BTN_ID_0:
{
if(msg->event == OBJ_EVENT_CLICKED)
{
}
}
break;
default : break;
}
}
}
}
/* 创建页面 */
static void vHomePage_Creat(void)
{
UG_WindowCreate(AppHomeWindow, HomeWindow_OBJ, HOME_WINDOW_OBJ_SIZE, vHomeWindow_CallBack);/* 创建窗口 */
UG_WindowResize(AppHomeWindow, 0, 0, 479, 319); /* 窗口大小 */
UG_WindowSetTitleTextFont(AppHomeWindow, &FONT_12X20); /* 窗口标题字体 */
UG_WindowSetTitleTextColor(AppHomeWindow, BLUE); /* 窗口标题文本颜色 */
UG_WindowSetTitleColor(AppHomeWindow, GRAY); /* 窗口标题颜色 */
UG_WindowSetTitleText(AppHomeWindow, " STM32F1 uGUI Demo Home Window 1"); /* 窗口标题文本 */
UG_WindowSetBackColor(AppHomeWindow, BROWN); /* 窗口背景色 */
UG_WindowSetForeColor(AppHomeWindow, WHITE); /* 窗口前景色 */
UG_WindowShow(AppHomeWindow); /* 显示窗口 */
dprintf("vHomePage_Creat...\r\n");
}
/* 运行页面 */
static void vHomePage_Run(void)
{
}
/* 退出页面 */
static void vHomePage_Exit(void)
{
dprintf("vHomePage_Exit...\r\n");
}
/* 页面接收事件*/
static void vHomePage_Event(void * obj, int event)
{
dprintf("vHomePage_Event...\r\n");
}
/* 首页 */
void vPageRegister_HomeMenu(u8 pageID)
{
AppHomeWindow = pstuGet_Application_Window(pageID);
if (AppHomeWindow != NULL)
{
xSuperPageManager.PageRegister(&xSuperPageManager, pageID, vHomePage_Creat, vHomePage_Run, vHomePage_Exit, vHomePage_Event);
dprintf("vPageRegister_HomeMenu...\r\n");
}
}
十五、设置页面
/* 页面窗口 */
static UG_WINDOW * AppSetWindow = {0};
/* 页面元素 */
#define SET_WINDOW_OBJ_SIZE (3) /* 界面元素大小 */
UG_OBJECT SetWindow_OBJ[SET_WINDOW_OBJ_SIZE] = {0}; /* 元素 */
/* 页面消息处理回调 */
void vSetWindow_CallBack(UG_MESSAGE * msg)
{
if (msg->type == MSG_TYPE_OBJECT)
{
if (msg->id == OBJ_TYPE_BUTTON)
{
switch(msg->sub_id)
{
case BTN_ID_0:
{
if(msg->event == OBJ_EVENT_CLICKED)
{
}
}
break;
default : break;
}
}
}
}
static u8 SetPageSta = 0;
/* 创建页面 */
static void vSetPage_Creat(void)
{
UG_WindowCreate(AppSetWindow, SetWindow_OBJ, SET_WINDOW_OBJ_SIZE, vSetWindow_CallBack);/* 创建窗口 */
UG_WindowResize(AppSetWindow, 0, 0, 479, 319); /* 窗口大小 */
UG_WindowSetTitleTextFont(AppSetWindow, &FONT_12X20); /* 窗口标题字体 */
UG_WindowSetTitleTextColor(AppSetWindow, BLUE); /* 窗口标题文本颜色 */
UG_WindowSetTitleColor(AppSetWindow, GRAY); /* 窗口标题颜色 */
UG_WindowSetTitleText(AppSetWindow, " STM32F1 uGUI Demo Set Window 2"); /* 窗口标题文本 */
UG_WindowSetBackColor(AppSetWindow, RED); /* 窗口背景色 */
UG_WindowSetForeColor(AppSetWindow, WHITE); /* 窗口前景色 */
UG_WindowShow(AppSetWindow); /* 显示窗口 */
dprintf("vSetPage_Creat...\r\n");
}
/* 运行页面 */
static void vSetPage_Run(void)
{
}
/* 退出页面 */
static void vSetPage_Exit(void)
{
dprintf("vSetPage_Exit...\r\n");
}
/* 页面接收事件*/
static void vSetPage_Event(void * obj, int event)
{
}
/* 设置页 */
void vPageRegister_SetMenu(u8 pageID)
{
AppSetWindow = pstuGet_Application_Window(pageID);
xSuperPageManager.PageRegister(&xSuperPageManager, pageID, vSetPage_Creat, vSetPage_Run, vSetPage_Exit, vSetPage_Event);
}
十六、关于页面
/* 页面窗口 */
static UG_WINDOW * AppAboutWindow = {0};
/* 页面元素 */
#define ABOUT_WINDOW_OBJ_SIZE (3) /* 界面元素大小 */
UG_OBJECT AboutWindow_OBJ[ABOUT_WINDOW_OBJ_SIZE] = {0}; /* 元素 */
/* 页面消息处理回调 */
void vAboutWindow_CallBack(UG_MESSAGE * msg)
{
if (msg->type == MSG_TYPE_OBJECT)
{
if (msg->id == OBJ_TYPE_BUTTON)
{
switch(msg->sub_id)
{
case BTN_ID_0:
{
if(msg->event == OBJ_EVENT_CLICKED)
{
}
}
break;
default : break;
}
}
}
}
/* 创建页面 */
static void vAboutPage_Creat(void)
{
UG_WindowCreate(AppAboutWindow, AboutWindow_OBJ, ABOUT_WINDOW_OBJ_SIZE, vAboutWindow_CallBack);/* 创建窗口 */
UG_WindowResize(AppAboutWindow, 0, 0, 479, 319); /* 窗口大小 */
UG_WindowSetTitleTextFont(AppAboutWindow, &FONT_12X20); /* 窗口标题字体 */
UG_WindowSetTitleTextColor(AppAboutWindow, BLUE); /* 窗口标题文本颜色 */
UG_WindowSetTitleColor(AppAboutWindow, GRAY); /* 窗口标题颜色 */
UG_WindowSetTitleText(AppAboutWindow, " STM32F1 uGUI Demo About Window 3"); /* 窗口标题文本 */
UG_WindowSetBackColor(AppAboutWindow, YELLOW); /* 窗口背景色 */
UG_WindowSetForeColor(AppAboutWindow, WHITE); /* 窗口前景色 */
UG_WindowShow(AppAboutWindow); /* 显示窗口 */
dprintf("vSetPage_Creat...\r\n");
}
/* 运行页面 */
static void vAboutPage_Run(void)
{
}
/* 退出页面 */
static void vAboutPage_Exit(void)
{
}
/* 页面接收事件*/
static void vAboutPage_Event(void * obj, int event)
{
}
/* 关于页 */
void vPageRegister_AboutMenu(u8 pageID)
{
AppAboutWindow = pstuGet_Application_Window(pageID);
xSuperPageManager.PageRegister(&xSuperPageManager, pageID, vAboutPage_Creat, vAboutPage_Run, vAboutPage_Exit, vAboutPage_Event);
}
十七、uGUI初始化
UG_GUI AppGUI; /* UGUI句柄 */
static void vUGUI_DrawPoint(UG_S16 x, UG_S16 y, UG_COLOR c)
{
vTFT_Drawing_Point(x, y, c);
}
static void vUGUI_DrawLine(UG_S16 x1 , UG_S16 y1 , UG_S16 x2 , UG_S16 y2 , UG_COLOR c)
{
vTFT_Drawing_Line(x1, y1, x2, y2, c);
}
static void vUGUI_FillFrame(UG_S16 x1 , UG_S16 y1 , UG_S16 x2 , UG_S16 y2 , UG_COLOR c)
{
vTFT_Set_Window(x1, y1, x2, y2, c);
}
/******************************************************************************************************************************
* 函数名 : vUGUI_Init
* 描 述 : uGUI初始化
******************************************************************************************************************************/
static void vUGUI_Init(void)
{
/* UGUI初始化 */
UG_Init(&AppGUI, vUGUI_DrawPoint, (TFT_XMAX + 1), (TFT_YMAX + 1));
/* 注册驱动函数 */
UG_DriverRegister(DRIVER_DRAW_LINE, (void *)vUGUI_DrawLine);
UG_DriverRegister(DRIVER_FILL_FRAME, (void *)vUGUI_FillFrame);
/* 使能驱动 */
UG_DriverEnable(DRIVER_DRAW_LINE);
UG_DriverEnable(DRIVER_FILL_FRAME);
/* 清屏 */
UG_FillScreen(WHITE);
}
十八、uGUI定时更新
void TIM5_IRQHandler(void)//1ms interrupt
{
static u8 timerTicks = 0;
static u8 keyTicks = 0;
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//TIM5 updata interrupt occurred or not
{
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);//Clear TIM5 updata interrupt flag
ulSysTick++;
if(timerTicks > 100)
{
timerTicks = 0;
UG_Update();
}
keyTicks++;
timerTicks++;
}
}
十九、测试例程
int main(void)
{
static u32 oldTick = 0;
static u16 count = 0;
static u16 countPage = 0;
u32 curTick = 0;
vSystem_Init();
vUGUI_Init();
vInit_Page_Register();
dprintf("Sysem Start Running......\r\n");
while(1)
{
//timer_loop();
curTick = ulSysTick;
if(((u32)(curTick - oldTick)) > 200)
{
xSuperPageManager.PageManagerRunning(&xSuperPageManager);
oldTick = curTick;
if((++count) >= 5)
{
countPage++;
count = 0;
LED5_CPL();
}
if (countPage <= 5)
{
xSuperPageManager.PageJump(&xSuperPageManager, Page_HomeMenu);
}
else if (countPage <= 10)
{
xSuperPageManager.PageJump(&xSuperPageManager, Page_SetMenu);
}
else if (countPage <= 15)
{
xSuperPageManager.PageJump(&xSuperPageManager, Page_AboutMenu);
}
else
{
countPage = 0;
}
}
}
}
二十、运行结果
00> Segger Rtt Init Ok......
00> STM32F103ZET6 Start Running......
00> Compiler Date: May 26 2022 22:17:56
00>
00> vPageRegister_HomeMenu...
00> Sysem Start Running......
00> vHomePage_Creat...
00> vHomePage_Exit...
00> vSetPage_Creat...
00> vSetPage_Exit...
00> vSetPage_Creat...
00> vHomePage_Creat...
00> vHomePage_Exit...
00> vSetPage_Creat...