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

发布者:qq8174350最新更新时间:2020-10-14 来源: eefocus关键字:OLED屏  GUI支持  STM32F103 手机看文章 扫描二维码
随时随地手机看文章

环境:

主机: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);

}

}


关键字:OLED屏  GUI支持  STM32F103 引用地址:为OLED屏增加GUI支持7:综合实例

上一篇:设计单片机日志系统
下一篇:为OLED屏增加GUI支持6:进度条控件

推荐阅读最新更新时间:2024-11-18 19:39

STM32f103按键检测程序实现长按短按
背景 只要使用单片机,按键检测基本上是一定要实现的功能。按键检测要好用,最重要的是实时和去抖。初学者往往会在主循环调用按键检测程序(实时)并利用延时去抖(准确)。这种在主循环内延时的做法对整个程序非常不友好,也非常不高效。因此,本篇就我自己实现的一个检测按键并可判断按键是否长短按的程序做个介绍和记录。 正文 在硬件连接上,按键一端连接在普通IO口上,另一端接地,IO配置为内部弱上拉。 在软件上,先配置一个5ms定时器并打开中断,每进入该定时中断则置位一次标志位“key_handle”。接着在主循环调用一个“scan_key()”函数,判断“key_handle”标志位是否在定时器内被置位,若被置位则将该位复位并读取连接按键的IO口
[单片机]
Proteus仿真stm32f103实现SPI
单片机源程序如下: #include stm32f10x.h #include spi.h #include Module.h #include stdio.h void Delay_Ms(u16 time); void RCC_Configuration(void); //void GPIO_Configuration(void); u32 retry=0; int i=0; /* Private functions ---------------------------------------------------------*/ /*******************************
[单片机]
华为P30 Pro用的哪家
华为正式发布了年度旗舰华为P30与华为P30 Pro,前者搭载了一块6.2英寸OLED屏幕,分辨率为2340x1080,后者搭载了一块6.47英寸曲面OLED屏,分辨率为2340x1080。   至于屏幕来源华为并未透露,不过从OLED屏幕的表述来看,应该并不是三星屏幕(三星OLED均称为AMOLED)。   不过供应商还是透露出一些蛛丝马迹,京东方(BOE)副总裁,微博认证为BOE超话主持人的@原烽_BOE 在微博上对华为P30发布会十分感兴趣,感慨道:“多好的曲面屏呀。” 有微博网友评论道:“我们支持BOE,就想知道(P30系列)是否是BOE的屏。”    对此原烽非常暧昧的回复了一句:“刚性屏不是。”
[手机便携]
华为P30 Pro用的哪家<font color='red'>屏</font>?
stm32f103串口实用DMA实现收发
目标环境: MCU:stm32f103C8T6 stm32 library:standard library V3.5.0 RTOS:FreeRTOS 实现功能: a. 接收DMA和串口IDLE中断配合接收不定长数据 b. 使用DMA发送数据 一. 初始化 #include stm32f10x.h #include stm32f10x_rcc.h #include stm32f10x_usart.h #include stm32f10x_gpio.h #include stm32f10x_dma.h #include freertos.h #include semph
[单片机]
STM32F103C8T6引脚功能分布
引脚分布: 数据手册中的:
[单片机]
STM32F103C8T6引脚功能分布
STM32F103 实验 PWM输出
正文 实验目的 使用TIM3的通道2,把通道2重映射到PB5,产生PWM来控制DS0的亮度 实验内容 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用 微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽 度的控制。 STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定 时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4 路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出! 要使 STM32 的通用定时器
[单片机]
<font color='red'>STM32F103</font> 实验 PWM输出
stm32f103基本定时器,定时器中断服务程序里面输出脉冲波形
main.c /**定时器中断TIM3方式,(当基本定时器不用PWM输出) 设计两路输出两路脉冲波: 周期:100us,占空比80% 周期:100us,占空比20%**/ int main(void) { LED_Init();//pc14引脚初始化 BEEP_Init();/pc13引脚初始化 TIME_Init();//定时器初始化 while(1); } time.c #include stm32f10x.h #include time.h #include delay.h #include beep.h #include stdio.h void TIME_Init(void) {
[单片机]
<font color='red'>stm32f103</font>基本定时器,定时器中断服务程序里面输出脉冲波形
Q3 OLED手机全球规模达到47亿美元 2020年比例将上升至53%
有机构预测OLED显示屏市场将会迎来高速增长,受苹果和三星电子OLED显示屏的大量使用。预计到2018年会有更多的厂商加入到这个行列来。2020年,这一比例将有望上升至53%。 据报道,市场调研公司IHS Markit周四发布报告称,今年第三季度全球智能手机用OLED显示屏的市场规模达到47亿美元,较去年同期的36亿美元激增了30%。 作为一种新型的屏幕类型,OLED有着无需背光源,可以自发光,可视角度更大、色彩更丰富、节能显著、可柔性弯曲等优点。随着苹果跟随部分中国厂商、三星电子,开始在旗舰智能手机iPhone X开始采用OLED显示屏,预计到2018年将会有更多的手机厂商和型号采用OLED显示屏。IHS Market此
[电源管理]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved