您当前的位置:首页 > 电子 > 光电显示与成像

STM32+OLED屏多级菜单显示(三)

时间:08-16来源:作者:点击数:
城东书院 www.cdsy.xyz

1.多级菜单

多级菜单是一种用户界面设计,它将信息和选项组织为层次结构,使得用户可以快速找到所需的选项。多级菜单的实现基于两种方案索引法树结构法,索引法阅读性好,扩展性不错,查找性最优,但是比较占用内存,并且一旦选项过多就会造成逻辑混乱

下面展示使用索引法设计的多级目录(黑色的板子是底板,可以理解为面包板),首先是一级目录:

其次,二级目录:

最后,三级目录:

2.typedef用法

在使用多级界面之前,首先要了解一些基础知识。typedef是C/C++中的一个关键字,用来给一个已存在的数据类型(比如int、float、struct等)取一个新的别名(自定义数据类型)。通过typedef声明的别名,可以像原类型一样被使用,但具有更直观、更易读的含义,从而提高代码可读性和可维护性。typedef的使用格式为:

typedef 原类型 新类型
 
举个例子,如:
typedef int MyInt;
MyInt a = 10;//等效int a = 10

再看这个例子,将一个结构体定义为Point类型的别名,使用时就可以使用Point代替这个结构体。这个例子中的第三行代码创建了一个Point类型的结构体变量p,并为其成员变量赋值,除此之外,还有更多的定义方式,如数组、函数指针、enum等

typedef struct {
    int x;
    int y;
} Point;
 
Point p;
p.x = 1;
p.y = 2;

2.函数指针

简单来说,函数指针是指向函数的指针变量,它存储了函数的入口地址,可以用来调用函数。在C语言中,函数指针的定义格式为:返回值类型 (*函数指针名称)(参数列表)。

在下面的例子中,定义了一个函数指针func_ptr,它指向同样返回int类型的函数add。将add函数的地址赋给了函数指针func_ptr后,就可以使用func_ptr来调用add函数,和直接使用add(3,5)是等效的

#include <stdio.h>
 
int add(int a, int b) 
{
    return a + b;
}
 
int main() 
{
    int result;
    int (*func_ptr)(int, int);  // 定义函数指针
 
    func_ptr = add;             // 将函数的地址赋给函数指针
 
    result = func_ptr(3, 5);  // 使用函数指针调用函数
    printf("%d\n", result);        // 输出结果:8
 
    return 0;
}

3.定义多级菜单数据显示类型

前面的基础知识讲完了,现在正式开始使用索引法实现多级菜单的第一步,定义多级菜单的数据类型,通过typedef声明的结构体设计界面菜单功能的数据类型,当前索引序号、三个按键、当前执行的函数指针,索引序号表示界面页码,要进入界面就要输入它的索引序号(就像是在宾馆房间编号,要进入房间就要知道它的房间编号),通过按键赋值索引序号达到跳转的目的(给房间编号的前台服务员),最后是执行的函数指针指向要执行的函数(可以理解为通往房间的路径)

typedef struct
{
	uint8_t CurrentNum;	//当前索引序号:页码
	uint8_t Enter;		//确认键
	uint8_t Next;		//下一个
	uint8_t Return;		//返回键
	void (*Current_Operation)(void);//当前操作(函数指针)
}Menu_table_t;

根据上面自定义的数据类型,定义一个一维数组taskTable[ ],一维数组中的元素的数据类型就是Menu_table_t(就像我定义一个int array[] = { 0 ,},0的数据类型就是int),taskTable的元素中的元素与自定义数据类型里的数据类型统一对应,就像最后一个函数指针元素指向菜单界面函数,简单说明一下,taskTable[0] = {0, 1, 0, 0, Menu_Innterface},

//界面调度表 //假定 int array[] = { 0, };
Menu_table_t taskTable[] =
{
    //菜单界面函数 -- 一级界面
    {0, 1, 2, 3, Menu_Interface}, 
};
 
/**
  * @brief  菜单界面函数
  * @param  无
  * @retval 无
  */
void Menu_Interface(void)
{
	char buff[50];
	
	RTC_Get_StdTime(RTC_GetCounter());
	
	sprintf(buff,"%0.2d:%0.2d:%0.2d",RTC_CLOCK.hour, RTC_CLOCK.min, RTC_CLOCK.sec);
	OLED_ShowString(4, 10,  24, buff);
	
	sprintf(buff,"Date:%0.4d-%0.2d-%0.2d",RTC_CLOCK.year,RTC_CLOCK.mon,RTC_CLOCK.day);
	OLED_ShowString(1, 6,  16, buff);
}

所以,数据类型就是这样对应的,第一个为索引序号,中间三个为按键,最后一个执行函数,将它的首地址赋值给指针函数

4.菜单逻辑顺序表

通过上述的对应关系,可以制定一张菜单逻辑顺序,通过中间的三个按键将索引序号赋值给任务调度序号,当在一级界面时,按下确认键就通过索引序号把务调度序号切换为1,进入到二级界面的第一个元素了,按下下一位键和返回键

uint8_t taskIndex = 0;	//任务调度序号
//任务调度表
Menu_table_t taskTable[] =
{
    //菜单界面函数 -- 一级界面
    {0, 1, 0, 0, Menu_Interface}, 
    //功能界面函数 -- 二级界面
    {1, 4, 2, 0, Function_Interface1},
    {2, 5, 3, 0, Function_Interface2},
    {3, 6, 1, 0, Function_Interface3},
	//功能设置界面函数 -- 三级界面
	{4, 4, 4, 1, Function_Interface4},
	{5, 5, 5, 2, Function_Interface5},
	{6, 6, 6, 3, Function_Interface6},
};
城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐