lzh电子论坛

欢迎来到lzh电子论坛:
如果您对电子技术感兴趣就加入我们吧!在这里互相交流互相学习!主要讨论的方向有:单片机,ARM,PCB板设计,FPGA,汇编,C/C++等方面。
-----lzh电子论坛
lzhbbs.top-me.com
lzh电子论坛

电子的道路是孤独的,要懂得左手温暖右手,要懂得把debug当作快乐去欣赏,去享受,那样你才会成功...

欢迎访问lzh电子论坛。可通过【谷歌,SOSO,搜狗】搜索“lzh电子论坛”直接进入论坛。点击了解论坛详细制度


    12864多级菜单设计

    分享
    avatar
    和谐号
    初级会员
    初级会员

    帖子数 : 2
    威望 : 1
    注册日期 : 14-01-21

    12864多级菜单设计

    帖子 由 和谐号 于 2014-01-21, 4:08 pm

    看到网上有个视频,用的是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)();//执行当前操作函数
                       }
    }
    完整程序包如下
    附件
    12864多级菜单例子.zip
    您无权下载这里的附件。
    (56 Kb) 下载2次

      目前的日期/时间是2018-04-25, 6:47 am