STM32简易多级菜单(数组查表法)
单片机开发中,有时会用到屏幕来显示内容,当需要逐级显示内容时,就需要使用多级菜单的形式了。
1 多级菜单
多级菜单的实现,大体分为两种设计思路:
- 通过双向链表实现
- 通过数组查表实现
总体思路都是把菜单的各个界面联系起来,可以从上级菜单跳到下级菜单,也可从下级菜单返回上级菜单。
数组查表的方式比较简单,易于理解,本篇就来使用数组查表发在STM32上实现多级菜单的显示。
2 代码实现
2.1 数组查表
首先需要定义一个结构体:
1 | typedef struct |
- current:当前页面的索引号
- up:按下“向上翻“按钮后要跳转到的页面索引号
- down:按下“向下翻“按钮后要跳转到的页面索引号
- enter:按下“确认“按钮后要跳转到的页面索引号
- current_operation:当前页面的索引号要执行的显示函数,这是一个函数指针
注意:对于菜单显示的操作,用到了3个按键,分别是向下、向下和确认,如果单片机上的IO资源较为紧张,还可以把“向上翻”按钮省去,只通过“向下翻”按钮来实现循环访问,对应的结构体也可以去掉该成员。
然后定义一个表,用来定义各个页面间如何跳转
1 | key_table table[30]= |
这里解释一下该表是如何工作的:
- 此表,表示了4级菜单的显示关系(注意第0层其实只是一个欢迎界面)
- 第一层菜单,只有4个选项,因此这里只列了4行(注意最后一个选项用作返回上一级,无实际内容含义)
- 第二层菜单,就是对第一层菜单中的3个实际的选项进行进一步的介绍,每种介绍又有4个子项(注意最后一个选项也是用作返回上一级,无实际内容含义),因此,这里的第二层菜单列了3x4=12行
- 第三层菜单,又是对第二层菜单中的子项进行进一步的介绍(3个分类,每类有3个子项),所以第三层菜单列了9行
- 注意数组中每一行的第1个数组,是索引号,先列举一个实际的例子进行分析:
上图就是一个实际的4级菜单要显示的内容,每个条目前,标记了索引号(0~25),即对应数组在定义的索引号。
比如数组关于第0层和第1层的定义:
1 | //第0层 |
- 先看第一行:索引是0,显示欢迎界面;后面的两个0表示此时按“上翻”和“下翻”无效,继续显示欢迎界面;再后面的1表示按下“确认”按钮后,跳转到索引1处(即显示第1级目录,且指向第1级的第1个子项);最后是此索引要显示的具体内容,fun_0就是控制屏幕显示欢迎界面
- 再看第二行:索引是1,显示第1级目录,且指向第1级的第1个子项(天气);后面的4表示此时按“上翻”跳转到索引4,即显示第1级目录,且指向第1级的第4个子项(Return);再后面的2表示此时按“下翻”跳转到索引2,即显示第1级目录,且指向第1级的第2个子项(音乐);再后面的5表示按下“确认”按钮后,跳转到索引5处(即显示第2级目录,且指向第2级的第1个子项-杭州);最后是此索引要显示的具体内容,fun_a1就是控制屏幕显示第1级目录,且指向第1级的第1个子项(天气)
- 其它行的含义与之类似
通过分析,不难发现,这些数组在空间上的关系:
对于菜单的最底层,因为没有上翻和下翻的功能需求,因此每行的前3个数字都是当前的索引号:
1 | //第3层 |
2.2 具体的显示函数
对于函数要显示的具体内容,根据自己的实现需要显示即可。
这里我使用的是OLED屏幕,借助U8g2图形库进行内容显示,以下是部分显示示例:
1 | /*********第1层***********/ |
2.3 按键切换页面
页面的切换,这里里简单的按钮轮询为例,比如初始显示欢迎界面的状态下,按下不同按键后,通过数组查表,确定要跳转到的索引号,然后根据索引号,通过函数指针执行索引号对应的显示函数,即实现了一次页面切换。
然后,就是在新的页面状态,收到下一个按钮指令,再切换到下一个显示状态。
1 | void (*current_operation_index)(); //定义一个函数指针 |
3 演示
测试效果如下:
https://www.bilibili.com/video/BV1r5411R7eA
4 总结
本篇介绍了一种简易的多级菜单的显示方法,本质是通过数组查表,实现各级菜单的各个页面(状态)的切换(跳转),并在STM32上编程实现,通过OLED屏幕,以及借助U8g2图形库,测试了多级菜单的显示功能。