结构体多级菜单,从网上下来的,移植后觉得还不错,分享给大家
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #ifndef _Menu_H_
- #define _Menu_H_
- #include"LCD1602.h" //液晶显示器头文件
- #include"KeYsCan.h"
- #include"TimEDisPlaY.H"
- #define LCD1602MaxDisplaYLinE 2 //LCD最大显示行数
- #define UP 0 //上
- #define Down 1 //下
- //#define LeFt 4 //确定
- //#define RigHt 5 //退出
- #define Enter 2
- #define Esc 3
- void NullSubs(void) //空函数
- { }
- struct MenuItem code SysTemSet[5]; //这里不声明一下,MainMenu里不能引用
- struct MenuItem code BaudRatE[7]; //同上
- struct MenuItem code EquipmenT[4]; //同上
- //*------------------------------------------------------------------------------
- //*目录结构体定义
- //*------------------------------------------------------------------------------
- struct MenuItem //结构体名称
- { unsigned char MenuCount; //当前层节点数、每层菜单能显示的条目数
- unsigned char *DisplayString; //指向菜单标题的字符串
- unsigned char (*Subs)(); //指向当前状态应该执行的功能函数
- struct MenuItem *ChildrenMenus;//指向当前菜单的下级菜单
- struct MenuItem *ParentMenus; //指向当前菜单的上级菜单
- } Null;
- struct MenuItem code MainMenu[4] = //结构体主菜单
- {
- {4,"1.SysTem Set ",&Null,SysTemSet,&Null},
- {4,"2.EquipmenT ID ",&Null,EquipmenT,&Null},
- {4,"3.BaudRatE ",&Null,BaudRatE, &Null},
- {4,"4.System Infor ",&Null,&Null, &Null},
- };
- struct MenuItem code SysTemSet[5] = //系统菜单
- {
- {5,"1.DatA Set ",&Null,&Null,MainMenu},
- {5,"2.TimE Set ",&Null,&Null,MainMenu},
- {5,"3.AlarM Set ",&Null,&Null,MainMenu},
- {5,"4.BacKLed Set ",&Null,&Null,MainMenu},
- {5,"5.Password Set ",&Null,&Null, &Null},
- };
- struct MenuItem code BaudRatE[7] = //波特率
- {
- {7,"1.2400 ",&Null,&Null,MainMenu},
- {7,"2.4800 ",&Null,&Null,MainMenu},
- {7,"3.9600 ",&Null,&Null,MainMenu},
- {7,"4.19200 ",&Null,&Null,MainMenu},
- {7,"5.38400 ",&Null,&Null,MainMenu},
- {7,"6.57600 ",&Null,&Null,MainMenu},
- {7,"7.115200 ",&Null,&Null,MainMenu},
- };
- struct MenuItem code EquipmenT[4] = //设备号
- {
- {4,"1.No.01 ",&Null,&Null,MainMenu},
- {4,"2.No.02 ",&Null,&Null,MainMenu},
- {4,"3.NO.03 ",&Null,&Null,MainMenu},
- {4,"4.No.04 ",&Null,&Null,MainMenu},
- };
- struct MenuItem (*MenuPoint) = MainMenu;
- char DisplayStart = 0; //显示菜单的开始位置
- char UserChoose = 0; //用户的选择
- char DisplayPoint = 0; //显示菜单的编号
- char MaxItems = 0; //菜单的数量
- char Option = 0; //保存用户的菜单编号
- //*------------------------------------------------------------------------------
- //*显示函数
- //*------------------------------------------------------------------------------
- void ShowMenu(void)
- {
- unsigned char i = 0;
- MaxItems = MenuPoint[0].MenuCount; //获取当前菜单的条目数
- DisplayPoint = DisplayStart;
- if (MaxItems > LCD1602MaxDisplaYLinE){ //如果大于能显示的菜单数做处理
- for (i = 0;i < LCD1602MaxDisplaYLinE;i++){
- LCD1602wRITESTring(i,1,MenuPoint[DisplayPoint].DisplayString);
- if ((DisplayPoint) == (UserChoose)){
- LCD1602SetWZ(0,0,0x7e); //写小箭头
- }
- else{
- LCD1602SetWZ(i,0,' '); //写空格
- }
- DisplayPoint += 1; //字符串偏移量+1
- if ((DisplayPoint) == (MaxItems)){
- DisplayPoint = 0;
- }
- }
- }
- else{
- for (i = 0;i < LCD1602MaxDisplaYLinE;i++){
- LCD1602wRITESTring(i,1,MenuPoint[DisplayPoint].DisplayString);
- if ((DisplayPoint) == (UserChoose)){
- LCD1602SetWZ(0,0,0x7e); //写小箭头
- }
- else{
- LCD1602SetWZ(i,0,' '); //写空格
- }
- DisplayPoint += 1; //字符串偏移量+1
- if ((DisplayPoint) == (MaxItems)){
- DisplayPoint = 0;
- }
- }
- }
- }
- //*------------------------------------------------------------------------------
- //*菜单执行函数
- //*------------------------------------------------------------------------------
- void ChangeMenu(void)
- { unsigned char GetKeyNum;
- GetKeyNum = KeYsCanFuc();
- if (GetKeyNum != 0xff){ //确定有功能按键被按下的情况下才执行其功能
- ShowMenu(); //显示菜单
- switch (GetKeyNum){
- case UP:
- UserChoose--; //用户菜单的选择
- if (UserChoose < 0){
- UserChoose = MaxItems - 1;
- }
- break;
- case Down:
- UserChoose++;
- if (UserChoose == MaxItems){
- UserChoose = 0;
- }
- break;
- case Enter:
- if ((MenuPoint[UserChoose].Subs) != NullSubs){
- (*MenuPoint[UserChoose].Subs)();
- }
- if (MenuPoint[UserChoose].ChildrenMenus != &Null){
- MenuPoint = MenuPoint[UserChoose].ChildrenMenus; //指向子菜单
- Option = UserChoose;
- UserChoose = 0;
- DisplayStart = 0;
- }
- break;
- case Esc:
- if (MenuPoint[0].ParentMenus != &Null){
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
新建文件夹.rar
(139.23 KB, 下载次数: 383)
|