使用函数指针实现多级菜单

/*

多级菜单v2.0

作者:Adam

单片机多级菜单

  • 这是一个使用函数指针实现的多级菜单
typedef struct _MENU_OptionTypeDef // 选项结构体
{
    char *String;       // 选项字符串
    void (*func)(void); // 选项功能 函数指针
} MENU_OptionTypeDef;
  • 使用方法

1. 创建选项列表,并直接初始化, 每个选项对应其名字和功能(直接填写函数名), 例如:
static MENU_OptionTypeDef MENU_OptionList[] = {{"<<<", NULL},                     // 固定格式, 用于退出
                                               {"Tools", MENU_RunToolsMenu},      // 工具
                                               {"Games", MENU_RunGamesMenu},      // 游戏
                                               {"Setting", MENU_RunSettingMenu},  // 设置
                                               {"Information", MENU_Information}, // 信息
                                               {"..", NULL}};                     // 固定格式, 用于计算选项列表长度和退出                                          
2. 调用 MENU_RunMenu() 运行菜单, 参数为选项列表
MENU_RunMenu(MENU_OptionList);
3. 为了实现多级菜单, 可使用一个函数来封装 第1 第2 步, 封装好的函数可作为功能被其他菜单调用, 以此实现不限层级多级菜单, 例如:
void MENU_RunMainMenu(void)
{
    static MENU_OptionTypeDef MENU_OptionList[] = {{"<<<"},
                                                   {"Tools", MENU_RunToolsMenu},      // 工具
                                                   {"Games", MENU_RunGamesMenu},      // 游戏
                                                   {"Setting", NULL},                 // 设置
                                                   {"Information", MENU_Information}, // 信息
                                                   {".."}};
    MENU_RunMenu(MENU_OptionList);
}

void MENU_RunToolsMenu(void)
{
    static MENU_OptionTypeDef MENU_OptionList[] = {{"<<<"},
                                                   {"Seria", NULL},         // 串口
                                                   {"Oscilloscope ", NULL}, // 示波器
                                                   {"PWM Output", NULL},    // PWM 输出
                                                   {"PWM Input", NULL},     // PWM 输入
                                                   {"ADC Input", NULL},     // ADC 输入
                                                   {".."}};
    MENU_RunMenu(MENU_OptionList);
}

*例如以上 void MENU_RunToolsMenu(void) 被选项 {"Tools", MENU_RunToolsMenu} 调用;

  • 移植方法

*注: 显示器驱动需要使用缓冲区机制, 如 u8g2

1. 配置菜单宏定义, 兼容不同显示器及布局, 例如:
    #define MENU_WIDTH 128 // 菜单宽度
    #define MENU_HEIGHT 64 // 菜单高度
2. 实现 menu_command_callback() 对应的指令功能以完成移植, 例如:
    case BUFFER_DISPLAY:
        OLED_Update();
        break;

*有些指令是有参数的, 参数已经提取好, 按需使用参数即可, 例如:

    case SHOW_STRING:
        {
            /* 提取参数列表 */
            int *arg_list = ((int *)&command) + 1;
            int show_x = arg_list[0];
            int show_y = arg_list[1];
            char *show_string = (char *)arg_list[2];

            /* 按需使用参数 */
            OLED_Printf(show_x, show_y, MENU_FONT_W, show_string);
            break;
        }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值