本帖最后由 流氓兔v 于 2011-4-10 21:31 编辑
做电子播放琴,,,,,昨天刚研究出来的无限添加菜单系统。
一个键有三种状态,键前沿,长按键,1S后产生作用键
使用方法:
先定义一个类似数据库结构体
#define FOCUS_VICE_OFF 1//子菜单作用——伴音声音设置——关
#define FOCUS_VICE_ON 2//子菜单作用——伴音声音设置——开
#define MAX_ITEM_VICE 2
Item_struct code Item_vice_voice[MAX_ITEM_VICE]={ {"OFF",FOCUS_VICE_OFF},
{"ON",FOCUS_VICE_ON}};
#define MAX_ITEM_MUSIC 2
Item_struct code Item_vice_list[2]={ {"caimugu",0},
{"youling",0}};
#define MAX_MENU_KEY 2
Menu_struct code Main_menu_key[MAX_MENU_KEY]={ {"musiclist", MAX_ITEM_VICE, Item_vice_list},
{"bangyin", MAX_ITEM_MUSIC, Item_vice_voice}};
void key_function_key(void)
{
if(Item_focus==FOCUS_VICE_OFF)
{
Flag_key_on=1; //开启演奏
Flag_beep2=0; //关闭伴音
}
if(Item_focus==FOCUS_VICE_ON)
{
Flag_key_on=1; //开启演奏
Flag_beep2=1; //开启伴音
}
}
void default_display_key(void)
{
LCD_prints(0, 0, "Key Play Music");
}
调用:
menu(MAX_MENU_KEY, Main_menu_key, default_display_key, key_function_key);
子函数:
/********************************************
* 名称:两层菜单函数
* 平台: AT89S52 12M晶振
* 编写:abao 2011-4-9
* 修改:
* 描述: 1.0版本
********************************************/
uint8 Item_focus; //子菜单焦点(决定菜单的作用)
bit Flag_menu_on; //菜单标志
bit Flag_item_on; //子菜单标志
uint8 Menu_order; //菜单次序
uint8 Item_order; //子菜单次序
void menu(uint8 max_menu, Menu_struct code *Main_menu, void (*default_display)(void), void (*key_function)(void))
{
if(Flag_menu_on) //开启菜单
{
if(Flag_item_on) //子菜单
{
if(MENU_KEY_NEXT) //前一个选项
{
MENU_KEY_NEXT=0;
if(Item_order<Main_menu[Menu_order].item_max-1)
{
LCD_clean();
++Item_order;
}
}
if(MENU_KEY_PRE) //后一个选项
{
MENU_KEY_PRE=0;
if(Item_order>0)
{
LCD_clean();
--Item_order;
}
}
LCD_prints(5, 0, Main_menu[Menu_order].menu_name);
LCD_printc(0, 1, 0x7e); //显示→
LCD_prints(1, 1, Main_menu[Menu_order].item_struct[Item_order].item_name);
if(MENU_KEY_YES) //子菜单功能选中
{
MENU_KEY_YES=0;
LCD_clean();
Flag_menu_on=0; //关闭菜单
Flag_item_on=0; //关闭子菜单
Item_focus=Main_menu[Menu_order].item_struct[Item_order].item_focus;
(*key_function)(); //按键作用
}
}else //菜单
{
if(MENU_KEY_NEXT) //前一个选项
{
MENU_KEY_NEXT=0;
if(Menu_order<max_menu-1)
{
LCD_clean();
++Menu_order;
}
}
if(MENU_KEY_PRE) //后一个选项
{
MENU_KEY_PRE=0;
if(Menu_order>0)
{
LCD_clean();
--Menu_order;
}
}
LCD_prints(5, 0, "Eenu");
LCD_printc(0, 1, 0x7e); //显示→
LCD_prints(1, 1, Main_menu[Menu_order].menu_name);
if(MENU_KEY_YES) //开启子菜单
{
MENU_KEY_YES=0;
LCD_clean();
Flag_item_on=1; //开启子菜单
}
}
}else
{
(*default_display)(); //默认显示
}
if(MENU_KEY_YES)
{
MENU_KEY_YES=0;
LCD_clean();
Flag_menu_on=1; //开启菜单
}
if(MENU_KEY_NO) //取消键
{
MENU_KEY_NO=0;
LCD_clean();
Flag_menu_on=0; //关闭菜单
Flag_item_on=0; //关闭子菜单
}
if(KEY_HOME)
{
Flag_menu_on=0; //关闭菜单
Flag_item_on=0; //关闭子菜单
}
}
按键子菜单,8MS循环一次:
/********************************************
* 函数:读矩阵键盘
* 输入:K0~K15
* 输出:Key_Flag0,Key_Flag1,EKey_Flag0,EKey_Flag1
* 使用:key_read();
********************************************/
sbit IOROW1=P1^0; //第1 行按键
sbit IOROW2=P1^1; //第2 行按键
sbit IOROW3=P1^2; //第3 行按键
sbit IOROW4=P1^3; //第4 行按键
uint8 Key_Time; //读键去抖延时
uint8 Lkey_time; //长按键延时时间
bit Lkey_state; //长按键状态
bit Lkey_flag; //长按标志
uint8 bdata Key_Flag0; //KEY0
sbit K0=Key_Flag0^0;
sbit K1=Key_Flag0^1;
sbit K2=Key_Flag0^2;
sbit K3=Key_Flag0^3;
sbit K4=Key_Flag0^4;
sbit K5=Key_Flag0^5;
sbit K6=Key_Flag0^6;
sbit K7=Key_Flag0^7;
uint8 bdata Key_Flag1; //KEY1按键状态
sbit K8=Key_Flag1^0;
sbit K9=Key_Flag1^1;
sbit K10=Key_Flag1^2;
sbit K11=Key_Flag1^3;
sbit K12=Key_Flag1^4;
sbit K13=Key_Flag1^5;
sbit K14=Key_Flag1^6;
sbit K15=Key_Flag1^7;
uint8 bdata EKey_Flag0; //KEY0键前沿
sbit EK0=EKey_Flag0^0;
sbit EK1=EKey_Flag0^1;
sbit EK2=EKey_Flag0^2;
sbit EK3=EKey_Flag0^3;
sbit EK4=EKey_Flag0^4;
sbit EK5=EKey_Flag0^5;
sbit EK6=EKey_Flag0^6;
sbit EK7=EKey_Flag0^7;
uint8 bdata EKey_Flag1; //EKEY1键前沿
sbit EK8=EKey_Flag1^0;
sbit EK9=EKey_Flag1^1;
sbit EK10=EKey_Flag1^2;
sbit EK11=EKey_Flag1^3;
sbit EK12=EKey_Flag1^4;
sbit EK13=EKey_Flag1^5;
sbit EK14=EKey_Flag1^6;
sbit EK15=EKey_Flag1^7;
uint8 bdata LKey_Flag0; //KEY0长按键
sbit LK0=LKey_Flag0^0;
sbit LK1=LKey_Flag0^1;
sbit LK2=LKey_Flag0^2;
sbit LK3=LKey_Flag0^3;
sbit LK4=LKey_Flag0^4;
sbit LK5=LKey_Flag0^5;
sbit LK6=LKey_Flag0^6;
sbit LK7=LKey_Flag0^7;
uint8 bdata LKey_Flag1; //KEY1长按键状态
sbit LK8=LKey_Flag1^0;
sbit LK9=LKey_Flag1^1;
sbit LK10=LKey_Flag1^2;
sbit LK11=LKey_Flag1^3;
sbit LK12=LKey_Flag1^4;
sbit LK13=LKey_Flag1^5;
sbit LK14=LKey_Flag1^6;
sbit LK15=LKey_Flag1^7;
//读矩阵键盘
void key_read(void)
{
uint8 Key_Temp0, Key_Temp1; //临时键
P1 = 0xff; //扫描第2行键
IOROW1= 0;
Key_Temp0 = ((P1 & 0xf0) ^ 0xf0)>> 4;
P1= P1 | 0xff; //扫描第1行键
IOROW2= 0;
Key_Temp0 = Key_Temp0 + ((P1 & 0xf0) ^ 0xf0);
P1= P1 | 0xff; //扫描第4行键
IOROW3= 0;
Key_Temp1 =((P1 & 0xf0) ^ 0xf0)>> 4;
P1= P1 | 0xff; //扫描第3行键
IOROW4= 0;
Key_Temp1 = Key_Temp1 + ((P1 & 0xf0) ^ 0xf0);
if((Key_Temp0 != EKey_Flag0) || (Key_Temp1 != EKey_Flag1)) //按键去抖
{
if( !Key_Time )
{
EKey_Flag0 = (Key_Flag0 ^ Key_Temp0) & Key_Temp0;
EKey_Flag1 = (Key_Flag1 ^ Key_Temp1) & Key_Temp1;
Key_Flag1 = Key_Temp1;
Key_Flag0 = Key_Temp0;
++Lkey_time;
if(Lkey_state)
{
if(Lkey_time==25)//200ms
{
Lkey_time=0;
Lkey_flag=1;
}else
{
Lkey_flag=0;
}
}else
{
if(Lkey_time==125)//长按键1s
{
Lkey_time=0;
Lkey_state=1;
Lkey_flag=1;
}else
{
Lkey_flag=0;
}
}
}else
{
--Key_Time;
Key_Temp1 = Key_Flag1;
Key_Temp0 = Key_Flag0;
}
}else
{
Lkey_state=0; //长按键标志清0 长按键第一次延迟1S响应
Lkey_time=0; //长按键延时时间清0
Key_Time = 2;
EKey_Flag1 = 0;
EKey_Flag0 = 0;
Key_Flag1 = Key_Temp1;
Key_Flag0 = Key_Temp0;
}
if(Lkey_flag) //长按键标志为1
{
LKey_Flag0 = Key_Flag0;
LKey_Flag1 = Key_Flag1;
}else
{
LKey_Flag0 = 0;
LKey_Flag1 = 0;
}
} |