• 单片机液晶多级菜单的程序写法


    传统单片机液晶菜单写法

    一般用单片机写液晶菜单都是通过大量标志位配合if else语句,或是switch case语句来完成当前液晶显示位置记录以及跳转的情况,这种写法往往会出现标志位多,代码冗余度高,程序中套用大量的条件判断语句,使得程序难以维护和升级。本文介绍了一种通过函数指针的方法来实现多级菜单的写法,程序通俗易懂,且易于维护。

    函数指针法写液晶多级菜单

    extern void (*KeyFuncPtr)(void); 
    typedef struct
    {
    	  unsigned int KeyIndex;	//当前所在的位置,类似于索引号,目的是为了告诉用户当前位置下需要执行的函数  
    	  unsigned int KeyUp;  //当前按下了向上按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  unsigned int KeyDown;  //当前按下了向下按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  unsigned int KeyLeft;  //当前按下了向左按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  unsigned int KeyRight;  //当前按下了向右按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  unsigned int KeyEnter; //当前按下了确定按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  unsigned int KeyEsc; 	//当前按下了取消按键,按下后需要跳转到下一幅菜单的KeyIndex的值
    	  void (*CurrentOperate)(void);  //当前位置下需要执行的函数
    }MeunTabStruct;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    首先定义了结构体用来记录菜单的位置,以及按键该按键后要跳转的函数位置,KeyIndex变量主要做唯一索引用,用来给每一幅液晶画面一个唯一标识,上下左右确定取消按键目的是为了记录在当前KeyIndex下,按下这些按键会跳转到的下一个KeyIndex的索引值是多少,CurrentOperate函数指针是记录当前KeyIndex索引下需要执行的函数。

    大致代码如下:
    Menu.h

    #ifndef _MENU_H_ 
    #define _MENU_H_ 
    extern void (*KeyFuncPtr)(void); 
    typedef struct
    {
          unsigned int KeyState;	        //当前状态索引号
    	  unsigned int KeyEnter;            //按下"确认"键时转向的状态索引号
    	  unsigned int KeyEsc;              //按下"取消"键时转向的状态索引号 
          unsigned int KeyUp;               //按下"向上"键时转向的状态索引号
    	  unsigned int KeyDown;             //按下"向下"键时转向的状态索引号
    	  unsigned int KeyLeft;             //按下向左键时转向的状态索引号
    	  unsigned int KeyRight;            //按下向右键时转向的状态索引号
    	  void (*CurrentOperate)(void);   //当前状态应该执行的功能操作 
    }MeunTabStruct;
    void DispFirstSectionMenu(void);
    void DispSecondSection1Menu(void);
    void DispSecondSection2Menu(void);
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Menu.c

    #include "Menu.h"
    onst MeunTabStruct   KeyTab[]=
    {
    //	  	|-----------> Index
    //		|   Enter 
    //	  	|	  |    Esc
    //      |	  |     |    up
    //      |     |		|    |   down
    //      |     |  	|    |    |   left
    //      |     |  	|    |    |    |   right
    //      |     |  	|    |    |    |	|		      |--->功能函数
    //      |     |  	|    |    |    |    |             |
    /**************************一级主菜单***************************************/ 
           {0,    5, 	0, 4,   1,   0,   0,      (*DispFirstSectionMenu)}, //一级菜单功能1
           {1,    6,	0,   0,   2,   1,   1,    (*DispFirstSectionMenu)}, //一级菜单功能2
           {2,    7,    0,   1,   3,   2,   2,    (*DispFirstSectionMenu)}, //一级菜单功能3
           {3,    8,    0,   2,   4,   3,   3,    (*DispFirstSectionMenu)}, //一级菜单功能4
    	   {4,    9,    0,   3,   0,   4,   4,    (*DispFirstSectionMenu)}, //一级菜单功能5                 
    /*************************功能1二级菜单*************************/ 
           {5,    5,    0,   5,   5,   5,   5,    (*DispSecondSection1Menu)},//功能1二级菜单
    /*************************功能2二级菜单*******************************/
           {6,    6,    1,   6,   6,   6,   6,    (*DispSecondSection2Menu)}, //功能2二级菜单
    
    void DispFirstSectionMenu(void)
    {
    //液晶屏幕显示处理
    }
    void DispSecondSection1Menu(void)
    {//液晶屏幕显示处理
    }
    void DispSecondSection2Menu(void)
    {//液晶屏幕显示处理
    }
    void MenuProc(unsigned int KeyValue)
    {
    	case _KEY_NO:
    	 		break;	
    	 case _ESC_KEY:
    	  	   LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    		   KeyFuncIndex = KeyTab[KeyFuncIndex].KeyEsc;
    	   	   KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下取消键后,	                                              
    	       (*KeyFuncPtr)();  
    	 break;            
    	 case _ENT_KEY:
    	  	   LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    		   KeyFuncIndex = KeyTab[KeyFuncIndex].KeyEnter;
    	   	   KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下确认键后,	                                              
    		  (*KeyFuncPtr)();
    	 break;            
    	 case _UP_KEY:
    	  	   BK = 1;
    		   BKLightCount = 0;
    	  	   LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    	 	   KeyFuncIndex = KeyTab[KeyFuncIndex].KeyUp;
    	 	 	   KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下向上键后,	                                              
    	             	   (*KeyFuncPtr)();
    	 break;             
    	 case _LEFT_KEY:
    	 	   LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    		   KeyFuncIndex = KeyTab[KeyFuncIndex].KeyLeft;
    	   	   KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下确认键后,	                                              
    	       (*KeyFuncPtr)();
    	 break;
    	 case _DOWN_KEY:
    	 	   LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    	 	   KeyFuncIndex = KeyTab[KeyFuncIndex].KeyDown;
    	       KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下向下键后,	                                              
    	       (*KeyFuncPtr)(); 
    	 break;
    	 case _RIGHT_KEY:
    	       LastKeyFuncIndex = KeyFuncIndex; //存取上一次函数的索引
    		   KeyFuncIndex =  KeyTab[KeyFuncIndex].KeyRight;
    	   	   KeyFuncPtr = KeyTab[KeyFuncIndex].CurrentOperate;//按下确认键后,	                                              
    	       (*KeyFuncPtr)();
    	 break;      
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    main.c

    int main()
    {
    	while(1)
    	{
    		MenuProc(GetKeyValue());//这里的GetKeyValue是获取按键值的意思,可以参考我的个人博客中关于按键函数的编写
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    加密货币为什么有价值?
    Python:实现reverse letters反向字母算法(附完整源码)
    【Spring Boot】Spring Boot集成RabbitMQ
    java计算机毕业设计口腔医院患者服务系统源码+系统+mysql数据库+lw文档+部署
    解决导入maven工程时cannot resolve依赖问题
    【数据分享】1960-2020年全国范围的PM2.5数据(tif/csv/nc)
    Bert+对抗训练+对抗性样本防御的文本分类实战
    Vue+less+cssVal实现在线换肤
    线程的属性
    ♥Redis教程 - Redis知识体系详解♥
  • 原文地址:https://blog.csdn.net/techenliu/article/details/132700870