搜索
bottom↓
回复: 17

[求助]希望哪位大神能详细解释下基于结构体的那个菜单。

[复制链接]

出0入0汤圆

发表于 2014-5-27 17:55:22 | 显示全部楼层 |阅读模式
如题,看了傻孩子的,网上也找了一些,还是看不明白,原谅我这么菜,我找到的程序都没什么注释,说实话真的看不懂,越看越绕,越迷糊。。在此希望哪位大神能给来一个详细的解答。。。拜谢!!!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2014-5-28 08:46:34 | 显示全部楼层
呃,难道这个问题太简单了??竟然没有人回答???

出0入0汤圆

发表于 2014-5-28 08:57:20 | 显示全部楼层
lswhome 发表于 2014-5-28 08:46
呃,难道这个问题太简单了??竟然没有人回答???

可以先研究架构

再研究结构体啊

http://www.amobbs.com/forum.php? ... p;extra=#pid7570190

出0入0汤圆

 楼主| 发表于 2014-5-28 10:34:50 | 显示全部楼层
我现在的菜单感觉很土,会浪费大量的代码空间。。。坑。。。

  1. static void System_Set(void)//环境设置子菜单
  2. {
  3.         UINT8 xdata Select=0;
  4.         UINT8 xdata Last_Select=0;
  5.         bit          RePaint=1;//是否重画整个菜单项


  6.         while(1)
  7.         {
  8.                 if(RePaint==1)
  9.                 {
  10.                         ST7565_Paint_RectangleFill(0,0,64,128,0);//清屏
  11.                         ST7565_Paint_Rectangle(0,10,64,108,1);
  12.                         ST7565_Paint_HLine(13,10,108,1);//横线
  13.                         ST7565_Paint_MixStr(1,40,"环境设定",0);
  14.                 }

  15.                 if(Select==0 || Last_Select==0 || RePaint==1)
  16.                 {
  17.                         ST7565_Paint_MixStr(19,40,"系统时间",(Select==0)?1:0);
  18.                 }               

  19.                 if(Select==1 || Last_Select==1 || RePaint==1)
  20.                 {
  21.                         ST7565_Paint_MixStr(32,40,"屏幕设定",(Select==1)?1:0);
  22.                 }               

  23.                 if(Select==2 || Last_Select==2 || RePaint==1)
  24.                 {
  25.                         ST7565_Paint_MixStr(45,40,"重启模式",(Select==2)?1:0);
  26.                 }               

  27.                 RePaint=0;
  28.                 Last_Select=Select;//保存上次的选择
  29.                 ST7565_Paint_Push_Data();//刷新显示

  30.                 //键盘
  31.                 Key_Scan();//扫描键盘
  32.                 while(Key_Trg==0)//等待按一个键
  33.                 {
  34.                         Key_Scan();//扫描键盘
  35.                 }

  36.                 if(Key_Trg & Key_Cancel)//Key_Cancel
  37.                 {
  38.                         break;
  39.                 }
  40.                 if(Key_Trg & Key_plus)//Key_+
  41.                 {
  42.                         (Select>1)?(Select=0):(Select++);
  43.                 }

  44.                 if(Key_Trg & Key_Minus)//Key_-
  45.                 {
  46.                         (Select<1)?(Select=2):(Select--);
  47.                 }

  48.                
  49.                 if(Key_Trg & Key_Ok)//Key_Ok
  50.                 {
  51.                         if(Select==0)
  52.                         {
  53.                                 Menu_Time_Set();//时间设定
  54.                         }

  55.                         if(Select==1)
  56.                         {
  57.                                 Menu_Screen_Set();//屏幕设定
  58.                         }
  59.                        
  60.                         if(Select==2)
  61.                         {
  62.                                 Menu_Boot_Operating();//重启后操作
  63.                         }                       
  64.                         ST7565_Paint_RectangleFill(0,0,64,128,0);//清屏
  65.                         RePaint=1;
  66.                 }
  67.         }
  68. }
复制代码


一个菜单一个函数,都是类似这样的,这样的好处就是节省内存,什么样的奇葩菜单都能做的出来(包括那种可以编辑的,可以调整数字之类的),缺点就是浪费大量的代码空间。。。感觉不好

出0入0汤圆

 楼主| 发表于 2014-5-28 10:38:29 | 显示全部楼层
比如这个也算是个菜单,可以调整一些参数,界面也不难看。


  1. static void Menu_Screen_Set(void)//屏幕设定
  2. {

  3.         UINT8 xdata Select=0;
  4.         UINT8 xdata Last_Select=0;
  5.         bit RePaint_Menu=1;
  6.        
  7.         UINT8  xdata str[4];
  8.         UINT8 xdata tmp1=Roms[0];
  9.         UINT8 xdata tmp2=Roms[1];
  10.         UINT8 xdata tmp3=Roms[31];
  11.         bit          RePaint=1;//是否重画整个菜单项

  12.         while(1)
  13.         {
  14.                 if(RePaint==1)
  15.                 {
  16.                         ST7565_Paint_RectangleFill(0,0,64,128,0);//清屏
  17.                         ST7565_Paint_Rectangle(0,8,64,112,1);//边框
  18.                         ST7565_Paint_HLine(13,8,112,1);//横线
  19.                         ST7565_Paint_MixStr(1,40,"屏幕设定",0);

  20.                         ST7565_Paint_MixStr(18,28,"屏幕对比度",0);
  21.                     ST7565_Paint_MixStr(32,19,"关闭时间 时  分",0);
  22.                         ST7565_Paint_MixStr(46,22,"数码管对比度",0);

  23.                         ST7565_Paint_HLine(30,88,12,1);//
  24.                         ST7565_Paint_HLine(44,67,6,1);//
  25.                         ST7565_Paint_HLine(44,85,12,1);//                       
  26.                         ST7565_Paint_HLine(58,94,12,1);//

  27.                 }
  28.                 if(Select==0 || Last_Select==0 || RePaint_Menu==1)//选择了第1项
  29.                 {
  30.                         sprintf(str,"%02d", (UINT16)tmp1);//对比度
  31.                         ST7565_Paint_MixStr(18,88,str,(Select==0)?1:0);
  32.                 }
  33.                
  34.                 if(Select==1 || Last_Select==1 || RePaint_Menu==1)//选择了第1项
  35.                 {       
  36.                         sprintf(str,"%01d", (UINT16)(tmp2/60));//
  37.                         ST7565_Paint_MixStr(32,67,str,(Select==1)?1:0);//时
  38.                         sprintf(str,"%02d", (UINT16)(tmp2%60));//
  39.                         ST7565_Paint_MixStr(32,85,str,(Select==1)?1:0);//分
  40.                 }
  41.        
  42.                 if(Select==2 || Last_Select==2 || RePaint_Menu==1)//选择了第1项
  43.                 {
  44.                         sprintf(str,"%02d", (UINT16)(tmp3));//
  45.                         ST7565_Paint_MixStr(46,94,str,(Select==2)?1:0);//数码管对比度
  46.                 }

  47.                
  48.                 RePaint=0;
  49.                 Last_Select=Select;//保存上次的选择
  50.                 ST7565_Paint_Push_Data();//刷新显示

  51.                 //键盘
  52.                 Key_Scan();//扫描键盘
  53.                 while(Key_Trg==0)//等待按一个键
  54.                 {
  55.                         Key_Scan();//扫描键盘
  56.                 }

  57.                 if(Key_Trg & Key_Cancel) break;

  58.                 if(Key_Trg & Key_Select)
  59.                 {
  60.                         Select>1?Select=0:Select++;
  61.                 }

  62.                 if(Key_Trg & Key_plus)
  63.                 {
  64.                         if(Select==0) (tmp1>51)?(tmp1=25):(tmp1++);//对比度
  65.                         if(Select==1) (tmp2>254)?(tmp2=1):(tmp2++);//关屏时间
  66.                         if(Select==2)  (tmp3>6)?(tmp3=0):(tmp3++);
  67.                 }

  68.                 if(Key_Trg & Key_Minus)
  69.                 {
  70.                         if(Select==0) (tmp1<26)?(tmp1=52):(tmp1--);//对比度
  71.                         if(Select==1) (tmp2<2)?(tmp2=255):(tmp2--);//关屏时间
  72.                         if(Select==2) (tmp3<1)?(tmp3=7):(tmp3--);
  73.                 }

  74.                 if(Key_Trg & Key_Ok)
  75.                 {
  76.                         Roms[0]=tmp1;//对比度的值
  77.                         Roms[1]=tmp2;//关屏时间的值                       
  78.                         Roms[31]=tmp3;
  79.                         SaveOfSetting();//保存设置
  80.                         break;
  81.                 }
  82.                 ST7565_Set_Contrast(tmp1);//即时做出对比度的设定
  83.                 TM1638_SetContrast(tmp3);//立即更改TM1638的对比度
  84.         }

  85. }

复制代码

出0入0汤圆

发表于 2014-5-28 18:38:19 | 显示全部楼层
mark。。。

出130入129汤圆

发表于 2014-5-28 18:46:56 | 显示全部楼层
lswhome 发表于 2014-5-28 10:38
比如这个也算是个菜单,可以调整一些参数,界面也不难看。

这个函数,里面有while循环,你要是不按键让其跳出,单片机不就在死等了?

出0入0汤圆

 楼主| 发表于 2014-5-28 22:17:30 | 显示全部楼层
68336016 发表于 2014-5-28 18:46
这个函数,里面有while循环,你要是不按键让其跳出,单片机不就在死等了? ...

是的,这个死等就能达到要求哇。。。
不要死等的也可以,就是里面没有WHILE,类似扫描键盘那种,高速扫描,如果有改变,就会显示改变的内容,如果没有改变,则进入函数就会自动退出,啥也不执行。。。总之我这种菜单就是很浪费代码资源,但要说实现的功能,貌似我目前的简单应用都能达到。话说那结构体的菜单真没人回答呀,唉。。。。

出130入129汤圆

发表于 2014-5-28 23:41:28 | 显示全部楼层
lswhome 发表于 2014-5-28 22:17
是的,这个死等就能达到要求哇。。。
不要死等的也可以,就是里面没有WHILE,类似扫描键盘那种,高速扫描 ...

我就是仿造傻孩子的那种结构体菜单的

MenuItem SpeedSelectMenu[SPEEDSELECT_MENUCOUNT] =
{        //MenuCount,ParentIndex,MenuString,MenuFunc,SubMenu,ParentMenu
        {SPEEDSELECT_MENUCOUNT,0,"速度1=     RPM",Gui_SelectCoef_Ns1,NULL,MainMenu},
        {SPEEDSELECT_MENUCOUNT,0,"速度2=     RPM",Gui_SelectCoef_Ns2,NULL,MainMenu},
        {SPEEDSELECT_MENUCOUNT,0,"速度3=     RPM",Gui_SelectCoef_Ns3,NULL,MainMenu},
        {SPEEDSELECT_MENUCOUNT,0,"速度4=     RPM",Gui_SelectCoef_Ns4,NULL,MainMenu},
};

平时菜单翻滚,进入,退出通过一个函数A来刷新,这函数A在main的主循环调用
如果进入到了菜单函数B,那么就那么通过修改函数指针pGuiFunction,把main主循环里的函数改成函数B
这样主循环就不会堵死,其它事情也能得到处理。

虽然看起来比较龌龊,但是没有其它更好思路前,我这么用也没出什么问题

main()
{
        while(1)
        {
                (*pGuiFunction)();
                其他一些函数();
        }
}

出0入0汤圆

 楼主| 发表于 2014-5-29 00:17:45 | 显示全部楼层
唉。。。我理解能力太有限了,我还是自己琢磨写一个结构体的菜单吧,回头写出来了,贴出来大家给指点指点一下吧,我现在就是看不懂使用怎样的一个逻辑来做这个菜单,而且感觉这样结构体的菜单会吃掉很多的内存,因为结构体说白了都是一堆数组,这些数组都是在内存里。

出0入264汤圆

发表于 2014-5-29 08:08:49 | 显示全部楼层
你的思路是对的。不需要使用结构体的菜单。即便是使用结构体,最终的调整设置等界面的方式还是类似于你写的这样。
菜单只是界面中的很少的一部分。真正占大头的还是各种参数设置调整界面。所以坚持你目前的方式,然后思考,如何让代码更加简洁
更加层次清晰。先给你一点提示:把按键扫描部分,从界面中分离出来。你可以按照这个方向去思考你的改进方法。

出0入0汤圆

 楼主| 发表于 2014-5-29 13:15:44 | 显示全部楼层
mcu_lover 发表于 2014-5-29 08:08
你的思路是对的。不需要使用结构体的菜单。即便是使用结构体,最终的调整设置等界面的方式还是类似于你写的 ...

嗯,明白您的意思了,现在我也学会了结构体菜单的基本工作逻辑,得空了就写一个比较通用的,这样在很多项目上只要拿过来稍微修改就可以使用了,这样会节省很多时间。。。感谢各位的指点!!谢谢!!!

出0入0汤圆

发表于 2014-5-29 18:49:12 | 显示全部楼层
过来看一下

出0入0汤圆

发表于 2014-5-30 09:54:42 | 显示全部楼层
傻孩子的菜单在哪?链接给个

出0入0汤圆

发表于 2015-2-11 15:43:14 | 显示全部楼层
mcu_lover 发表于 2014-5-29 08:08
你的思路是对的。不需要使用结构体的菜单。即便是使用结构体,最终的调整设置等界面的方式还是类似于你写的 ...

是不是把按键结果放入消息队列,在要用的界面中去查看消息队列?

出0入264汤圆

发表于 2015-2-11 16:32:01 | 显示全部楼层
黄晨0410 发表于 2015-2-11 15:43
是不是把按键结果放入消息队列,在要用的界面中去查看消息队列?

是的。 消息队列中的消息,始终只由当前界面进行处理。

出0入0汤圆

发表于 2015-2-11 17:01:23 | 显示全部楼层
正在学习你的贴子,

出0入0汤圆

发表于 2015-4-15 17:01:35 | 显示全部楼层
mcu_lover 发表于 2014-5-29 08:08
你的思路是对的。不需要使用结构体的菜单。即便是使用结构体,最终的调整设置等界面的方式还是类似于你写的 ...

love点评总是很到位
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 09:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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