使用STM32和OLED实现多级菜单功能

STM32_OLED多级菜单

程序实现

多级菜单显示实则是多个界面的跳转,这个版本更加适合初学者。我使用了两个按键,一个用来选择下一项,另一个用来确定选项。所以我们暂时叫他next键和enter键。先定义一个结构体,结构体里面有四个变量,分别代表当前索引号,next键,enter键和当前执行函数。
结构体如下:

typedef struct
{
    u8 current;//当前状态索引号
    u8 next; //向下一个
    u8 enter; //确定
    void (*current_operation)(void); //当前状态应该执行的操作
} Menu_table;

这里是核心思想,就是按键按下决定当前的索引号,继续定义一个数组:

Menu_table  table[17]=
{
    {0,0,1,(*show0)},//一级界面
	
    {1,2, 5,(*show1)},//二级界面    第一行
    {2,3, 9,(*show2)},//二级界面    第二行
    {3,4,13,(*show3)},//二级界面   第三行
    {4,1, 0,(*show4)},//三级界面    Back
	
    {5, 6, 4, (*show5)},  //三级菜单 Back
    {6, 7, 5, (*show6)}, //三级菜单 
    {7, 8, 5, (*show7)}, //三级菜单 
    {8, 5, 5, (*show8)}, //三级菜单 

    {9 , 10, 4, (*show9)},    //三级菜单  Back
    {10, 11, 9, (*show10)}, //三级菜单
    {11, 12, 9, (*show11)}, //三级菜单 
    {12, 9 , 9, (*show12)},  //三级菜单 

    {13, 14, 4, (*show13)},  //三级菜单  Back
    {14, 15, 13, (*show14)}, //三级菜单
    {15, 16, 13, (*show15)}, //三级菜单 
    {16, 13, 13, (*show16)}, 
};

这里解释一下这个数组中 {0,0,1,(show0)},一级界面 ,由于我们在前面先定义了Menu_table结构体,结构体成员变量分别为当前索引号,next,enter和void (current_operation)(void),第一的0代表当前的索引号,第二个0代表next这个按键按下返回的索引号,第三个1代表enter按键按下返回的索引号。第三个(*show0)代表索引号为0要执行的函数。一一对应。再结合按键按下的画面就比较有逻辑了。


在三级菜单最后,我采用了直接跳转回上一级,避免溢出现象。

本质上所有的页面均为一幅图像,例如下

void show0(void)//第一页
{
    OLED_ShowString(25,0,"Menu Test",16);
	OLED_ShowString(5,2,"Test 1",16);
	OLED_ShowString(5,4,"Test 2",16);
	OLED_ShowString(5,6,"Test 3",16);
}

void show1(void)//第二页
{
	OLED_ShowString(5,0,"Test 1   <",16);
	OLED_ShowString(5,2,"Test 2",16);
	OLED_ShowString(5,4,"Test 3",16);
	OLED_ShowString(5,6,"Back ",16);
}

再就是按键方面

void  Menu_key_set(void)
{
  key1 = KEY1_Get();
  key2 = KEY2_Get();
  if(key1 == 1)
  {   
    func_index=table[func_index].next;//按键next按下后的索引号
    OLED_Clear();
  }
  if(key2 == 1)
  {
    func_index=table[func_index].enter;
    OLED_Clear();
  }

  current_operation_index=table[func_index].current_operation;//执行当前索引号所对应的功能函数。
  (*current_operation_index)();//执行当前操作函数
}

uint8_t KEY1_Get(void)
{
	if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == 0)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == 0);
		Delay_ms(20);
		Key1=1;
	}
	else
		Key1=0;

	return Key1;
}
物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32和OLED实现多级菜单功能

发表评论