Fork me on GitHub

【单片机程序设计】简易菜单管理器

前文

最近在搞一个小项目,以前写菜单是用switch case 结构,每一个菜单占用一个case结构,小菜单程序倒还好,若是菜单动辄几十上百就会显得代码量过大,不简洁,而且代码编写起来也相当困难。菜单是树形结构,很适合列表的使用,但是若用指针,如果单片机内存比较丰富那还行,若比较垃圾的单片机需要占用不少内存资源,因此将数据全修改为结构体位定义,根据菜单的实际大小可以定义不同位数,达到节省空间的作用。

代码实现

.c文件

/* Includes ------------------------------------------------------------------*/
#include "tabcontrol.h"

void TabFun0(void);
void TabFun1(void);
void TabFun2(void);
void TabFun3(void);
void TabFun4(void);
void TabFun5(void);
void TabFun6(void);
void TabFun7(void);
void TabFun8(void);
void TabFun9(void);
void TabFun10(void);
void TabFun11(void);

Tab_Struct Tab[12]=
{
  {0,0,1,3,0,TabFun0},
  {1,0,2,6,0,TabFun1},
  {2,1,3,9,0,TabFun2},
  {3,5,4,3,1,TabFun3},
  {4,3,5,4,1,TabFun4},
  {5,4,3,5,1,TabFun5},
  {6,8,7,6,2,TabFun6},
  {7,6,8,7,2,TabFun7},
  {8,7,6,8,2,TabFun8},
  {9,11,10,9,3,TabFun9},
  {10,9,11,10,3,TabFun10},
  {11,10,9,11,3,TabFun11}
};

/**
  * @brief  菜单控制函数
  * @param  None
  * @retval None
  * @note   None
  */
void TabControlRun(uint8_t op)
{
  static uint8_t TabIndex = 0;
  switch(op)
  {
    case 0x01:
      TabIndex = Tab[TabIndex].Last;
    break;
    
    case 0x02:
      TabIndex = Tab[TabIndex].Nex;
    break;
    
    case 0x03:
      TabIndex = Tab[TabIndex].Sub;
    break;

    case 0x04:
      TabIndex = Tab[TabIndex].Parent;
    break;
    
    default:break;
  }
  Tab[TabIndex].Function();
}

/**
  * @brief  菜单函数
  * @param  None
  * @retval None
  * @note   None
  */
void TabFun1(void)
{

}

.h文件

typedef struct
{
  uint8_t Nom:4;/*非必须*/
  uint8_t Last:4;
  uint8_t Nex:4;
  uint8_t Sub:4;
  uint8_t Parent:4;
  void (* Function)(/**/);
}Tab_Struct;

Excel 代码生成技巧

我们可以通过Excel自带的连接字符串函数(="字符串"&A0)来自动生成的我们想要的函数。

总结

使用该方法能够一定程度节省空间,第一块内存的申请其实并非是必要的,我们可以通过本层下一页菜单和上一页菜单的指向性就可以判断本菜单的编号了。如本菜单指向下一个菜单是3,指向上一个菜单是4,那么本菜单一定是5。因为下一个菜单或者上一个菜单至少有一个是满足序号相邻的关系。另外我们可以通过Excel 连接字符串的公式的方法来自动生成的我们的菜单代码。
这个小技巧是不是非常方便呢,大家有什么建议或者改进欢迎提出哦。

posted @ 2021-03-06 15:37  赤诚Xie  阅读(25)  评论(0编辑  收藏  举报