这是我之前申请到NUCLEO-L476RG开发板时做的一个小项目。用红外遥控可以使液晶显示多个画面,字库自己做的,可以用红外修改参数的数值并保存,有些比较重要的画面还有要求输入密码,只有密码正确才能进入,废话不多说了,看图吧。 添加一些代码,我觉得注释还是蛮多的,详情见附件源码。 //------------------------------------- // // 具体菜单选项定义,定义一个结构数组 // 存储在编码区,节省内存RAM // //------------------------------------- struct Option sOption[OPTIONMETE] = { {0,4,13, "基本设置 ",4}, //0 {0,18,13,"反馈设置 ",4}, //1 {0,46,13,"高级设置 ",4}, //2 {0,73,13,"故障诊断 ",4}, //3 {1,OPTIONMETE-1,0," ",0}, //4 {1,OPTIONMETE-1,0," 请输入基本密码",0}, //5 {1,OPTIONMETE-1,0," ",0}, //6 {1,OPTIONMETE-1,0," ",0}, //7 {2,OPTIONMETE-1,0,"关位确认 ",4}, //8 {2,OPTIONMETE-1,0,"开位确认 ",4}, //9 {2,OPTIONMETE-1,0,"调节死区 ",4}, //10 {2,OPTIONMETE-1,0,"丢信动作 ",4}, //11 {2,OPTIONMETE-1,0,"关过矩值 ",4}, //12 {2,OPTIONMETE-1,0,"开过矩值 ",4}, //13 {2,OPTIONMETE-1,0,"显示方向 ",4}, //14 {2,OPTIONMETE-1,0,"现场控制 ",4}, //15 {2,OPTIONMETE-1,0,"更改基本密码 ",6}, //16 {2,OPTIONMETE-1,0,"恢复出厂值 ",5}, //17 {3,OPTIONMETE-1,1," ",0}, //18 {3,OPTIONMETE-1,1," 请输入反馈密码",0}, //19 {3,OPTIONMETE-1,1," ",0}, //20 {3,OPTIONMETE-1,1," ",0}, //21 {4,OPTIONMETE-1,1,"低端微调 ",4}, //22 {4,OPTIONMETE-1,1,"高端微调 ",4}, //23 {4,27,1,"触点输出 ",4}, //24 {4,27,1,"扩展触点 ",4}, //25 {4,OPTIONMETE-1,1,"更改反馈密码 ",6}, //26 {5,OPTIONMETE-1,24,"关到位 ",3}, //27 {5,OPTIONMETE-1,24,"开到位 ",3}, //28 {5,OPTIONMETE-1,24,"关过矩 ",3}, //29 {5,OPTIONMETE-1,24,"开过矩 ",3}, //30 {5,OPTIONMETE-1,24,"过 矩 ",3}, //31 {5,OPTIONMETE-1,24,"正在关 ",3}, //32 {5,OPTIONMETE-1,24,"正在开 ",3}, //33 {5,OPTIONMETE-1,24,"正在运行 ",4}, //34 {5,39,24,"中间位置 ",4}, //35 {5,OPTIONMETE-1,24,"远方位置 ",4}, //36 {5,OPTIONMETE-1,24,"现场位置 ",4}, //37 {6,OPTIONMETE-1,35," 运行到达位置 ",0}, //38 {6,OPTIONMETE-1,35," ",0}, //39 {6,OPTIONMETE-1,35," ",0}, //40 {6,OPTIONMETE-1,35," ",0}, //41 {7,OPTIONMETE-1,24," 故障报警 ",0}, //42 {7,OPTIONMETE-1,24,"过矩报警 ",4}, //43 {7,OPTIONMETE-1,24,"远方报警 ",4}, //44 {7,OPTIONMETE-1,24," ",0}, //45 {8,OPTIONMETE-1,2," ",0}, //46 {8,OPTIONMETE-1,2," 请输入高级密码",0}, //47 {8,OPTIONMETE-1,2," ",0}, //48 {8,OPTIONMETE-1,2," ",0}, //49 {9,OPTIONMETE-1,2,"ESD 设置 ",4}, //50 {9,OPTIONMETE-1,2,"关闭方式 ",4}, //51 {9,OPTIONMETE-1,2,"关闭方向 ",4}, //52 {9,OPTIONMETE-1,2,"正反作用 ",4}, //53 {9,OPTIONMETE-1,2,"转矩显示 ",4}, //54 {9,OPTIONMETE-1,2,"反馈低端 ",4}, //55 {9,OPTIONMETE-1,2,"两线控制 ",4}, //56 {9,OPTIONMETE-1,2,"标定低信 ",4}, //57 {9,OPTIONMETE-1,2,"标定高信 ",4}, //58 {9,OPTIONMETE-1,2,"刹车制动 ",4}, //59 {9,OPTIONMETE-1,2,"停动时间 ",4}, //60 {9,OPTIONMETE-1,2,"间断运行 ",4}, //61 {9,OPTIONMETE-1,2,"更改高级密码 ",6}, //62 {9,OPTIONMETE-1,2,"基本密码查询 ",6}, //63 {9,OPTIONMETE-1,2,"反馈密码查询 ",6}, //64 {9,66,2,"保存出厂值 ",5}, //65 {10,OPTIONMETE-1,65," ",0}, //66 {10,OPTIONMETE-1,65,"请输入出厂密码 ",0}, //67 {10,OPTIONMETE-1,65," ",0}, //68 {10,OPTIONMETE-1,65," ",0}, //69 {11,OPTIONMETE-1,65,"保存出厂设置 ",6}, //70 {11,OPTIONMETE-1,65,"电源选项 ",4}, //71 {11,OPTIONMETE-1,65,"远方保持 ",4}, //72 {12,OPTIONMETE-1,3,"方式钮位置 ",5}, //73 {12,OPTIONMETE-1,3,"操作钮位置 ",5}, //74 {12,OPTIONMETE-1,3,"远方打开信号 ",6}, //75 {12,OPTIONMETE-1,3,"远方关闭信号 ",6}, //76 {12,OPTIONMETE-1,3,"远方保持信号 ",6}, //77 {12,OPTIONMETE-1,3,"远方自动信号 ",6}, //78 {12,OPTIONMETE-1,3,"远方ESD 信号 ",6}, //79 {12,OPTIONMETE-1,3,"控制电流 ",4}, //80 {13,OPTIONMETE-1,61,"开向始位 ",4}, //81 {13,OPTIONMETE-1,61,"开向终位 ",4}, //82 {13,OPTIONMETE-1,61,"开向动程 ",4}, //83 {13,OPTIONMETE-1,61,"开向停时 ",4}, //84 {13,OPTIONMETE-1,61,"关向始位 ",4}, //85 {13,OPTIONMETE-1,61,"关向终位 ",4}, //86 {13,OPTIONMETE-1,61,"关向动程 ",4}, //87 {13,OPTIONMETE-1,61,"关向停时 ",4}, //88 {14,OPTIONMETE-1,50,"ESD 动位 ",4}, //89 {14,OPTIONMETE-1,50,"ESD 有效电平 ",6}, //90 {14,OPTIONMETE-1,50,"ESD 超越过热 ",6}, //91 {14,OPTIONMETE-1,50,"ESD 超越停止 ",6}, //92 {14,OPTIONMETE-1,50,"ESD 超越间断 ",6}, //93 {14,OPTIONMETE-1,50,"ESD 超越过矩 ",6}, //94 {15,OPTIONMETE-1,56," 两线设置 ",0}, //95 {15,OPTIONMETE-1,56,"有信开,无信关 ",7}, //96 {15,OPTIONMETE-1,56,"有信关,无信开 ",7}, //97 {MENULEVEL-1,OPTIONMETE-1,0,"",0} //98 }; //---------------------------------------- // // 菜单上移一项函数 // 函数原形:void MenuUpOneOption (void); // 没有参数,没有返回值 // 调用方式:void MenuUpOneOption (void); // //---------------------------------------- void MenuUpOneOption (void) { if(MenuLevelStart()) //如果当前为表单第一项 { if(Level[sOption[SelectIndex].KeyLevel][2]>=4) //并且表单中选项数目大于等于4个 { FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][1]-3; //第一行显示索引号为倒数第四项 SelectIndex = Level[sOption[SelectIndex].KeyLevel][1]; //选择索引为表单最后一项 SelectLine = 4; //标记选择行为第四行 DIS12864M(); //刷新屏幕显示 } else //如果选项数目并不大于四个 { SelectIndex = Level[sOption[SelectIndex].KeyLevel][1]; //选择索引为当前表单最后一个 SelectLine = Level[sOption[SelectIndex].KeyLevel][2]; //显示行表单数目(最后一个) DIS12864M(); //刷新屏幕显示 } } else //如果当前不是开始索引 { if(SelectLine==1) //并且已经在屏幕最上边一行 { FirstLineDisIndex--; //显示索引上移 SelectIndex--; //选择索引自减 SelectLine = 1; //选择行还是第一行 DIS12864M (); //刷新屏幕 } else //如果不是第一行 { SelectLine--; //选择行自减 SelectIndex--; //选择索引自减 DIS12864M (); //刷新屏幕显示 } } } //---------------------------------------- // // 菜单下移一项函数 // 函数原形:void MenuDownOneOption (void); // 没有参数,没有返回值 // 调用方式:void MenuDownOneOption (void); // //---------------------------------------- void MenuDownOneOption (void) { if(MenuLevelEnd()) //如果当前是表单最后一个索引 { FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0]; //第一行显示索引为表单第一个选项 SelectIndex = Level[sOption[SelectIndex].KeyLevel][0]; //选择索引为表单第一个选项索引 SelectLine = 1; //选择行为第一行 DIS12864M (); //刷新显示 } else //如果不是最后的索引 { if(SelectLine!=4) //如果当前不是屏幕最底行 { SelectIndex++; //选择索引自加 SelectLine++; //选择行下移 // SetALineReverse (SelectLine); //刷新选择行 DIS12864M (); //刷新显示 } else //如果是屏幕最低行 { FirstLineDisIndex++; //第一行显示下移 SelectIndex++; //选择索引自加 DIS12864M(); //刷新显示 } } } //---------------------------------------- // // 菜单退出功能函数 // 函数原形:void MenuCancelOption (void); // 没有参数,没有返回值 // 调用方式:void MenuCancelOption (void); // //---------------------------------------- void MenuCancelOption (void) { if(SelectIndex != OPTIONMETE-1) //如果不是从功能返回 { if(CancelIndex_flag == 1 && sOption[SelectIndex].KeyLevel == 5) { CancelIndex_flag = 0; SelectIndex = 25;} else SelectIndex = sOption[SelectIndex].CancelIndex; //选择索引为选项返回索引 } else //如果是从功能返回 SelectIndex = LastIndex;//索引等于进入前保存索引 if(Level[sOption[SelectIndex].KeyLevel][2]>=4) //如果返回表单选项数目大于4个 { if(SelectIndex > Level[sOption[SelectIndex].KeyLevel][1]-3) //根据返回选项确定显示首项 { FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][1]-3; SelectLine = 4-(Level[sOption[SelectIndex].KeyLevel][1]-SelectIndex); DIS12864M (); //刷新显示 } else //一般显示方式 { FirstLineDisIndex = SelectIndex; //第一行显示索引 SelectLine = 1; //选择第一行 DIS12864M (); //刷新菜单 } } else //如果返回表单选项数目不足4个 { FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0]; //第一行显示索引为表单第一项 SelectLine = SelectIndex - Level[sOption[SelectIndex].KeyLevel][0]+1; //选择行标志为当前选择索引对应行 DIS12864M (); //刷新菜单 } } |
|
谢谢分享!!! |
很经典的菜单树结构 |