打印
[应用相关]

(转)为OLED屏增加GUI支持7:综合实例

[复制链接]
628|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
木木guainv|  楼主 | 2018-8-15 13:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文博客链接:http://blog.csdn.net/jdh99


环境:

主机:WIN10

开发环境:MDK5.13

MCU:STM32F103


说明:
前面的**已经介绍了本GUI的基本功能,目前有的控件有文本控件,图片控件,以及进度条控件,这是我项目中所需要的,读者可以参考这些代码增加自己所需的控件。本文展示一个综合实例,显示一个完整的界面。文中用到调度框架pt-thread。

实现效果:



源代码:

gui.h:gui头文件


/**
* Copyright (c), 2015-2025
* @file gui.h
* @brief gui头文件
* @author jdh
* @version 1.0
* @date 2015/9/6
*/

#ifndef _GUI_H_
#define _GUI_H_

/*********************************************************************
*                                                        头文件
**********************************************************************/

#include "gui_interface.h"
#include "gui_text_lib.h"
#include "gui_2d_lib.h"
#include "gui_widget_text.h"
#include "gui_widget_image.h"
#include "gui_widget_progbar.h"

/*********************************************************************
*                                                        函数
**********************************************************************/

/**
* @brief 初始化gui
*/

void gui_init(void);

/**
* @brief 销毁控件
* @param handle:控件句柄
*/

void gui_widget_delete(void *handle);

#endif



gui.c:gui主文件


/**
* Copyright (c), 2015-2025
* @file gui.c
* @brief gui主文件
* @author jdh
* @date 2015/9/6
*/

/*********************************************************************
*                                                        头文件
**********************************************************************/

#include "gui.h"
#include "stdlib.h"

/*********************************************************************
*                                                        函数
**********************************************************************/

/**
* @brief 初始化gui
*/

void gui_init(void)
{
//        //初始化字库
//        font_init();
}

/**
* @brief 销毁控件
* @param handle:控件句柄
*/

void gui_widget_delete(void *handle)
{
        free(handle);
        handle = (void *)0;
}


实例:

gui_mode_fence.h


/**
* Copyright (c), 2015-2025
* @file gui_mode_fence.h
* @brief 围栏界面模块头文件
* @author jdh
* @date 2015/11/22
*/

#ifndef _GUI_MODE_FENCE_H_
#define _GUI_MODE_FENCE_H_

/*********************************************************************
*                                                        头文件
**********************************************************************/

#include "world.h"

/*********************************************************************
*                                                        宏定义
**********************************************************************/

/**
* @brief 工作间隔,单位:ms
*/

#define INTERVAL_GUI_MODE_FENCE                        100  

/*********************************************************************
*                                                        函数
**********************************************************************/

/**
* @brief 模块载入
*/

void gui_mode_fence_load(void);

/**
* @brief 模块运行
*/

void gui_mode_fence_run(void);

/**
* @brief 设置显示状态
* @param enable:0:关闭显示,1:打开显示
*/

void gui_mode_fence_show(uint8_t enable);

/**
* @brief 得到当前的显示状态
* @retval 0:关闭显示,1:打开显示
*/

uint8_t gui_mode_fence_get_show(void);

#endif



gui_mode_fence.c


/**
* Copyright (c), 2015-2025
* @file gui_mode_fence.c
* @brief 围栏模式界面模块主文件
* @author jdh
* @date 2015/11/22
* @update 2015/12/11
*/

/*********************************************************************
*                                                        头文件
**********************************************************************/

#include "gui_mode_fence.h"
#include "status_bar.h"
#include "gui_schedule.h"
#include "para_manage.h"
#include "slave_manage.h"

/*********************************************************************
*                                                        数据结构
**********************************************************************/

/**
* @brief 按键状态
*/

struct _Key_State
{
        uint8_t ok;
        uint8_t cancel;
        uint8_t left;
        uint8_t right;
};

/*********************************************************************
*                                                        静态变量
**********************************************************************/

/**
* @brief pt任务变量
*/

static struct pt pt_task;

/**
* @brief 当前显示状态.0:未显示,1显示
*/

static uint8_t State_Show = 0;

/**
* @brief 控件
*/

//警报距离
static Widget_Text_Handle Widget_Text_Alarm_Distance;
//状态
static Widget_Text_Handle Widget_Text_State;
//距离
static Widget_Text_Handle Widget_Text_Distance;

/**
* @brief 按键状态
*/

static struct _Key_State Key_State =
{
        .ok = 0,
        .cancel = 0,
        .left = 0,
        .right = 0
};

/**
* @brief 从机信息
*/

static struct _Slave_Info Slave_Info_Show;

/*********************************************************************
*                                                        静态函数
**********************************************************************/

/**
* @brief 任务运行
* @retval 任务状态
*/

static int pt_run(struct pt *pt);

/**
* @brief 按键处理
*/

static void deal_key(void);

/**
* @brief 更新界面
*/

static void refresh_ui(void);

/*********************************************************************
*                                                        函数
**********************************************************************/

/**
* @brief 模块载入
*/

void gui_mode_fence_load(void)
{
        //载入任务
        PT_INIT(&pt_task);
}

/**
* @brief 模块运行
*/

void gui_mode_fence_run(void)
{
        //启动任务
        pt_run(&pt_task);
}

/**
* @brief 设置显示状态
* @param enable:0:关闭显示,1:打开显示
*/

void gui_mode_fence_show(uint8_t enable)
{
        uint8_t distance_alarm = 0;
        char str[32] = {0};
       
        //判断当前状态
        if (State_Show == enable)
        {
                return;
        }
       
        State_Show = enable;
        if (State_Show)
        {
                //清屏
                gui_fill_rect(0,0,LCD_WIDTH - 1,LCD_HEIGHT - 1,0);
               
                //显示状态栏
                status_bar_show(ON);
                //显示其他控件
                //读取报警距离
                distance_alarm = para_manage_read_distance_alarm();
                sprintf(str,"%dm",distance_alarm);
                Widget_Text_Alarm_Distance = gui_widget_text_create(93,20,30,20,GB18030_20X20,str);
                Widget_Text_State = gui_widget_text_create(93,40,30,20,GB18030_20X20,"正常");
                Widget_Text_Distance = gui_widget_text_create(0,27,87,30,GB18030_37X37B,"0.0m");
                refresh_ui();
        }
        else
        {
                status_bar_show(OFF);
                gui_widget_delete(Widget_Text_Alarm_Distance);
                gui_widget_delete(Widget_Text_State);
                gui_widget_delete(Widget_Text_Distance);
        }
}

/**
* @brief 得到当前的显示状态
* @retval 0:关闭显示,1:打开显示
*/

uint8_t gui_mode_fence_get_show(void)
{
        return State_Show;
}

/**
* @brief 任务运行
* @retval 任务状态
*/

static int pt_run(struct pt *pt)
{
        static T_Time time_delay;
       
        PT_BEGIN(pt);
       
        //等待显示
        PT_WAIT_UNTIL(pt,State_Show);
       
        //等待
        time_delay = get_time();
        PT_WAIT_UNTIL(pt,sub_time_safe(get_time(),&time_delay) > INTERVAL_GUI_MODE_FENCE * 1000 || State_Show == OFF);
       
        if (State_Show)
        {
                //更新状态栏
                status_bar_refresh();
                //更新界面
                refresh_ui();
                //处理按键
                deal_key();
        }
       
        PT_END(pt);
}

/**
* @brief 按键处理
*/

static void deal_key(void)
{       
        uint8_t distance_alarm = 0;
        char str[32] = {0};
       
        if (inf_key_detect_hold(KEY_CANCEL))
        {
                if (Key_State.cancel == 0)
                {
                        Key_State.cancel = 1;
                        return;
                }
        }
        else
        {
                if (Key_State.cancel == 1)
                {
                        Key_State.cancel = 0;
                        return;
                }
        }
       
        if (inf_key_detect_hold(KEY_OK))
        {
                if (Key_State.ok == 0)
                {
                        Key_State.ok = 1;
                       
                        distance_alarm = para_manage_read_distance_alarm();
                        switch (distance_alarm)
                        {
                                case 5:
                                {
                                        distance_alarm = 10;
                                        break;
                                }
                                case 10:
                                {
                                        distance_alarm = 20;
                                        break;
                                }
                                case 20:
                                {
                                        distance_alarm = 30;
                                        break;
                                }
                                case 30:
                                {
                                        distance_alarm = 5;
                                        break;
                                }
                                default:
                                {
                                        distance_alarm = 10;
                                        break;
                                }
                        }
                        para_manage_earase_para(2);
                        para_manage_save_valid(2);
                        para_manage_save_distance_alarm(distance_alarm);
                        sprintf(str,"%dm",distance_alarm);
                        gui_widget_text_set_text(Widget_Text_Alarm_Distance,GB18030_20X20,str);
                        return;
                }
        }
        else
        {
                if (Key_State.ok == 1)
                {
                        Key_State.ok = 0;
                        return;
                }
        }
       
        if (inf_key_detect_hold(KEY_LEFT))
        {
                if (Key_State.left == 0)
                {
                        Key_State.left = 1;
                       
                        //设置为停止中模式
                        para_manage_save_work_mode(MODE_STOPING);
                        //切换到停止进度界面
                        gui_schedule_switch(GUI_STOP_PROGRESS);
                       
                        return;
                }
        }
        else
        {
                if (Key_State.left == 1)
                {
                        Key_State.left = 0;
                        return;
                }
        }
       
        if (inf_key_detect_hold(KEY_RIGHT))
        {
                if (Key_State.right == 0)
                {
                        Key_State.right = 1;
                       
                        //设置为搜索模式
                        para_manage_save_work_mode(MODE_SEARCH);
                        //切换到搜索模式界面
                        gui_schedule_switch(GUI_MODE_SEARCH);
                        return;
                }
        }
        else
        {
                if (Key_State.right == 1)
                {
                        Key_State.right = 0;
                        return;
                }
        }
}

/**
* @brief 更新界面
*/

static void refresh_ui(void)
{       
        char str[32] = {0};
        uint16_t slave_id = 0;
        struct _Slave_Info slave_info;
       
        //从机数量
        if (para_manage_read_slave_num() == 0)
        {
                return;
        }
        //读取从机id
        slave_id = para_manage_read_slave_id(1);
        //读取从机信息
        slave_info = slave_manage_read_slave(slave_id);
       
        //状态
        if (Slave_Info_Show.state != slave_info.state)
        {
                Slave_Info_Show.state = slave_info.state;
                switch (Slave_Info_Show.state)
                {
                        case 0:
                        {
                                gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"正常");
                                break;
                        }
                        case 1:
                        {
                                gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"低电");
                                break;
                        }
                        case 2:
                        {
                                gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"超距");
                                break;
                        }
                        case 3:
                        {
                                gui_widget_text_set_text(Widget_Text_State,GB18030_20X20,"失踪");
                                break;
                        }
                }
        }
       
        //距离
        if (Slave_Info_Show.distance != slave_info.distance)
        {
                Slave_Info_Show.distance = slave_info.distance;
                sprintf(str,"%.1fm",Slave_Info_Show.distance);
                gui_widget_text_set_text(Widget_Text_Distance,GB18030_37X37B,str);
        }
}
沙发
观海| | 2018-8-16 08:27 | 只看该作者
喜欢这种综合的例子 感谢楼主

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

146

主题

4098

帖子

5

粉丝