打印
[STM32F1]

TM32简易多级菜单

[复制链接]
360|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sheflynn|  楼主 | 2024-8-31 12:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1 多级菜单通过数组查表实现

数组查表的方式比较简单,易于理解,本篇就来使用数组查表发在STM32上实现多级菜单的显示。
typedef struct{uchar current;uchar up;//向上翻索引号uchar down;//向下翻索引号uchar enter;//确认索引号void (*current_operation)();} key_table;

    当前页面的索引号
  • 向上翻“按钮后要跳转到的页面索引号
  • 向下翻“按钮后要跳转到的页面索引号
  • 确认“按钮后要跳转到的页面索引号
  • 当前页面的索引号要执行的显示函数,这是一个函数指针

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层其实只是一个欢迎界面)
  • 第二层菜单,就是对第一层菜单中的3个实际的选项进行进一步的介绍,每种介绍又有4个子项(注意最后一个选项也是用作返回上一级,无实际内容含义),因此,这里的第二层菜单列了3x4=12行
  • 注意数组中每一行的第1个数组,是索引号,先列举一个实际的例子进行分析:

比如数组关于第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,显示欢迎界面;再后面的1表示按下“确认”按钮后,跳转到索引1处(即显示第1级目录,且指向第1级的第1个子项);后面的4表示此时按“上翻”跳转到索引4,即显示第1级目录,且指向第1级的第4个子项(Return);再后面的5表示按下“确认”按钮后,跳转到索引5处(即显示第2级目录,且指向第2级的第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(; //...()if(KEY10||==)(KEY30)   delay_ms10;if==)       = table;    while!KEY1;}       (KEY20{           func_index [func_index.down//向下翻           ()}       (KEY30{           func_index [func_index.enter//确认           ()}   if != last_index{       current_operation_index [func_index.current_operationu8g2_ClearBuffer&u8g2;       *current_operation_index(;u8g2_SendBuffer&u8g2;       last_index ;   }

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

1247

帖子

2

粉丝