STM32多级界面搭建
在实际的项目之中,需要用单片机在LCD/OLED中搭建一个3级的图形界面。本文的工程文件我将上次传到百度网盘,链接在最后的部分。
一、方案选择
方案一:使用if条件语句写一个界面,但是这种方法在两级界面的时候还可以,在多级界面的时候代码的逻辑上的复杂度会大幅增加,不太使用。
方案二:使用嵌入式图形库lvgl等,但是这个对新手不太友好。
方案三:使用结构体变量存储界面信息,可以是使得多级界面也可以逻辑清晰。
二、实现效果
主界面:
菜单界面:
功能界面:
三、程序设计
3-1宏定义变量设计
·界面标志位:
在头文件中首先需要定义一个结构体来存放界面标志位,包括现在界面的状态,当前运行的任务状态,以及当前任务是否处于运行状态。
·界面变量:
创建三个枚举变量,Main_Interface,Menu_Interface,Task_Interface,来表示目前界面所在的位置,是主界面还是菜单界面还是任务界面。
·任务变量:
创建n个任务,每个任务提供一个代号,方便识别。
#ifndef __GUI_H__
#define __GUI_H__
/*********************************************
* 创建一个结构体
* 存放界面标志位
*********************************************/
typedef struct
{
uint8_t Interface_Mark; //界面状态
uint8_t Task_Mark; //任务状态
uint8_t Run_Task; //开始运行任务
} Mark;
/*********************************************
* 创建一个枚举
* 存放界面变量
*********************************************/
enum
{
Main_Interface, /****主界面*****/
Menu_Interface, /****菜单界面***/
Task_Interface, /****任务界面***/
};
/*********************************************
* 创建一个枚举
* 存放功能变量
*********************************************/
enum
{
F_ONE,
F_TWO,
F_THREE,
F_FOUR,
Stopping, /****任务停止***/
};
extern Mark Mark_Sign;
void Interface_APP(Mark *Mark_Sign);
void Interface(Mark *Mark_Sign,uint8_t keys);
void GUI_init(void);
#endif
3-2控制函数设计
主函数调用:
使用定义的结构体来显示界面,即显示初始界面。
显示界面函数:
主函数调用,根据Mark_Sign->Interface_Mar变量来确实显示当前所在的界面。
功能切换函数:主函数调用,通过扫描按键,当按下对应按键时,执行相应的函数,如确认进入函数,返回退出函数,功能切换函数。
/***************
//初始化,显示主界面
***************/
void GUI_init(void)
{
Interface_APP(&Mark_Sign);
}
/***************
//mian函数中显示,主循环中调用,用于显示界面
***************/
void Interface_APP(Mark *Mark_Sign)
{
switch (Mark_Sign->Interface_Mark)
{
//状态标志位 主界面
case Main_Interface:
Main_Interface_APP();//显示主界面
break;
//状态标志位 菜单界面
case Menu_Interface:
Menu_Interface_APP();//显示菜单界面
break;
//状态标志位 任务界面
case Task_Interface:
Function_Menu_APP(Mark_Sign);//显示功能界面
break;
default:
break;
}
}
/***************
//mian函数中显示,主循环中调用,按键扫描,当按下对应按键时,执行相应的函数
***************/
void Interface(Mark *Mark_Sign,uint8_t keys)
{
/* 1,检测当前按下的按键为确认键
* 2,检测当前的界面
* (1)如果是主界面,则进入菜单界面
* (2)如果是菜单界面,则进入任务界面
* (3)如果是任务界面,则开执行被选中的任务*/
if(keys == KEY1_PRES)
{
key_Inter(Mark_Sign);
}
/*1,检测当前按下的按键为返回键
* 2,检测当前的界面
* (1)如果是任务界面,则停止正在运行的任务,返回到菜单界面
* (2)如果是菜单界面,则返回到主界面*/
if(keys == KEY2_PRES)
{