标题: 单片机实现多级菜单 [打印本页]

作者: cheng734398377    时间: 2015-6-14 09:57
标题: 单片机实现多级菜单
看到网上有个视频,用的是12864做的菜单,很花哨,自己也心痒痒想做一个,收集了 很多关于这方面的东西,但是都是五花八门,没有一个完整的可以共大家参考的程序,所以决定写偏文章供大家参考,希望读者下去自己优化,改进。有什么不足之处还请多多包涵。好了,废话不多说,直接进入正题吧。

1、首先定义一个机构体如下
typedef struct
   {
     uchar current;
     uchar up;//上键
     uchar down;//下键
     uchar enter;//确认键
     void (*current_operation)();
     } key_table;


结构体包含5个变量,分别是函数的索引号即用户想要执行哪个函数的代号,然后有三个键,用户可以自己定义别的按键,最后一个是函数指针,即索引号对应的函数。然后在定义一个结构体数组,如下
key_table code table[n]=
{
     {0,2,1,3,(*fun1)},
     {1,0,2,4,(*fun2)},
     {2,1,0,5,(*fun3)},                  
     {3,0,6,3,(*fun4)},
     {4,1,6,4,(*fun5)},                       
     {5,2,6,5,(*fun6)},
     {6,0,0,0,(*fun7)},
     ............                                          
};
其中n为函数数组大小。下面详细介绍key_table code table[n]里面的值是怎么确定的。
首先可以先这样定义该数组
key_table code table[n]=
{
     {0,x,y,z,(*fun1)},
     {1,x,y,z,(*fun2)},
     {2,x,y,z,(*fun3)},                  
     {3,x,y,z,(*fun4)},
     {4,x,y,z,(*fun5)},                       
     {5,x,y,z,(*fun6)},
     {6,x,y,z,(*fun7)},
     ............                                          
};
其中,x,y,z是未知数,先不确定,他们对应的是三个键按下要指示的索引值,如果四个键,就有四个未知数,在确定他们之前,必须要了解自己函数执行什么命令。加入开始时时执行数组里面的第一个即table[0],而想在此按上键执行函数fun6,那么table[0]里面需要这样设置
{0,5,y,z,(*fun1)},同样,如果希望按下键执行fun7则需要设置为
{0,x,6,z,(*fun1)},如果希望按确认键执行fun3则需要设置为
{0,x,y,2,(*fun1)};如果上面三种情况都想要就设置为
{0,5,6,2,(*fun1)}.其它数组元素一次类推。这一步做完了看主程序里面(主要是while(1)里面)。
/*******************find index****************************/
              switch(key)
              {
case 0x44:                                                            func_index=table[func_index].up;    //向上翻                                           break;
case 0x24:                                           func_index=table[func_index].enter;//回车
break;
case 0x14:                                           func_index=table[func_index].down;//向下翻
break;
default:break;

                  }                                current_operation_index=table[func_index].current_operation;
(*current_operation_index)();//执行当前操作函数

其中,key是返回的按键值,这个用户视情况而定,
下面是详细的例子,
主要是以结构体为基础设计的,以12864显示函数代替了用户需要的函数功能,只需要修改相应的函数和索引号,就可以达到任意界面切换了是小弟研究了还久才搞定的,虽然网上也有这些,但是都不够系统,只有基本的东西,这篇例子希望能够给读者一些有用的东西,仅供参考哦!

#include <reg52.h>
#include "fun.h"
#include "lcd12864.h"
#include "delay.h"
#define uchar unsigned char
sbit keydown=P0^0;
sbit keyenter=P0^1;
sbit keyup=P0^2;
uchar func_index=0;
void (*current_operation_index)();
typedef struct
   {
         uchar current;
         uchar up;//向上翻索引号
         uchar down;//向下翻索引号
         uchar enter;//确认索引号
         void (*current_operation)();
         } key_table;
key_table code table[30]=
{
        {0,3,1,4,(*fun1)},//第一层,显示【清华大学】、北京大学、重庆三峡学院、返回
         {1,0,2,8,(*fun2)},//第一层,显示清华大学、【北京大学】、重庆三峡学院、返回
         {2,1,3,12,(*fun3)},//第一层,显示清华大学、北京大学、【重庆三峡学院】、返回                     
         {3,2,0,25,(*fun4)},//第一层,显示清华大学、北京大学、重庆三峡学院、【返回】
         {4,7,5,16,(*fun5)},//第二层,清华大学层下显示【地点】、创建时间、简介、返回                                                   
         {5,4,6,17,(*fun6)},//第二层,清华大学层下显示地点、【创建时间】、简介、返回      
         {6,5,7,18,(*fun7)}, //第二层,清华大学层下显示地点、创建时间、【简介】、返回                                                                             
         {7,6,4,0,(*fun8)},//第二层,清华大学层下显示地点、创建时间、简介、【返回】      
         {8,11,9,19,(*fun9)},//第二层,北京大学层下显示【历史】、政治、简介、返回                                                
         {9,8,10,20,(*fun10)},//第二层,北京大学层下显示历史、【政治】、简介、返回  
         {10,9,11,21,(*fun11)}, //第二层,北京大学层下显示历史、政治、【简介】、返回                                                                                
         {11,10,8,1,(*fun12)},//第二层,北京大学层下显示历史、政治、简介、【返回】         
         {12,15,13,22,(*fun13)},//第二层,重庆三峡学院层下显示【简介】、最佳院系、最佳实验室、返回                                                        
         {13,12,14,23,(*fun14)}, //第二层,重庆三峡学院层下显示简介、【最佳院系】、最佳实验室、返回                                                               
         {14,13,15,24,(*fun15)}, //第二层,重庆三峡学院层下显示简介、最佳院系、【最佳实验室】、返回                                                               
         {15,14,12,2,(*fun16)}, //第二层,重庆三峡学院层下显示简介、最佳院系、最佳实验室、【返回】   
         {16,16,16,4,(*fun17)}, //第三层,清华大学地点层                                                                    
         {17,17,17,5,(*fun18)}, //第三层,清华大学创时间层                                                      
         {18,18,18,6,(*fun19)}, //第三层,清华大学简介层
         {19,19,19,8,(*fun20)}, //第三层,北京大学历史层                                                                    
         {20,20,20,9,(*fun21)}, //第三层,北京大学政治层                                                           
         {21,21,21,10,(*fun22)}, //第三层,北京大学简介层
         {22,22,22,12,(*fun23)}, //第三层,重庆三峡学院简介层                                                                  
         {23,23,23,13,(*fun24)}, //第三层,重庆三峡学院最佳院系层                                                        
         {24,24,24,14,(*fun25)}, //第三层,重庆三峡学院最佳实验室层        
         {25,25,25,0,(*fun26)}, //第0层      

};
void main()
{  
          init_lcd(); //初始化LCD模块  
   while(1)
   {     
         /*******************find index****************************/
                            if((keyup==0)||(keydown==0)||(keyenter==0))
                            {
                                     delay(10);//消抖
                                     if(keyup==0)
                                     {
                                     func_index=table[func_index].up;    //向上翻
                                     while(!keyup);//松手检测
                                     }
                                     if(keydown==0)
                                     {
                                     func_index=table[func_index].down;    //向下翻
                                     while(!keydown);
                                     }
                                     if(keyenter==0)
                                     {
                                     func_index=table[func_index].enter;    //确认
                                     while(!keyenter);
                                     }
                              init_lcd();
                           }                                    
                            current_operation_index=table[func_index].current_operation;
                            (*current_operation_index)();//执行当前操作函数
                   }
}
完整程序包如下


作者: admin    时间: 2015-6-14 10:33
谢谢分享完整程序包好像没有上传上来哦
作者: 景云之应    时间: 2015-6-16 10:58
我也想做,先学习了
作者: hefeng898961    时间: 2016-3-1 08:39
楼主辛苦了 ,感谢分享!
作者: luoluoluo136    时间: 2016-3-22 10:50
东西呢???
作者: 念如    时间: 2016-5-14 08:09
怎么没看到完整程序呢
作者: lizhun1    时间: 2016-5-26 12:52
楼主,求完整程序
作者: lyxxzrb    时间: 2016-5-27 17:44
感谢费心分享,有用!
作者: 我诺你一世不弃    时间: 2016-5-30 13:39
感谢楼主分享
作者: lllllly    时间: 2016-7-26 13:57
楼主,程序包呢?
作者: 曹世鹏    时间: 2016-9-21 15:12
没有附件可供下载。
作者: liwenjiefa98    时间: 2016-11-12 21:11
用C语言写的多级菜单源程序
作者: chukuanglxs    时间: 2017-1-12 09:15
谢谢,看看资料源码
作者: luohui_88    时间: 2017-1-22 11:45
怎么没有完整源码呢?
作者: zgmzgm    时间: 2017-3-1 12:04
楼主,完整程序包呢?
作者: zgmzgm    时间: 2017-3-1 12:05
楼主,求完整程序
作者: YQS    时间: 2017-3-1 16:07

感谢楼主分享
作者: YQS    时间: 2017-3-1 16:28
谢谢楼主分享经验,怎么没有完整源码呢?
作者: qwqwqwq    时间: 2017-5-21 15:07
厉害,学习了
作者: lujiantu0926    时间: 2017-7-20 11:31
怎么看不到!
作者: fengy_2006    时间: 2017-8-15 03:37
下来看看不错,不错
作者: zcl711109    时间: 2017-8-15 20:57
你好我想看
作者: 一束光的旅程    时间: 2017-9-30 08:55
学习学习,谢谢楼主
作者: shaodongsxj    时间: 2017-11-7 14:21
好东西值得收藏
作者: liu100m    时间: 2017-12-2 16:17
  {0,3,1,4,(*fun1)  ,x,y,z是未知数,先不确定,他们对应的是三个键按下要指示的索引值,如果四个键,就有四个未知数。x,y,z是未知数是各键按的次数吗?
作者: binyv    时间: 2017-12-22 22:06
好像看懂了一点思路
作者: 且听风涛    时间: 2018-3-24 16:46
谢谢!!!!!!
作者: 且听风涛    时间: 2018-3-24 16:49
66666666666666
作者: yigehaorens    时间: 2018-4-14 19:50
路过学习。。。
作者: lvdianguang    时间: 2019-1-19 22:37
谢谢分享
作者: 王秋冬    时间: 2019-1-21 10:14
谢谢分享
作者: zhut290948199    时间: 2019-2-7 09:27
谢谢分享完整程序包好像没有上传上来哦
作者: yoxi    时间: 2019-2-11 13:13
己经很好了,LCD那些真不用别人传了
作者: 站着说话不腰疼    时间: 2019-2-11 16:19
这里有很好的案例,你们却还在这儿纠结http://www.51hei.com/bbs/dpj-150435-1.html
作者: chenwg    时间: 2019-5-31 20:57
谢谢分享
作者: chenwg    时间: 2019-5-31 20:58
辛苦了 ,感谢分享!
作者: unknown379    时间: 2019-6-1 10:25
这个非常有启发。正在考虑多级菜单应该怎么组织比较清爽呢。
作者: pwj010    时间: 2019-6-1 13:52
用数组实现的话会不会太大了啊。。
作者: yf158288464    时间: 2019-6-6 07:51
学习下啦
作者: hilam    时间: 2019-8-7 15:11
这个帖子没了,谁帮忙上传一下,谢谢!
34楼说的这里有很好的案例,你们却还在这儿纠结http://www.51hei.com/bbs/dpj-150435-1.html
作者: shuiquan3    时间: 2019-8-17 18:17
下载,学习
作者: shuiquan3    时间: 2019-8-17 18:18
谢谢分享完整程序
作者: chulailiuda    时间: 2019-10-2 17:52
楼主辛苦了 ,感谢分享!
作者: ygflsa    时间: 2019-11-13 19:02
当前索引号怎么调用真是搞不懂.望大神指点.谢了!

作者: ygflsa    时间: 2019-11-26 16:21
终于搞懂了.
作者: nicejack    时间: 2020-1-28 16:17
有完整代码
作者: xinbibo    时间: 2020-2-2 15:24
特别期待啊
作者: univers    时间: 2020-2-3 20:59
看不懂
作者: zhouhai521    时间: 2020-10-24 10:43
谢谢楼主分享经验
作者: 0711zhao    时间: 2020-11-17 14:12
没有源码啊
作者: timeabcd    时间: 2020-11-23 09:37
太复杂,搞懂需要点时间了!
作者: jovew    时间: 2020-11-23 11:29
程序包没有上传,请上传上来啊!!!
作者: ttianmei    时间: 2021-6-14 18:26
这个貌似不好实现参数修改啊,菜单不能只做演示吧,
作者: ttianmei    时间: 2021-6-15 16:53
稍作调整也是可以进行修改参数的,进入最后一级菜单后按up或down键让页面跳转本页面,然后通过索引值去修改指定的参数值,刷新显示就可以




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1