基于按键驱动的查询式LCD多级菜单框架代码设计

         很多嵌入式MCU项目会用到LCD菜单显示和按键配合来实现人机交互。但由于MCU资源有限,通常选用的LCD都是小屏幕,无法完整显示全部的菜单项,出于用户体验以及菜单的整体美观,菜单经常需要设计成多级形式。因此,设计上菜单一般都是使用上、下、选择、退出四个按键进行控制。本文正是介绍一种通用的MCU多级菜单框架设计,主要采用查询式菜单列表,代码几乎可以完美应用于各种MCU LCD菜单应用场合。

一、菜单结构体设计

typedef enum {
    CONTENT_STR,
    CONTENT_IMG,
    CONTENT_CURSOR,
    CONTENT_NULL,

}content_type_e;


typedef struct {
      void* content;
      content_type_e type;
      uint8_t revert;
      uint16_t x;
      uint16_t y;
      uint16_t max_width;
      uint16_t max_height;
}display_info_t;

typedef enum {
    MENU_NO_ACT,    /*0 */
    MENU_PREVIOUS,
    MENU_EXIT,          
    MENU_ENTER,
    MENU_NEXT,
    MENU_NEXT_ITEM,
    MENU_NEXT_LEVEL,
    MENU_SELE_ITEM,
    MENU_SELE_LEVEL,
    MENU_TOP,
    MENU_CURRENT,
    MENU_PARAM_NEXT, /*9 */
}menu_act_ret_t;

typedef enum {
    MENU_LEVEL_0 = 0,
    MENU_LEVEL_1,
    MENU_LEVEL_2,
    MENU_LEVEL_MAX,
}MENU_LEVEL_E;

/*菜单列表索引列举*/
typedef enum {
    /*level-1 menu index*/
    MENU_IDX_TOP = 0,

    /*level-2 menu index*/
    MENU_IDX_SECOND_1,
    MENU_IDX_SECOND_2,
    MENU_IDX_SECOND_3,
    MENU_IDX_SECOND_4,

    /*level-3 menu index*/
    MENU_IDX_THRID_11,
    MENU_IDX_THRID_12,
    MENU_IDX_THRID_12,
    MENU_IDX_THRID_14,
    MENU_IDX_THRID_15,

    MENU_IDX_THRID_21,
    MENU_IDX_THRID_22,
    MENU_IDX_THRID_23,
    MENU_IDX_THRID_24,
    MENU_IDX_THRID_25,
    MENU_IDX_THRID_26,

    MENU_IDX_THRID_31,
    MENU_IDX_THRID_32,
    MENU_IDX_THRID_33,
    MENU_IDX_THRID_34,
    MENU_IDX_THRID_35,

    MENU_IDX_THRID_41,
    MENU_IDX_THRID_42,
    MENU_IDX_THRID_43,
}MENU_IDX_E;

typedef struct str_menu_table {
    MENU_IDX_E table_index;

    uint8_t select_index;
    uint8_t esc_index;

    uint32_t max_key_val;

    MENU_LEVEL_E level;
    bool has_submenu;

    menu_act_ret_t  (* act)(uint8_t idx);
    display_info_t* (* caption)(prt_menu_ctrl_t *menu, menu_act_ret_t act);
}menu_table_t;

菜单表项结构体(struct str_menu_table)定义如上,成员介绍如下:

1.table_index是各个菜单项的索引,用来跳转选择菜单表项(参见后续代码)

2.select_index、esc_index,分别表示在处在该菜单表项时,按选择键和退出键的跳转菜单索引。注意,只有选择和退出可以跳转菜单表项,上下键只会处理显示菜单内容的更新

3.max_key_val表示该菜单按键值最大值,比如该菜单只有3个子菜单项,max_key_val就是3。

4.level表示该菜单处在哪一级菜单上,退出时需要跳转到上一级菜单需要用到。

5.has_submenu表示该菜单项有没有子菜单项。

6.act函数,可以作为菜单选项选择某项之后,执行保存菜单参数或设置的回调函数。

7.caption函数响应上下按键,根据按键key值更新显示内容,返回的就是需要显示的内容。

typedef void (*menu_display_t)(display_info_t* info);

typedef struct str_menu_control {
    MENU_IDX_E curr_idx;
    uint8_t key_val;
    uint8_t rollback;
    uint8_t menu_level;
    uint8_t menu_table_size;

    MENU_LANGUAGE_E language;
    /*Record item for each menu level*/
    uint8_t menu_item[16];

    menu_display_t display;
    uint8_t (* checkmenu)(void);

    uint8_t display_buf[512];
    display_info_t display_info;
}menu_ctrl_t;

除了菜单表项结构体,还需要一个菜单控制结构体定义如上,该结构体的作用就是在代码中,掌握全部菜单项的控制、跳转以及菜单内容显示。说明如下:

1.curr_idx记录单前菜单表项索引值,表示目前在哪一个菜单表项上。

2.key_val,表示当前按键菜单的上下键按键值,最大不超过该菜单表项的max_key_val,超过就回到0重新开始。代码可以自己定义按上键key_val加1还是减一。我这里使用的是按上键减1,按下键加1。

3.rollback用来指示key_val值要不要翻转,比如加到max_key_val之后要不要回到0重新开始,或者减到0之后,要不要回到max_key_val-1。相应就是菜单项会不会循环跳转。

4.menu_level表示当前处在哪一级菜单中,当按选择键或者退出键时,需要把当前这级菜单的key_val记录到menu_item[]数组中,以便退出时能正确显示上一级菜单的菜单项。

5.menu_item[]数组如上所

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值