STM32中实现OLED多级菜单(支持修改参数)

STM32中实现OLED多级菜单

一、完整工程源码下载

地址:https://download.csdn.net/download/qq_44062900/18755302

二、硬件连接

1、OLED12864

OLED_SCK—>PA0 //时钟管脚
OLED_MOSI—>PC13 //数据管脚(主机输出从机输入)
OLED_RES—>PB9 //复位管脚(低电平有效)
OLED_DC—>PB8 //数据/命令(低电平有效)选择管脚
OLED_CS—>PB7 //片选管脚(低电平有效)

2、按键

KEY_UP(上一页)—>PB12
KEY_DOWN(下一页)—>PB14
KEY_LEFT(确认) —>PB13
KEY_RIGHT(返回)—>PB15

3、蜂鸣器

BEEP–>PB4

三、效果展示

1、图片效果

主界面
在这里插入图片描述

菜单选项界面
在这里插入图片描述

设置界面
在这里插入图片描述
在这里插入图片描述

电池信息界面
在这里插入图片描述

2、视频效果

stm32+OLED实现多级菜单

四、核心代码

1、gui.h文件

#ifndef _GUI_H_
#define	_GUI_H_

#include "stm32f10x.h"

#define ON 1
#define OFF 0

typedef struct
{
	u8 Cur_Index;//当前索引项
	u8 previous;//上一页
	u8 next;//下一页
	u8 enter;//确认
	u8 back;//返回
	void (*current_operation)(u8,u8);//	当前索引执行的函数(界面)
}Main_Menu;

//各界面的索引值
enum
{
	_Main_UI=0,
	_Wifi_Option,
	_Bluetooth_Option,
	_Setting_Option,
	_Info_Option,
	_Wifi_Child,
	_Bluetooth_Child,
	_Setting_Child,
	_Info_Child,
	_OLED_Lock,
};

//按键索引值
enum
{
	KEY_PREVIOUS=2,
	KEY_ENTER,
	KEY_NEXT,
	KEY_BACK
};

void Main_UI(u8 page_index,u8 key_val);
void Main_Menu_Func(u8 page_index,u8 key_val);
void Wifi_Child(u8 page_index,u8 key_val);
void Bluetooth_Child(u8 page_index,u8 key_val);
void Setting_Child(u8 page_index,u8 key_val);
void Info_Child(u8 page_index,u8 key_val);
void OLED_Lock(u8 page_index,u8 key_val);
void GUI_Refresh(void);
#endif

2、gui.c文件

#include "gui.h"
#include "oled.h"
#include "oledfont.h"
#include "key.h"
#include "led.h"
#include <stdio.h>
#include "rtc.h"
#include <string.h>
#include "beep.h"
#include "adc.h"
#include "oled.h"
#include "esp8266.h"

static u8 func_index=_Main_UI;//当前页面索引值
static u8 last_index=_Main_UI;//上一个界面索引值
static void (*current_operation_func)(u8,u8);//定义一个函数指针
static u8 BEEP_swi=ON;

//索引表
Main_Menu table[20]=
{
	//Cur_Index,previous,next,enter,back,(*current_operation)(u8,u8)
	//主界面
	{_Main_UI,_Main_UI,_Main_UI,_Wifi_Option,_OLED_Lock,Main_UI},
	//主菜单
	{_Wifi_Option,_Info_Option,_Bluetooth_Option,_Wifi_Child,_Main_UI,Main_Menu_Func},//Wifi
	{_Bluetooth_Option,_Wifi_Option,_Setting_Option,_Bluetooth_Child,_Main_UI,Main_Menu_Func},//蓝牙
	{_Setting_Option,_Bluetooth_Option,_Info_Option,_Setting_Child,_Main_UI,Main_Menu_Func},//设置
	{_Info_Option,_Setting_Option,_Wifi_Option,_Info_Child,_Main_UI,Main_Menu_Func},//关于信息
	
	//子菜单
	{_Wifi_Child,_Wifi_Child,_Wifi_Child,_Wifi_Child,_Wifi_Option,Wifi_Child},//Wifi子菜单
	{_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Option,Bluetooth_Child},//蓝牙子菜单
	{_Setting_Child,_Setting_Child,_Setting_Child,_Setting_Child,_Setting_Option,Setting_Child},//设置子菜单
	{_Info_Child,_Info_Child,_Info_Child,_Info_Child,_Info_Option,Info_Child},//关于信息子菜单
	{_OLED_Lock,_Main_UI,_Main_UI,_Main_UI,_Main_UI,OLED_Lock},//OLED熄屏
};

/*
函数功能:刷新界面
参数:无
返回值:无
*/
void GUI_Refresh(void)
{
	u8 key_val=Get_KEY_Value();
	if(key_val!=0)//只有按键按下才刷屏
	{
		last_index=func_index;//更新上一界面索引值
		switch(key_val)
		{
			case KEY_PREVIOUS: func_index=table[func_index].previous;//更新索引值
					break;
			case KEY_ENTER: func_index=table[func_index].enter;//更新索引值
					break;
			case KEY_NEXT:func_index=table[func_index].next;//更新索引值
					break;
			case KEY_BACK:func_index=table[func_index].back;//更新索引值
					break;
			default:break;
		}
		if(BEEP_swi==ON)
		{
			BEEP=1;
			Delay_Ms(50);
			BEEP=0;
		}
		OLED_Clear(0);//清屏
	}
	current_operation_func=table[func_index].current_operation;
	(*current_operation_func)(func_index,key_val);//执行当前索引对应的函数
		
}


/*
函数功能:显示主界面
参数:u8 page_index,u8 key_val
返回值:无
*/
void Main_UI(u8 page_index,u8 key_val)
{
	char buff[20];
	OLED_Display_Image(0,0,11,7,(char*)Signal_11x7,NO_ALGIN);//显示信号塔
	OLED_Display_Image(14,0,9,9,(char*)Bluetooth_9x9,NO_ALGIN);//显示蓝牙
	snprintf(buff,sizeof(buff),"%02d-%02d-%02d",Current_Time.year%100,Current_Time.month,Current_Time.day);
	OLED_Display_String(0,1,8,8,buff,NORMAL,CEN_ALIGN);//显示日期
	snprintf(buff,sizeof(buff),"%02d:%02d",Current_Time.hour,Current_Time.min);
	OLED_Display_String(0,2,16,32,buff,NORMAL,CEN_ALIGN);//显示时间
	OLED_Display_Image(112,0,16,8,(char*)Bat_16x8,NO_ALGIN);//显示电量
	OLED_Display_Chinese(40,6,16,16,(char *)(Week_Font_16x16+7*32),NO_ALGIN);//星
	OLED_Display_Chinese(56,6,16,16,(char *)(Week_Font_16x16+8*32),NO_ALGIN);//期
	OLED_Display_Chinese(72,6,16,16,(char *)(Week_Font_16x16+(Week_Get()-1)*32),NO_ALGIN);//一~七
	OLED_Display_Image(0,6,16,16,(char*)Menu_16x16,NO_ALGIN);//显示菜单
	OLED_Display_Image(112,6,16,16,(char*)Lock_16x16,NO_ALGIN);//显示锁屏
}
/*
函数功能:主菜单显示函数
参数:u8 page_index,u8 key_val
返回值:无
*/
void Main_Menu_Func(u8 page_index,u8 key_val)
{
	char buff[20];
	OLED_Display_Image(0,0,11,7,(char*)Signal_11x7,NO_ALGIN);//显示信号塔
	OLED_Display_Image(14,0,9,9,(char*)Bluetooth_9x9,NO_ALGIN);//显示蓝牙
	snprintf(buff,sizeof(buff),"%02d:%02d:%02d",Current_Time.hour,Current_Time.min,Current_Time.sec);
	OLED_Display_String(0,0,8,8,buff,NORMAL,CEN_ALIGN);//显示时间
	OLED_Display_Image(112,0,16,8,(char*)Bat_16x8,NO_ALGIN);//显示电量
	OLED_Display_Image(15,4,16,16,(char*)Left_16x16,NO_ALGIN);//显示左箭头
	OLED_Display_Image(97,4,16,16,(char*)Right_16x16,NO_ALGIN);//显示右箭头
	OLED_Display_Image(0,6,16,16,(char*)Enter_16x16,NO_ALGIN);//显示确定
	OLED_Display_Image(112,6,16,16,(char*)Back_16x16,NO_ALGIN);//显示返回箭头
	switch(page_index)
	{
		case _Wifi_Option:OLED_Display_Image(0,2,48,48,(char*)Wifi_48x48,CEN_ALIGN);//显示Wifi图标
						 break;
		case _Bluetooth_Option:OLED_Display_Image(0,2,48,48,(char*)Bluetooth_48x48,CEN_ALIGN);//显示蓝牙图标
						 break;
		case _Setting_Option:OLED_Display_Image(0,2,48,48,(char*)Setting_48x48,CEN_ALIGN);//显示设置图标
						 break;
		case _Info_Option:OLED_Display_Image(0,2,48,48,(char*)Info_48x48,CEN_ALIGN);//显示关于信息图标
						 break;
		default:break;
	}
}


/*
函数功能:Wifi选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Wifi_Child(u8 page_index,u8 key_val)
{
	static u8 cur_pos=1;
	static u8 wifi_status=ON;
	static u8 wifi_mode=SoftAP_Station;
	static u8 esp_tcpserver=OFF;
	static u8 esp_unvarnishedmode=OFF;
	if(last_index!=_Wifi_Option)//判断是否是第一次进入此界面
	{
		switch(key_val)
		{
			case KEY_PREVIOUS: cur_pos==1?cur_pos=6:cur_pos--;
					break;
			case KEY_ENTER://确定(设置)按键
			{
				switch(cur_pos)
				{
					case 1:wifi_status=!wifi_status;
							if(wifi_status==OFF)
							{
								esp_tcpserver=OFF;
								esp_unvarnishedmode=OFF;
							}
							break;
					case 2:if(wifi_status==ON)
							{
								wifi_mode==SoftAP_Station?wifi_mode=Station:wifi_mode++;
								esp_tcpserver=OFF;
								esp_unvarnishedmode=OFF;
							}
							break;
					case 3:if(wifi_status==ON&&esp_unvarnishedmode==OFF&&
							(wifi_mode==SoftAP_Station||wifi_mode==SoftAP))esp_tcpserver=!esp_tcpserver;
							break;
					case 4:if(wifi_status==ON&&esp_tcpserver==OFF&&
							(wifi_mode==SoftAP_Station||wifi_mode==Station))esp_unvarnishedmode=!esp_unvarnishedmode;
							break;
					case 5:
							break;
					case 6:
							break;
					default:break;
				}
			}
					break;
			case KEY_NEXT:cur_pos==6?cur_pos=1:cur_pos++;
					break;
			default:break;
		}
	}
	else cur_pos=1;//第一次进入此界面,界面指针清零
	if(cur_pos<=4)
	{
		OLED_Display_String(0,0,8,16,wifi_status?"1.Switch:ON":"1.Switch:OFF",cur_pos==1?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,2,8,16,wifi_mode==SoftAP_Station?"2.Mode:AP+STA":wifi_mode==SoftAP?"2.Mode:AP":"2.Mode:STA",cur_pos==2?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,4,8,16,esp_tcpserver?"3.TCP server:ON":"3.TCP server:OFF",cur_pos==3?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,6,8,16,esp_unvarnishedmode?"4.Mqtt mode:ON":"4.Mqtt mode:OFF",cur_pos==4?REVERSE:NORMAL,NO_ALGIN);
	}
	else if(cur_pos<=8)
	{
		OLED_Display_String(0,0,8,16,"5.RSSI:",cur_pos==5?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,2,8,16,"6.Esp touch",cur_pos==6?REVERSE:NORMAL,NO_ALGIN);
	}
}


/*
函数功能:蓝牙选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Bluetooth_Child(u8 page_index,u8 key_val)
{
	static u8 cur_pos=1;
	static u8 BL_status=ON;
	if(last_index!=_Bluetooth_Option)//判断是否是第一次进入此界面
	{
		switch(key_val)
		{
			case KEY_PREVIOUS: cur_pos==1?cur_pos=4:cur_pos--;
					break;
			case KEY_ENTER://确定(设置)按键
			{
				switch(cur_pos)
				{
					case 1:BL_status=!BL_status;
							break;
					case 2:
							break;
					case 3:
							break;
					case 4:
							break;
					default:break;
				}
			}
					break;
			case KEY_NEXT:cur_pos==4?cur_pos=1:cur_pos++;
					break;
			default:break;
		}
	}
	else cur_pos=1;//第一次进入此界面,界面指针清零
	OLED_Display_String(0,0,8,16,BL_status?"1.Switch:ON":"1.Switch:OFF",cur_pos==1?REVERSE:NORMAL,NO_ALGIN);
	OLED_Display_String(0,2,8,16,"2.Addr match",cur_pos==2?REVERSE:NORMAL,NO_ALGIN);
	OLED_Display_String(0,4,8,16,"3.RSSI:",cur_pos==3?REVERSE:NORMAL,NO_ALGIN);
	OLED_Display_String(0,6,8,16,"4.Mode set",cur_pos==4?REVERSE:NORMAL,NO_ALGIN);
}


/*
函数功能:设置选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Setting_Child(u8 page_index,u8 key_val)
{
	char buff[20];
	static u8 cur_pos=1;
	static u8 Remote_form=0;
	static u8 EEPROM_swi=ON;
	static u8 Bri_level=8;
	if(last_index!=_Setting_Option)//判断是否是第一次进入此界面
	{
		switch(key_val)
		{
			case KEY_PREVIOUS: cur_pos==1?cur_pos=6:cur_pos--;
					break;
			case KEY_ENTER://确定(设置)按键
			{
				switch(cur_pos)
				{
					case 1:
							break;
					case 2:Remote_form==2?Remote_form=0:Remote_form++;
							break;
					case 3:Bri_level==16?Bri_level=1:Bri_level++;
						   OLED_SPI_WriteByte(0x81,OLED_CMD);//设置对比度
						   OLED_SPI_WriteByte(Bri_level*16-1,OLED_CMD);
							break;
					case 4:BEEP_swi=!BEEP_swi;
							break;
					case 5:EEPROM_swi=!EEPROM_swi;
							break;
					case 6:
							break;
					default:break;
				}
			}
					break;
			case KEY_NEXT:cur_pos==6?cur_pos=1:cur_pos++;
					break;
			default:break;
		}
	}
	else cur_pos=1;//第一次进入此界面,界面指针清零
	
	if(cur_pos<=4)
	{
		OLED_Display_String(0,0,8,16,"1.Calib time",cur_pos==1?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,2,8,16,Remote_form==0?"2.Remote:NRF2.4G":Remote_form==1?"2.Remote:Wi-Fi":"2.Remote:BL",cur_pos==2?REVERSE:NORMAL,NO_ALGIN);
		snprintf(buff,sizeof(buff),"3.Bri set:%d",Bri_level);//显示亮度
		OLED_Display_String(0,4,8,16,buff,cur_pos==3?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,6,8,16,BEEP_swi?"4.BEEP:ON":"4.BEEP:OFF",cur_pos==4?REVERSE:NORMAL,NO_ALGIN);
	}
	else if(cur_pos<=8)
	{
		OLED_Display_String(0,0,8,16,EEPROM_swi?"5.EEPROM:ON":"5.EEPROM:OFF",cur_pos==5?REVERSE:NORMAL,NO_ALGIN);
		OLED_Display_String(0,2,8,16,"6.Low Power",cur_pos==6?REVERSE:NORMAL,NO_ALGIN);
	}
	

}
/*
函数功能:关于信息页
参数:u8 page_index,u8 key_val
返回值;无
*/
void Info_Child(u8 page_index,u8 key_val)
{
	char buff[20];
	snprintf(buff,sizeof(buff),"1.BAT vol:%.2f V",BAT_Voltage*2);//分压比为2
	OLED_Display_String(0,0,8,16,buff,NORMAL,NO_ALGIN);
	OLED_Display_String(0,3,8,16,"2.Version:v1.0",NORMAL,NO_ALGIN);
}
/*
函数功能:OLED熄屏
参数:u8 page_index,u8 key_val
返回值;无
*/
void OLED_Lock(u8 page_index,u8 key_val)
{
	OLED_Clear(0);
}

版权声明:本文为CSDN博主「Fog.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44062900/article/details/115798468

生成海报
点赞 0

Fog.

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32智能门锁之调试步进电机

1、电机模块 手动转动轴芯是否正常转动有阻力,证明电机是正常的。 基于STM32F407单片机杜邦线接线到步进电机驱动模块 2、步进电机 motor.c 和 motor.h代码 #include "motor.h"#define MOTOR_

AD原理图设计与Clion源码工具学习

一、AD绘制电路原理图 1.准备工作 下载Altium Designer,具体安装步骤以及百度网盘分享参考:Altium Designer2018下载安装及基本使用 STM32F103C8T6元件库&#xff1a

#C51 IIC通讯(底层配置时序)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如: 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 前言