当前位置:网站首页>STM32简易多级菜单(数组查表法)
STM32简易多级菜单(数组查表法)
2022-07-05 09:11:00 【华为云】
1 多级菜单
通过双向链表实现
通过数组查表实现
总体思路都是把菜单的各个界面联系起来,可以从上级菜单跳到下级菜单,也可从下级菜单返回上级菜单。
数组查表的方式比较简单,易于理解,本篇就来使用数组查表发在STM32上实现多级菜单的显示。
2 代码实现
2.1 数组查表
首先需要定义一个结构体:
typedef struct{ uchar current; uchar up;//向上翻索引号 uchar down;//向下翻索引号 uchar enter;//确认索引号 void (*current_operation)();} key_table;
current:当前页面的索引号
up:按下“向上翻“按钮后要跳转到的页面索引号
down:按下“向下翻“按钮后要跳转到的页面索引号
enter:按下“确认“按钮后要跳转到的页面索引号
current_operation:当前页面的索引号要执行的显示函数,这是一个函数指针
注意:对于菜单显示的操作,用到了3个按键,分别是向下、向下和确认,如果单片机上的IO资源较为紧张,还可以把“向上翻”按钮省去,只通过“向下翻”按钮来实现循环访问,对应的结构体也可以去掉该成员。
然后定义一个表,用来定义各个页面间如何跳转
key_table table[30]={ //第0层 {0,0,0,1,(*fun_0)}, //第1层 {1,4,2, 5,(*fun_a1)}, {2,1,3, 9,(*fun_b1)}, {3,2,4,13,(*fun_c1)}, {4,3,1, 0,(*fun_d1)}, //第2层 {5,8,6,17,(*fun_a21)}, {6,5,7,18,(*fun_a22)}, {7,6,8,19,(*fun_a23)}, {8,7,5, 1,(*fun_a24)}, { 9,12,10,20,(*fun_b21)}, {10, 9,11,21,(*fun_b22)}, {11,10,12,22,(*fun_b23)}, {12,11, 9, 2,(*fun_b24)}, {13,16,14,23,(*fun_c21)}, {14,13,15,24,(*fun_c22)}, {15,14,16,25,(*fun_c23)}, {16,15,13, 3,(*fun_c24)}, //第3层 {17,17,17,5,(*fun_a31)}, {18,18,18,6,(*fun_a32)}, {19,19,19,7,(*fun_a33)}, {20,20,20, 9,(*fun_b31)}, {21,21,21,10,(*fun_b32)}, {22,22,22,11,(*fun_b33)}, {23,23,23,13,(*fun_c31)}, {24,24,24,14,(*fun_c32)}, {25,25,25,15,(*fun_c33)}, };
这里解释一下该表是如何工作的:
此表,表示了4级菜单的显示关系(注意第0层其实只是一个欢迎界面)
第一层菜单,只有4个选项,因此这里只列了4行(注意最后一个选项用作返回上一级,无实际内容含义)
第二层菜单,就是对第一层菜单中的3个实际的选项进行进一步的介绍,每种介绍又有4个子项(注意最后一个选项也是用作返回上一级,无实际内容含义),因此,这里的第二层菜单列了3x4=12行
第三层菜单,又是对第二层菜单中的子项进行进一步的介绍(3个分类,每类有3个子项),所以第三层菜单列了9行
注意数组中每一行的第1个数组,是索引号,先列举一个实际的例子进行分析:
上图就是一个实际的4级菜单要显示的内容,每个条目前,标记了索引号(0~25),即对应数组在定义的索引号。
比如数组关于第0层和第1层的定义:
//第0层{0,0,0,1,(*fun_0)},//第1层{1,4,2, 5,(*fun_a1)},{2,1,3, 9,(*fun_b1)},{3,2,4,13,(*fun_c1)}, {4,3,1, 0,(*fun_d1)},
先看第一行:索引是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个数字都是当前的索引号:
//第3层{17,17,17,5,(*fun_a31)}, {18,18,18,6,(*fun_a32)}, {19,19,19,7,(*fun_a33)},{20,20,20, 9,(*fun_b31)}, {21,21,21,10,(*fun_b32)}, {22,22,22,11,(*fun_b33)},{23,23,23,13,(*fun_c31)}, {24,24,24,14,(*fun_c32)}, {25,25,25,15,(*fun_c33)},
2.2 具体的显示函数
对于函数要显示的具体内容,根据自己的实现需要显示即可。
这里我使用的是OLED屏幕,借助U8g2图形库进行内容显示,以下是部分显示示例:
/*********第1层***********/void fun_a1() { u8g2_DrawStr(&u8g2,0,16,">"); u8g2_DrawStr(&u8g2,16,16,"[1]Weather"); u8g2_DrawStr(&u8g2,16,32,"[2]Music"); u8g2_DrawStr(&u8g2,16,48,"[3]Device Info"); u8g2_DrawStr(&u8g2,16,64,"<--"); }void fun_b1() { u8g2_DrawStr(&u8g2,0,32,">"); u8g2_DrawStr(&u8g2,16,16,"[1]Weather"); u8g2_DrawStr(&u8g2,16,32,"[2]Music"); u8g2_DrawStr(&u8g2,16,48,"[3]Device Info"); u8g2_DrawStr(&u8g2,16,64,"<--"); }void fun_c1() { u8g2_DrawStr(&u8g2,0,48,">"); u8g2_DrawStr(&u8g2,16,16,"[1]Weather"); u8g2_DrawStr(&u8g2,16,32,"[2]Music"); u8g2_DrawStr(&u8g2,16,48,"[3]Device Info"); u8g2_DrawStr(&u8g2,16,64,"<--"); }void fun_d1() { u8g2_DrawStr(&u8g2,0,64,">"); u8g2_DrawStr(&u8g2,16,16,"[1]Weather"); u8g2_DrawStr(&u8g2,16,32,"[2]Music"); u8g2_DrawStr(&u8g2,16,48,"[3]Device Info"); u8g2_DrawStr(&u8g2,16,64,"<--"); }/*********第2层***********/void fun_a21() { u8g2_DrawStr(&u8g2,0,16,">"); u8g2_DrawStr(&u8g2,16,16,"* HangZhou"); u8g2_DrawStr(&u8g2,16,32,"* BeiJing"); u8g2_DrawStr(&u8g2,16,48,"* ShangHai"); u8g2_DrawStr(&u8g2,16,64,"<--"); }//省略...
2.3 按键切换页面
页面的切换,这里里简单的按钮轮询为例,比如初始显示欢迎界面的状态下,按下不同按键后,通过数组查表,确定要跳转到的索引号,然后根据索引号,通过函数指针执行索引号对应的显示函数,即实现了一次页面切换。
然后,就是在新的页面状态,收到下一个按钮指令,再切换到下一个显示状态。
void (*current_operation_index)(); //定义一个函数指针//...while(1){ if((KEY1==0)||(KEY2==0)||(KEY3==0)) { delay_ms(10);//消抖 if(KEY1==0) { func_index = table[func_index].up; //向上翻 while(!KEY1);//松手检测 } if(KEY2==0) { func_index = table[func_index].down; //向下翻 while(!KEY2); } if(KEY3==0) { func_index = table[func_index].enter; //确认 while(!KEY3); } } if (func_index != last_index) { current_operation_index = table[func_index].current_operation; u8g2_ClearBuffer(&u8g2); (*current_operation_index)();//执行当前操作函数 u8g2_SendBuffer(&u8g2); last_index = func_index; }}
3 演示
测试效果如下:
https://www.bilibili.com/video/BV1r5411R7eA
4 总结
本篇介绍了一种简易的多级菜单的显示方法,本质是通过数组查表,实现各级菜单的各个页面(状态)的切换(跳转),并在STM32上编程实现,通过OLED屏幕,以及借助U8g2图形库,测试了多级菜单的显示功能。
边栏推荐
- OpenFeign
- nodejs_ fs. writeFile
- Introduction Guide to stereo vision (7): stereo matching
- Multiple solutions to one problem, asp Net core application startup initialization n schemes [Part 1]
- Huber Loss
- Newton iterative method (solving nonlinear equations)
- Solutions of ordinary differential equations (2) examples
- 3D reconstruction open source code summary [keep updated]
- The location search property gets the login user name
- Introduction Guide to stereo vision (3): Zhang calibration method of camera calibration [ultra detailed and worthy of collection]
猜你喜欢
nodejs_ fs. writeFile
Wechat H5 official account to get openid climbing account
嗨 FUN 一夏,与 StarRocks 一起玩转 SQL Planner!
[code practice] [stereo matching series] Classic ad census: (5) scan line optimization
[beauty of algebra] singular value decomposition (SVD) and its application to linear least squares solution ax=b
Node collaboration and publishing
Hi Fun Summer, play SQL planner with starrocks!
Priority queue (heap)
Composition of applet code
Ros- learn basic knowledge of 0 ROS - nodes, running ROS nodes, topics, services, etc
随机推荐
利用请求头开发多端应用
Driver's license physical examination hospital (114-2 hang up the corresponding hospital driver physical examination)
MPSoC QSPI Flash 升级办法
太不好用了,长文章加图文,今后只写小短文
Multiple solutions to one problem, asp Net core application startup initialization n schemes [Part 1]
Attention is all you need
Ecmascript6 introduction and environment construction
asp. Net (c)
Use and programming method of ros-8 parameters
[code practice] [stereo matching series] Classic ad census: (4) cross domain cost aggregation
The combination of deep learning model and wet experiment is expected to be used for metabolic flux analysis
Solution to the problem of the 10th Programming Competition (synchronized competition) of Harbin University of technology "Colin Minglun Cup"
AUTOSAR from getting started to mastering 100 lectures (103) -dbc file format and creation details
Introduction Guide to stereo vision (1): coordinate system and camera parameters
Beautiful soup parsing and extracting data
容易混淆的基本概念 成员变量 局部变量 全局变量
[technical school] spatial accuracy of binocular stereo vision system: accurate quantitative analysis
3D reconstruction open source code summary [keep updated]
Hi Fun Summer, play SQL planner with starrocks!
ROS learning 4 custom message