发 帖  
原厂入驻New
申请华秋企业认证 多层板首单免费打样!
30s提交资料,10分钟通过审核(免费赔付+顺丰包邮)>>立即报名
LCD多级菜单还有哪些问题?
445 按键 main 函数
分享
最近在做一个多级菜单项目,看了很多资料,大体分两种设计思路:1、通过双向链表实现;2、通过数组实现。思路无非是把菜单联系起来,可以跳到下级菜单,也可以返回上级菜单。用傻孩子的双向链表的方法,大体上实现了。但是有些细节没有想明白,感觉代码写的一团糟。现在发帖,和大家一起谈论下。
傻孩子给的历程,一会我以附件的形式给出。
/***********************
* 结构体宏定义 *
***********************/
struct MenuItem
{
char MenuCount;                         //本级菜单项目数
char *displayString;                      //本菜单显示字符串
void (*Subs)();                           //本菜单对应的功能函数,可以为NULL
struct MenuItem *ChildrenMenus;   //下级菜单指针,可以为NULL
struct MenuItem *ParentMenus;    //上级菜单指针,可以为NULL
}NULL_MENU;
问题1:
char *DisplayString 这个变量有必要吗?
只给显示函数函数要显示的内容,不给坐标,有什么用?
问题2:
按着下面给出的历程,每个按键的功能,在每个界面都是一样的,如果不同的界面,按键含义不同,怎处理?
问题3:
void (*Subs)()指向的函数,只有当按下Enter键时候才执行,也就是说void (*Subs)()指向的函数一旦返回,就不能再进入。这样就有问题,当用户要输入参数时候,加入没有输入完,函数是不能返回的,这个时候就会阻塞main函数,怎么解决?
int main()
{                     
    short KeyNum = 0xff;
    SystemInitialation();            //系统初始化
    ShowMenu();
        while(1)
        {
            ClearWatchDog();             //喂狗
            KeyNum = GetKeyNum();        //获取按键值
            /*******************目录操作*********************/
            /***************************************
            *   [按键说明]                         *
            *  ----------------------------------- *
            *   [K1]            UP(向上)           *
            *   [K5]            Down(向下)         *
            *   [K2]            Esc(后退)          *
            *   [K6]            Enter(确定)        *
            *   [K3]            返回根目录         *
            ***************************************/
            IF (KeyNum != 0xff)
            {
             ShowMenu();
                 switch(KeyNum)
                 {
                     case UP:
                         UserChoose --;
                         if (UserChoose < 0)
                         {
                             UserChoose = MaxItems-1;
                         }
                         break;
                     case Esc:
                         if (MenuPoint[0].ParentMenus != &Null)
                         {
                             MenuPoint = MenuPoint[0].ParentMenus;
                             UserChoose = 0;
                             DisplayStart = 0;
                         }
                         break;
                     case Down:
                         UserChoose ++;
                         if (UserChoose == MaxItems)
                         {
                             UserChoose = 0;
                         }
                         break;
                     case Enter:
                         if (MenuPoint[UserChoose].Subs != NullSubs)
                         {
                             (*MenuPoint[UserChoose].Subs)();
                         }
                         else if (MenuPoint[UserChoose].ChildrenMenus != &Null)
                         {
                             MenuPoint = MenuPoint[UserChoose].ChildrenMenus;
                             UserChoose = 0;
                             DisplayStart = 0;
                         }
                         break;
                     case Reset:
                         MenuPoint = MainMenu;
                         UserChoose = 0;
                         DisplayStart = 0;
                         break;
                 }
                 if ((UserChoose < DisplayStart) || (UserChoose > (DisplayStart+3)))
                 {
                    DisplayStart = UserChoose;
                 }
                 ShowMenu();
            }
            /*******************目录操作*********************/
        }
}
傻孩子菜单历程.rar (3.42 KB )
0
2019-8-18 16:23:40   评论 分享淘帖 邀请回答

相关问题

33个回答
ST官方有一个软件包STM32F10x_AN2790_FW_V2.0.0,里面有一个简单的菜单结构,最近我自己做的一个菜单就是按照里面的菜单结构的思路扩充的,可以参考一下
menu.zip (9.52 KB )
2019-8-19 02:04:22 评论

举报

2019-8-19 02:12:14 评论

举报

目前用二维数组来做多级菜单,效果还可以,虽然没有链表做菜单强,但胜在节省了很多SRAM,在SRAM资源充足的情况下还是建议用链表不要用数组
2019-8-19 02:32:06 评论

举报

NULL_MENU *p_menu;假设有三个菜单menu1,menu2,menu3
然后具体按键中判断
if (p_menu == &menu1)
else if (p_menu == &menu2)
……
手机不好打字,只好打个大概不知楼主看懂没
主要就是比较当前指针与哪个菜单的地址匹配
2019-8-19 02:39:20 评论

举报

就是状态机,不是太复杂用switch也不错的
2019-8-19 02:50:23 评论

举报

switch+goto就够了,简单
2019-8-19 03:04:38 评论

举报

问题1、2:这个菜单结构只能实现简单的界面变化,也就是说每个界面的标题位置是固定的。例如:手抄器、手持控制器等界面比较简单
问题3:我觉得不会
2019-8-19 03:19:04 评论

举报

谢谢,我参考下,我有不明的地方,还望您多多指教。
2019-8-19 03:25:17 评论

举报

问题3为什么不会呢?
2019-8-19 03:32:28 评论

举报

几个界面可以用switch,界面多了,代码就有点乱,也不利于修改。
2019-8-19 03:40:56 评论

举报

那还不如用我现在的函数指针的方法,条例还清晰,也便于修改和维护。
2019-8-19 03:54:48 评论

举报

大体上明白,就是现判断目前的界面处于那个界面,然后去执行本界面相关的函数或者操作。
2019-8-19 04:12:46 评论

举报

为什么费SRAM呢?前面加const不就完了,所有的结构体都在ROM里。
2019-8-19 04:30:14 评论

举报

结构体加const???恕我C语言基础薄弱,如果加了const还能修改里面的内容么?
比如菜单当前索引号占据了1个字节,函数指针占据4个字节,光是这2个东西都用了5个字节了,还没算上其他呢
2019-8-19 04:36:58 评论

举报

结构体,为什么就不能加const?
.h文件里声明一个结构体:
struct        MenuItem
{
        _UBYTE                                MenuCount;                //本层菜单项目数
        void                                (*Subs)();                //本层菜单执行函数
        struct        MenuItem        *ChildrenMenus;        //子菜单指针
        struct        MenuItem        *ParentMenus;        //父菜单指针
};
在.C文件里定义一个变量:
/*****************一级菜单***************/
//首页
const        struct        MenuItem        Menu_USER_Frist_struct[3]=
{
//        {2,USER_LCD_Frist_Function,(struct        MenuItem*) Menu_USER_Second1,(struct        MenuItem*)NULL},
        {2,USER_LCD_Frist_Function,(struct        MenuItem*) NULL,(struct        MenuItem*)NULL},
        {2,USER_LCD_Frist_Function,(struct        MenuItem*) Menu_USER_Second2,(struct        MenuItem*)NULL},
        {1,USER_LCD_Frist_Function,(struct        MenuItem*)&Menu_USER_Second3,(struct        MenuItem*)NULL},
};
怎么就废SRAM了?全部在ROM里。
2019-8-19 04:55:18 评论

举报

结构体,为什么就不能加const?
.h文件里声明一个结构体:
struct        MenuItem
{
        _UBYTE                                MenuCount;                //本层菜单项目数
        void                                (*Subs)();                //本层菜单执行函数
        struct        MenuItem        *ChildrenMenus;        //子菜单指针
        struct        MenuItem        *ParentMenus;        //父菜单指针
};
在.C文件里定义一个变量:
/*****************一级菜单***************/
//首页
const        struct        MenuItem        Menu_USER_Frist_struct[3]=
{
//        {2,USER_LCD_Frist_Function,(struct        MenuItem*) Menu_USER_Second1,(struct        MenuItem*)NULL},
        {2,USER_LCD_Frist_Function,(struct        MenuItem*) NULL,(struct        MenuItem*)NULL},
        {2,USER_LCD_Frist_Function,(struct        MenuItem*) Menu_USER_Second2,(struct        MenuItem*)NULL},
        {1,USER_LCD_Frist_Function,(struct        MenuItem*)&Menu_USER_Second3,(struct        MenuItem*)NULL},
};
怎么就废SRAM了?全部在ROM里。
2019-8-19 05:11:31 评论

举报

引用傻孩子的一句话:你真的理解了这个菜单了?
2019-8-19 05:18:40 评论

举报


我用了你给的代码做了个测试,在菜单结构里面加了个索引号index来指示当前菜单索引到哪个子菜单,但只要对这个索引号进行修改就出现图中的错误,很明显存放在FLASH里面的数据是不能直接修改的,不知道是我理解错了还是你理解错了
2019-8-19 05:30:10 评论

举报

你好好看看傻孩子给的历程,就明白了。
2019-8-19 05:49:54 评论

举报

只有小组成员才能发言,加入小组>>

12下一页

878个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表