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...

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值