历史上的今天
今天是:2024年10月14日(星期一)
2020年10月14日 | 为OLED屏增加GUI支持7:综合实例
2020-10-14 来源:eefocus
环境:
主机: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);
}
}
上一篇:设计单片机日志系统
史海拾趣
|
差分线对的工作原理是使接收到的信号等于两个互补并且彼此互为参考的信号之间的差值,因此可以极大地降低信号的电气噪声效应。而单端信号的工作原理是接收信号等于信号与电源或地之间的差值 ,因此信号或电源系统上的噪声不能被有效抵消。这就 ...… 查看全部问答> |
|
哪位用过ZLG7290这款芯片,我现在也在使用。 我想请教大家个问题:如何写驱动实现控制wince的系统菜单的?比如打开左下角的菜单,上下移动菜单,或者关闭任意程序等。谢谢… 查看全部问答> |
|
wince5.0 window media player 6.4 支持标准RTSP 要让wince5.0 window media player 6.4 支持标准RTSP,所以要写一个RTSP 的filter, 我的问题是,只要注册了这个rtsp的filter ,用media player6.4接收rtsp的流就会直接调用我这个RTSP 的filter? 还是还要修改注册表其他地方??… 查看全部问答> |
|
USB接口(Universal Serial Bus)是一种通用的高速串行接口。它最主要的特点是它的高速传输特性。USB1.1理论速度极限可以达到12Mb/s,USB2.0可达到480Mb/s。这样,它可以很好解决大数据量的数据在嵌入式系统与PC机之间的互传问题;同时,它支持热 ...… 查看全部问答> |
|
IEEE JSSC的论文从60年代到2005年全集15G电骡地址 由于原文档太大,采用点对点的方法很占带宽,现在改用电螺分享,速度会很快,为了方便下载,重新打包成700M的大小,共18个文档,地址文件详见附件。 晚上10:00以后速度会很快,不过总共有12G的内容,一个新的文档要下完还是需要一定时间的。 最后 ...… 查看全部问答> |
|
#include static unsigned int results; void main(void) { volatile unsigned int i;//unsigned long int j; WDTCTL = WDTPW+WDTHOLD;   ...… 查看全部问答> |




