C语言----基于旋转编码器按键的菜单结构

参考:
在不使用的情况下,做显示界面,菜单结构将会是很重要的东西 。因为如果显示逻辑复杂,当遇上需要修改的界面的时候,复杂、混乱的显示逻辑(没错,就是那种很多语句的结构),将会使人抓狂 。在参考了“傻孩子菜单框架”之后自己整理了一个菜单框架,主要应用在如:EC11旋转编码器上 。这东西是什么,自己淘宝就知道了了 。。。。
编码器提供3种不同的逻辑:左旋转、右旋转、确定 。
这点跟我参考的菜单框架有点不同的,他的是4个按键逻辑 。所以相应的要对菜单结构体进行改动 。
显示逻辑:
(1)当检测到对应按键码时,进入菜单结构体中的按键处理函数,函数根据按键码的不同,要么移动菜单游标切换深度 。要么加、减标志位 。
(2)标志位为一个16bit数组如([2];),具有2个元素 。元素0为当前的标志位状态,程序主要运用的是元素0 。元素1用来保存上一次标志位的状态 。如按键处理函数改变了“[0]”的值,只要将它与“[1]”对比,如果不同则代表这个标志位被程序改变了,将会触发此标志位管理的显示功能 。这一过程类似于单片机的中断 。检测到标志位改变则触发相应的中断事件 。

C语言----基于旋转编码器按键的菜单结构

文章插图
【C语言----基于旋转编码器按键的菜单结构】(3) 界面深度处理:在最高深度时,按下“ENTER”就会进入下一深度,最低深度则会进入上一深度 。那么中间的深度呢?我进行了一个处理,就是在中间的深度,如果当前的标志位达到最大值,则会跳转到上一深度 。如果不是,则跳转下一深度 。在VS上运行下面的代码,跳转到“布类、速度、返回”的位置就很明了 。当显示“返回”时,“”这个标志位达到最大值“2”,此时按下“”会跳转到第一深度,如果是“布类”、“速度”,则会跳转到对应的下一深度 。
所以,这个菜单结构采用的是“消息->消息处理”的机制,按键可以改变标志位数值以及移动菜单游标到不同的结构体成员 。实现同深度以及不同深度的结构体成员之间的跳转 。
下面代码在2015下编译运行通过,代码是一个简单的洗衣机菜单的例子 。结构如下图:
C语言----基于旋转编码器按键的菜单结构

文章插图
画面上有2个位置会显示内容,分别是位置1跟位置2 。这两个位置显示的内容会根据我们的按键操作进行切换,比方位置一“模式”可以切换成显示“布类”,也可以切换成显示“牛仔” 。具体可以运行以下代码:
#include #include#include/************* LCD显示框架相关定义 **************/#define Null 0#define u8unsigned char#define u16unsigned short#define u32unsigned int//比较标志位#define CompareF(Flag)(*Flag == *(Flag+1)) //同化标志位#define ClearF(Flag)(*(Flag+1) = *Flag)#define LEFT1#define RIGHT3#define ENTER2voidMFunc_MD(u8 key);voidMFunc_TB(u8 key);//菜单标志位结构体struct MFlag{u16 m1_Main[2];u16 m2_Mode[2];u16 m2_Water[2];u16 m3_type[2];u16 m3_speed[2];};//菜单结构体struct MenuItem{ u16MN;//当前菜单标志位最大值u16*MF;//菜单标志位void (*Func)(u8 key);//菜单功能函数struct MenuItem*Next;struct MenuItem*Prev;};//声明菜单结构体变量struct MenuItemm1_Main[1];struct MenuItemm2_Option[2];struct MenuItemm3_Mode[2];struct MenuItem*pMenu;//声明标志位结构体变量struct MFlagMenuF ={{ 0,0 },{ 0,0 },{ 0,0 },{ 0,0 },{ 0,0 },};/**************** 菜单结构体变量的定义 *****************///一级深度菜单结构体struct MenuItemm1_Main[1] ={{2, &MenuF.m1_Main[0] ,MFunc_TB,m2_Option, Null },};//二级深度菜单结构体struct MenuItemm2_Option[2] ={{3, &MenuF.m2_Mode[0] , MFunc_MD, &m3_Mode[0], m1_Main },{5, &MenuF.m2_Water[0], MFunc_TB, Null,m1_Main },};//三级深度菜单结构体struct MenuItemm3_Mode[2] ={{5, &MenuF.m3_type[0],MFunc_TB, Null, &m2_Option[0] },{5, &MenuF.m3_speed[0], MFunc_TB, Null, &m2_Option[0] },};/****************** 菜单跳转函数的定义 *******************///底部以及顶部菜单结构体成员的按键处理函数//struct MenuItem*Next;其中一个为空,使用此菜单函数//struct MenuItem*Prev;voidMFunc_TB(u8 key){switch (key){case LEFT:if(*pMenu->MF>0)*pMenu->MF -= 1;//当前标志位-1break;case RIGHT: if (*pMenu->MF