onlineforyou 发表于 2009-11-10 08:10:27

请教多级菜单中的函数指针问题

#define u8 unsigned char

void (*KeyFuncPtr)(); //按键功能指针

typedef struct{
      u8 KeyStateIndex; //当前状态索引号
      u8 KeyEnterState; //按下"确认"键时转向的状态索引号
      u8 KeyExitState; //按下"返回"键时转向的状态索引号
      u8 KeyUpState;//按下"向上"键时转向的状态索引号
      u8 KeyDownState;//按下"向下"键时转向的状态索引号
      void (*CurrentOperate)(); //当前状态应该执行的功能操作
}KbdTabStruct;


KbdTabStruct volatile const code KeyTab[]={

//       |-----------> Index
//       |Enter
//       ||Exit
//       |||Up
//       ||||Down   --->功能函数
//       |||||       |
       { 0, 1, 2, 3, 4,(*DispMenuInit)},   // 图标层菜单:第一级菜单
       { 1, 0, 0, 0, 0,(*DispMenuEnter)},
       { 2, 0, 0, 0, 0,(*DispMenuExit)},
       { 3, 0, 0, 0, 0,(*DispMenuUp)},
       { 4, 0, 0, 0, 0,(*DispMenuDown)},
      
       .......
      
       ........
      
       { 200, 201, 202, 203, 204,(*DispMenuInit)},   // :第四级菜单
       { 201, 0,   0,   0,    0, (*DispMenuEnter)},
       { 202, 0,   0,   0,    0,(*DispMenuExit)},
       { 203, 0,   0,   0,    0,(*DispMenuUp)},
       { 204, 0,   0,   0,    0,(*DispMenuDown)},
      
   
};   
请问当 KeyStateIndex >= 100后编译后程序就跑飞了,好像堆栈溢出了,是不是当索引号大时,函数指针到不了指定的函数了,比如当 KeyStateIndex =200时,要执行对应的函数:void DispMenuInit(void),就溢出了,这种现象是什么原因呢?麻烦各位指教,谢谢!

cuiyun 发表于 2009-11-10 08:40:12

不懂

lusson 发表于 2009-11-10 10:11:00

应该不会存在这样的问题
你的菜单是怎么嵌套的?

Eiman 发表于 2009-11-10 12:15:10

你的“......”是不是真的有5到199?数组必须要有205个,否则有误

onlineforyou 发表于 2009-11-10 12:43:52

是的,从0到204
我是引用本站中的那个"一个占用内存最少的菜单“中的例子

main中调用菜单按键程序
void main(void)
{
while(1)
{
MenuCheckKey();
}
}
//-------------------------//
void MenuCheckKey(void)
{
    u8 key = 0;
   
    key = KeyScan();
    switch(key)
    {
      case Key_Enter:{ //确认键,找出新的菜单状态编号
            KeyFuncIndex=KeyTab.KeyEnterState;
            KeyFuncPtr=KeyTab.CurrentOperate;
            (*KeyFuncPtr)();//执行当前按键的操作
            break;
      }
      case Key_Exit:{ //退出键,找出新的菜单状态编号
            KeyFuncIndex=KeyTab.KeyExitState;
            KeyFuncPtr=KeyTab.CurrentOperate;
            (*KeyFuncPtr)();//执行当前按键的操作
            break;
      }
      case Key_Up:{ //向上键,找出新的菜单状态编号
            KeyFuncIndex=KeyTab.KeyUpState;
            KeyFuncPtr=KeyTab.CurrentOperate;
            (*KeyFuncPtr)();//执行当前按键的操作
            break;
      }
      case Key_Down:{ //向下键,找出新的菜单状态编号
            KeyFuncIndex=KeyTab.KeyDownState;
            KeyFuncPtr=KeyTab.CurrentOperate;
            (*KeyFuncPtr)();//执行当前按键的操作
            break;
      }

//---------------------------------------------------------------------------
      default: //按键错误的处理
            break;
    }
   
    if(Flash)
    {
   
      KeyFuncPtr = KeyTab.CurrentOperate;
      (*KeyFuncPtr)();//执行当前按键的操作
      Flash = 0;
    }
   
}

pigeon0411 发表于 2010-2-4 16:14:59

内存不够的表现

ksniper 发表于 2010-2-4 16:16:37

mark 慢慢学习

mynameis 发表于 2010-2-5 02:02:05

感觉楼主搞得有点复杂了,可以考虑用函数指针数组来简化模型。

hpdell 发表于 2010-4-22 17:48:02

太复杂,看不懂!!!!!我也在找菜单函数,但是有很多都看不懂,特别是里面的那些数值,不知道是根据什么来计算的,要是有个比较详细的例程就好了!!!!!!!!!!!!!

xsky 发表于 2010-4-22 21:28:21

回复【8楼】hpdell
-----------------------------------------------------------------------

那些数值就是按下对应按键后要跳转的目标KeyStateIndex。

xsky 发表于 2010-4-22 21:30:02

回复【7楼】mynameis
-----------------------------------------------------------------------

其实这个应该就算是比较简单的了,KbdTabStruct volatile const code KeyTab …… 就是已经初始化了菜单关系及函数指针。

C.Ronaldo 发表于 2010-4-23 10:19:15

静下心看1 2天就不觉得难了!

haydon123 发表于 2011-4-21 20:09:26

m

cumtgao 发表于 2011-5-12 14:00:00

最近也为菜单在烦

yaxi1984 发表于 2011-5-14 20:07:34

这个是Keil C51编译器的限制,Keil C51对于函数指针是不完全支持的。
欲知详情,请参阅: http://www.keil.com/appnotes/docs/apnt_129.asp

当初我也是在C51中采用了函数指针,导致了某些非常诡异的现象,找了好久才发现这个限制的,希望能有所帮助。

mengzhihu2 发表于 2011-5-14 20:22:59

有时间看看我也看看怎么弄。。。。

g___1 发表于 2011-5-15 11:50:47

不懂啊

cctv02 发表于 2011-10-27 00:42:24

mark

liuchuanxhu 发表于 2012-5-12 08:31:16

正在研究中…………

jinjin_xia 发表于 2012-12-11 15:52:30

想问一下,这个数据结构中,执行函数怎么对具体数据进行修改呢,按一下ENTER按鍵马上就返回了
页: [1]
查看完整版本: 请教多级菜单中的函数指针问题