菜单一般需要四个按键,上下移动光标,进入菜单,退出菜单
1.按键部分
按键头文件
#ifndef __KEYdriver_H
#define __KEYdriver_H
#include "sys.h"
#include "stdbool.h"
/*用户定义的宏开始*/
#define CursorUp PCin(14)
#define CursorDown PCin(15)
#define Confirm PAin(0)
#define Quit PAin(1)
#define LEDOut PCout(13)#define MAX_MenuNum 6/*用户定义的宏结束*/
/*用户定义变量开始*/
struct KEY_TASK
{char key; bool in_Or_start;bool ReturnOneLevelUp;
};/*用户定义变量结束*/void KeyDriverInit(void);
void KEY_Control(struct KEY_TASK* strKey);
void StrKeyInit(struct KEY_TASK* strKey);#endif
按键c文件
#include "KeyDriver.h"void KeyDriverInit(void)
{ GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitTypeDef GPIO_InitStruct1;GPIO_InitTypeDef GPIO_InitStruct2;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能B端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能B端口时钟GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0|GPIO_Pin_1;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能B端口时钟GPIO_InitStruct1.GPIO_Pin= GPIO_Pin_14|GPIO_Pin_15;GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct1.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStruct1);GPIO_InitStruct2.GPIO_Pin= GPIO_Pin_13;GPIO_InitStruct2.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct2.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStruct2);
}void KEY_Control(struct KEY_TASK* strKey)
{if(CursorUp ==0 ){delay_ms(10);if(CursorUp ==0)strKey->key++;while(CursorUp == 0); delay_ms(10);}else if(CursorDown ==0 ){delay_ms(10);if(CursorDown == 0)strKey->key--;while(CursorDown == 0); delay_ms(10);}else if(Confirm == 0){delay_ms(10);if(Confirm == 0)strKey->in_Or_start = 1 ;while(Confirm == 0); delay_ms(10); }else if(Quit == 0){delay_ms(10);if(Quit == 0)strKey->ReturnOneLevelUp = 1 ;while(Quit == 0); delay_ms(10); }if(strKey->key<=0)strKey->key = 0;if(strKey->key > MAX_MenuNum)strKey->key = 0;return ;
}void StrKeyInit(struct KEY_TASK* strKey)
{strKey->in_Or_start =0;strKey->key = 0;strKey->ReturnOneLevelUp = 0;
}
2.菜单显示部分
菜单头文件
#ifndef __MENU_H
#define __MENU_H
#include "sys.h"void OneMenu(void);#endif
菜单C文件
#include "menu.h" void OneMenu(void)
{struct KEY_TASK StrOneMenuKey;StrKeyInit(&StrOneMenuKey);while(1) {KEY_Control(&StrOneMenuKey);StrOneMenuKey.ReturnOneLevelUp = 0;//防止误按,第一级界面无法返回上一界面if(StrOneMenuKey.key<=6)//判断按键向下移动的次数方便容纳更多的菜单{switch(StrOneMenuKey.key){case 0:OLED_ShowString(1,0,"correction <",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two ",8);//显示并不清空OLED_ShowString(1,3,"Task three ",8);//显示并不清空OLED_ShowString(1,4,"Task four ",8);//显示并不清空OLED_ShowString(1,5,"Task five ",8);//显示并不清空OLED_ShowString(1,6,"Task six ",8);//显示并不清空if(StrOneMenuKey.in_Or_start ==1)//可以进入二级菜单,也可以执行任务我这里就执行任务了。{OLED_Clear();while(1){KEY_Control(&StrOneMenuKey);//当需要循环执行的任务完成后可以返回一个值利用这个返回值判断是否结束while//非循环任务直接在此处调用函数即可无需whileLEDOut =0;if(StrOneMenuKey.ReturnOneLevelUp == 1){StrOneMenuKey.in_Or_start = 0;StrOneMenuKey.ReturnOneLevelUp = 0;LEDOut = 1; break;}}}break;case 1:OLED_ShowString(1,0,"correction ",8);OLED_ShowString(1,1,"Task one <",8);OLED_ShowString(1,2,"Task two ",8);OLED_ShowString(1,3,"Task three ",8);OLED_ShowString(1,4,"Task four ",8);OLED_ShowString(1,5,"Task five ",8);OLED_ShowString(1,6,"Task six ",8);if(StrOneMenuKey.in_Or_start ==1)//可以进入二级菜单,也可以执行任务我这里就执行任务了。{OLED_Clear();while(1){KEY_Control(&StrOneMenuKey);//当需要循环执行的任务完成后可以返回一个值利用这个返回值判断是否结束while//非循环任务直接在此处调用函数即可无需while//printf("hello world\r\n");OLED_ShowNumber(1,1,USART_RX_BUF[2],3,8);if(StrOneMenuKey.ReturnOneLevelUp == 1){StrOneMenuKey.in_Or_start = 0;StrOneMenuKey.ReturnOneLevelUp = 0;break; }}}break;case 2:OLED_ShowString(1,0,"correction ",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two <",8);//显示并不清空OLED_ShowString(1,3,"Task three ",8);//显示并不清空OLED_ShowString(1,4,"Task four ",8);//显示并不清空OLED_ShowString(1,5,"Task five ",8);//显示并不清空OLED_ShowString(1,6,"Task six ",8);//显示并不清空 break;case 3:OLED_ShowString(1,0,"correction",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two ",8);//显示并不清空OLED_ShowString(1,3,"Task three <",8);//显示并不清空OLED_ShowString(1,4,"Task four ",8);//显示并不清空OLED_ShowString(1,5,"Task five ",8);//显示并不清空OLED_ShowString(1,6,"Task six ",8);//显示并不清空 break;case 4:OLED_ShowString(1,0,"correction ",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two ",8);//显示并不清空OLED_ShowString(1,3,"Task three ",8);//显示并不清空OLED_ShowString(1,4,"Task four <",8);//显示并不清空OLED_ShowString(1,5,"Task five ",8);//显示并不清空OLED_ShowString(1,6,"Task six ",8);//显示并不清空 break;case 5:OLED_ShowString(1,0,"correction ",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two ",8);//显示并不清空OLED_ShowString(1,3,"Task three ",8);//显示并不清空OLED_ShowString(1,4,"Task four ",8);//显示并不清空OLED_ShowString(1,5,"Task five <",8);//显示并不清空OLED_ShowString(1,6,"Task six ",8);//显示并不清空break;case 6:OLED_ShowString(1,0,"correction ",8);//显示并不清空OLED_ShowString(1,1,"Task one ",8);//显示并不清空OLED_ShowString(1,2,"Task two ",8);//显示并不清空OLED_ShowString(1,3,"Task three ",8);//显示并不清空OLED_ShowString(1,4,"Task four ",8);//显示并不清空OLED_ShowString(1,5,"Task five ",8);//显示并不清空OLED_ShowString(1,6,"Task six <",8);//显示并不清空 break;}}
// if(StrOneMenuKey.key>6)
// {
// switch(StrOneMenuKey.key)
// {
// case 7:
// OLED_ShowString(1,0,"correction <",8);//显示并不清空
// OLED_ShowString(1,1,"Task one ",8);//显示并不清空
// OLED_ShowString(1,2,"Task two ",8);//显示并不清空
// OLED_ShowString(1,3,"Task three ",8);//显示并不清空
// OLED_ShowString(1,4,"Task four ",8);//显示并不清空
// OLED_ShowString(1,5,"Task five ",8);//显示并不清空
// OLED_ShowString(1,6,"Task six ",8);//显示并不清空
// break;
// case 8:OLED_Clear();
// OLED_ShowString(1,0,"correction ",8);//显示并不清空
// OLED_ShowString(1,1,"Task one <",8);//显示并不清空
// OLED_ShowString(1,2,"Task two ",8);//显示并不清空
// OLED_ShowString(1,3,"Task three ",8);//显示并不清空
// OLED_ShowString(1,4,"Task four ",8);//显示并不清空
// OLED_ShowString(1,5,"Task five ",8);//显示并不清空
// OLED_ShowString(1,6,"Task six ",8);//显示并不清空
// break;
// case 9:
// OLED_ShowString(1,0,"correction ",8);//显示并不清空
// OLED_ShowString(1,1,"Task one ",8);//显示并不清空
// OLED_ShowString(1,2,"Task two <",8);//显示并不清空
// OLED_ShowString(1,3,"Task three ",8);//显示并不清空
// OLED_ShowString(1,4,"Task four ",8);//显示并不清空
// OLED_ShowString(1,5,"Task five ",8);//显示并不清空
// OLED_ShowString(1,6,"Task six ",8);//显示并不清空
// break;
// case 10:
// OLED_ShowString(1,0,"correction",8);//显示并不清空
// OLED_ShowString(1,1,"Task one ",8);//显示并不清空
// OLED_ShowString(1,2,"Task two ",8);//显示并不清空
// OLED_ShowString(1,3,"Task three <",8);//显示并不清空
// OLED_ShowString(1,4,"Task four ",8);//显示并不清空
// OLED_ShowString(1,5,"Task five ",8);//显示并不清空
// OLED_ShowString(1,6,"Task six ",8);//显示并不清空
// break;
// }
// }}//while
}