8、界面的整体框架

界面


其实关于业务逻辑这方面并没有什么好说的,有一个大概的想法去做就行,但这部分也是最费时间的地方,还有有原U主的代码作为参考,这次其实也只是在UP的基础上去修改一点东西,毕竟UI这个东西没个好的审美,做出来也费力不讨好,简称,我杀我自己…

关于界面的实现,我使用PC端先仿真一些纯逻辑和界面的内容,涉及到硬件的先使用其他方法跳过,然后做完一个移植一个,直至全部完成.

页面框架

20210111230643

整个GUI是由8个页面构成的,每个页面都是一个大小等同于屏幕大小的容器,在上电后,各个硬件模块初始化完毕后,就开始了8个容器的初始化.后续的管理由一个页面管理模块管理.该页面管理模块单独占用一个系统线程.

页面管理里面简单的认为所有的页面一共划分为3级,如下.

  1. 表盘页面
  2. 菜单页面
  3. 各个功能页面

界面管理

依旧延续up主思路,每个页面由四个主要函数实现一切逻辑,分别是初始化,循环,触发,退出四个事件.然后将每个页面注册到页面管理器中,通过页面管理器进行统一的页面调度.

界面管理器原代码是C++写的(MIT许可),里面模拟了一些压栈入栈的操作,我根据个人需求该了一下这个文件,删除了一些内容.
现在只有基本的页面切换管理,事件传递调度.
具体代码如下.(临时改的,有需要的可以根据自己的命名规范修改)

/*
 * MIT License
 * Copyright (c) 2018-2020 _VIFEXTech
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the follo18wing conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "PageManager.h"
#include <string.h>
#include "lv_obj_test.h"

#define MALLOC      malloc
#define FREE        free
#define IS_PAGE(page)   ((page)<(page_manager.max_page))
typedef struct
{
    uint8_t new_page;
    uint8_t old_page;
    uint8_t max_page;
    PageList_TypeDef* page_list;
}page_manager_data_t;

static page_manager_data_t page_manager;

static bool push(uint8_t _id);
static bool pop(void);
static void enent_transmit(void* _obj, int _event);
static void run(void);
static void init(uint8_t _max);
static void delte(void);
static bool creat(   uint8_t _id,
                            CallbackFunction_t ,
                            CallbackFunction_t ,
                            CallbackFunction_t ,
                            EventFunction_t );
page_manager_t page =
{
    init,
    delte,
    creat,
    push,
    pop,
    enent_transmit,
    run
};
/**
  * @brief  清除一个页面
  * @param  pageID: 页面编号
  * @retval true:成功 false:失败
  */
static bool PageClear(uint8_t pageID)
{
    if(!IS_PAGE(pageID))
        return false;

    page_manager.page_list[pageID].SetupCallback = NULL;
    page_manager.page_list[pageID].LoopCallback = NULL;
    page_manager.page_list[pageID].ExitCallback = NULL;
    page_manager.page_list[pageID].EventCallback = NULL;

    return true;
}
/**
  * @brief  初始化页面调度器
  * @param  pageMax: 页面最大数量
  * @param  eventMax: 事件最大数量
  * @retval 无
  */
static void init(uint8_t pageMax)
{
    page_manager.max_page = pageMax;
    page_manager.new_page = E_PAGE_MAX;
    page_manager.old_page = E_PAGE_MAX;

    /* 申请内存,清空列表 */
    page_manager.page_list = (PageList_TypeDef*)MALLOC(sizeof(PageList_TypeDef)*page_manager.max_page);
    if(page_manager.page_list != NULL)
    {
        for(uint8_t page = 0; page < page_manager.max_page; page++)
        {
            PageClear(page);
        }
    }
    else FREE(page_manager.page_list);
}

/**
  * @brief  页面调度器析构
  * @param  无
  * @retval 无
  */
static void delte()
{
    FREE(page_manager.page_list);
}



/**
  * @brief  注册一个基本页面,包含一个初始化函数,循环函数,退出函数,事件函数
  * @param  pageID: 页面编号
  * @param  setupCallback: 初始化函数回调
  * @param  loopCallback: 循环函数回调
  * @param  exitCallback: 退出函数回调
  * @param  eventCallback: 事件函数回调
  * @retval true:成功 false:失败
  */
static bool creat(
    uint8_t pageID,
    CallbackFunction_t setupCallback,
    CallbackFunction_t loopCallback,
    CallbackFunction_t exitCallback,
    EventFunction_t eventCallback
)
{
    if(!IS_PAGE(pageID))
        return false;
    page_manager.page_list[pageID].SetupCallback = setupCallback;
    page_manager.page_list[pageID].LoopCallback = loopCallback;
    page_manager.page_list[pageID].ExitCallback = exitCallback;
    page_manager.page_list[pageID].EventCallback = eventCallback;
    return true;
}

/**
  * @brief  页面事件传递
  * @param  obj: 发生事件的对象
  * @param  event: 事件编号
  * @retval 无
  */
static void enent_transmit(void* obj, int event)
{
    /*将事件传递到当前页面*/
    if(page_manager.page_list[page_manager.new_page].EventCallback != NULL)
        page_manager.page_list[page_manager.new_page].EventCallback(obj, event);
}


/**
  * @brief  页面压栈,跳转至该页面
  * @param  pageID: 页面编号
  * @retval true:成功 false:失败
  */
static bool push(uint8_t pageID)
{
    if(!IS_PAGE(pageID))
        return false;
    page_manager.old_page = page_manager.new_page;
    page_manager.new_page = pageID;
    return true;
}

/**
  * @brief  页面弹栈,跳转至上一个页面
  * @param  无
  * @retval true:成功 false:失败
  */
static bool pop()
{
    page_manager.old_page = page_manager.new_page;
    if(page_manager.new_page == PAGE_MainMenu) //在第二级菜单  跳转到第一级菜单
    {
       page_manager.new_page = PAGE_DialPlate;
    }
    else if(page_manager.new_page > PAGE_MainMenu) //在第三级菜单  跳转到第二级菜单
    {
       page_manager.new_page = PAGE_MainMenu;
    }
    else if(page_manager.new_page < PAGE_MainMenu) //在第一级菜单
    {
       page_manager.new_page = PAGE_DialPlate;
    }
    return true;
}
/**
  * @brief  页面调度器状态机
  * @param  无
  * @retval 无
  */
static void run()
{
    /*页面切换事件*/
    if(page_manager.new_page != page_manager.old_page)
    {
        /*触发旧页面退出事件*/
        if(page_manager.page_list[page_manager.old_page].ExitCallback != NULL && IS_PAGE(page_manager.old_page))
            page_manager.page_list[page_manager.old_page].ExitCallback();

        /*触发新页面初始化事件*/
        if(page_manager.page_list[page_manager.new_page].SetupCallback != NULL && IS_PAGE(page_manager.new_page))
            page_manager.page_list[page_manager.new_page].SetupCallback();
        /*标记新页面为当前页面*/
        page_manager.old_page = page_manager.new_page;
    }
    else
    {
        /*页面循环事件*/
        if(page_manager.page_list[page_manager.new_page].LoopCallback != NULL && IS_PAGE(page_manager.new_page))
            page_manager.page_list[page_manager.new_page].LoopCallback();
    }
}

/*
 * MIT License
 * Copyright (c) 2018-2020 _VIFEXTech
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the follo18wing conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __PAGEMANAGER_H
#define __PAGEMANAGER_H

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

typedef void(*CallbackFunction_t)(void);
typedef void(*EventFunction_t)(void*,int);

typedef struct
{
    CallbackFunction_t SetupCallback;
    CallbackFunction_t LoopCallback;
    CallbackFunction_t ExitCallback;
    EventFunction_t EventCallback;
} PageList_TypeDef;

typedef struct
{
    void(*init)(uint8_t);
    void(*delte)(void);
    bool(*creat)(uint8_t,CallbackFunction_t,CallbackFunction_t,CallbackFunction_t,EventFunction_t);
    bool(*push)(uint8_t);
    bool(*pop)(void);
    void(*event_transmit)(void*,int);
    void(*running)(void);
}page_manager_t;

extern page_manager_t page;


#endif

简单的将所有的页面划分为三个阶段的页面,初始页面为一级菜单,主页面为二级菜单,后续的所有功能页面为三级菜单,这样的好处就是逻辑足够简单,坏处就是通用性比较差.看个人取舍吧.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
PLC控制柜的整体框架通常包括以下几个主要组成部分: 1. 电源模块:负责为整个PLC系统提供稳定的电源供应。它通常包括主电源输入、电源滤波器、电源开关和电源指示灯等。 2. CPU模块:是PLC的核心部分,负责处理输入信号、执行程序逻辑、控制输出信号等。它通常包括中央处理器(CPU)、存储器(RAM和ROM)以及各种接口模块。 3. 输入模块:用于接收外部信号输入,如传感器信号、按钮信号等。它通常包括数字输入模块和模拟输入模块,可以将外部信号转换为数字量或模拟量。 4. 输出模块:用于控制外部设备的操作,如电机、阀门、灯光等。它通常包括数字输出模块和模拟输出模块,可以将数字量或模拟量转换为相应的输出信号。 5. 通信模块:用于与其他设备进行数据交换和通信。它可以支持多种通信协议和接口,如以太网、串口、CAN总线等。 6. 编程端口:用于连接编程设备,如编程电缆或编程接口模块。通过编程端口,可以将程序和参数下载到PLC中,实现对PLC的编程和配置。 7. 显示与操作界面:用于显示PLC的运行状态和参数设置,以及进行操作和调试。它通常包括液晶显示屏、按键、指示灯等。 8. 电气保护装置:用于保护PLC系统和外部设备免受电气故障和过载等不良影响。它通常包括熔断器、继电器、过载保护器等。 以上是PLC控制柜的一般框架,不同的应用场景和需求可能会有所差异。具体的PLC控制柜设计和布局还需要根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值