delay_1ms();
}
#endif
//函数说明
//--------------------------------
unsignedcharget_key(void);
//--------------------------------
#ifndef__key_h
#define__key_h
unsignedcharkey_read(void)
{
unsignedchari;
/*获取列地址*/
DDRB=0xf0;//高4位输出,低4位输入
PORTB=0x0f;//高4位输出0,低4位带上拉输入
delay_nms
(1);
i=PINB&0x0f;
/*获取行地址*/
DDRB=0x0f;//高4位输入,低4位输出
PORTB=0xf0;//低4位输出0,高4位带上拉输入
delay_nms
(1);
i|=PINB&0xf0;
switch(i)
{
case0xff:
return0x00;
case0xee:
return'0';
case0xde:
return'1';
case0xbe:
return'2';
case0x7e:
return'3';
case0xed:
return'4';
case0xdd:
return'5';
case0xbd:
return'6';
case0x7d:
return'7';
case0xeb:
return'8';
case0xdb:
return'9';
case0xbb:
return'A';
case0x7b:
return'B';
case0xe7:
return'C';
case0xd7:
return'D';
case0xb7:
return'E';
case0x77:
return'F';
default:
return0x00;
}
}
unsignedcharget_key(void)
{
unsignedchari;
staticunsignedcharj;//按键记录
i=key_read();
if(i==0x00)//无有效按键按下
{
j=0x00;//清除按键记录
return0x00;//程序退出
}
if(j==0x00)//为新按键
{
j=i;//保存本次结果
delay_nms(10);//延时去抖动
i=key_read();
if(i==j)
returni;
}
return0x00;
}
#endif
#include
#include
#include"1602.h"
#include"key.h"
#include"uart.h"
/**************************************************************
*主函数*
**************************************************************/
voidmain(void)
{
LCD_init();
init_USART();
ShowMenu();//欢迎界面显示
while
(1)
{
Menu_Change(get_key());
}
}
#defineNull0
/***********************
*函数声明*
***********************/
voidShowMenu(void);
voidMenu_Change(unsignedcharKeyNum);
/***********************
*按键功能键宏定义*
***********************/
#defineUP'3'
#defineDown'7'
#defineEsc'B'
#defineEnter'F'
#defineReset'0'
/**********************
*目录结构体定义*
**********************/
structMenuItem
{
unsignedcharMenuCount;//当前层节点数
unsignedchar*DisplayString;//菜单标题
void(*Subs)();//节点函数
structMenuItem*ChildrenMenus;//子节点
structMenuItem*ParentMenus;//父节点
};
/***********************
*调用子函数区*
***********************/
voidNullSubs(void)
{
}
//----------------------以下为例子,请根据实际情况修改---------------------------
voidTimeSet(void)
{
put_s("TimeSet");
}
voidDateSet(void)
{
put_s("DateSet");
}
voidAlertSet(void)
{
put_s("AlertSet");
}
//------------------------------------------------------------------------------
/***********************
*结构体区*
***********************/
//----------------------以下为例子,请根据实际情况修改---------------------------
structMenuItemTimeMenu[4];
structMenuItemFlashMenu[5];
structMenuItemVoiceMenu[5];
structMenuItemRobotMenu[5];
structMenuItemMainMenu[5];
structMenuItemTimeMenu[4]=
{//MenuCountDisplayStringSubsChildrenMenusParentMenus
{4,"1.TimeSet",TimeSet,Null,MainMenu},
{4,"2.DateSet",DateSet,Null,MainMenu},
{4,"3.AlertSet",AlertSet,Null,MainMenu},
{4,"4.Back",NullSubs,MainMenu,MainMenu},
};
structMenuItemFlashMenu[5]=
{//MenuCountDisplayStringSubsChildrenMenusParentMenus
{5,"1.FlashRecord",NullSubs,Null,MainMenu},
{5,"2.Play",NullSubs,Null,MainMenu},
{5,"3.Pause",NullSubs,Null,MainMenu},
{5,"4.FlashDelete",NullSubs,Null,MainMenu},
{5,"5.Back",NullSubs,MainMenu,MainMenu},
};
structMenuItemVoiceMenu[5]=
{//MenuCountDisplayStringSubsChildrenMenusParentMenus
{5,"1.VoiceRecord",NullSubs,Null,MainMenu},
{5,"2.Play",NullSubs,Null,MainMenu},
{5,"3.Pause",NullSubs,Null,MainMenu},
{5,"4.VoiceDelete",NullSubs,Null,MainMenu},
{5,"5.Back",NullSubs,MainMenu,MainMenu},
};
structMenuItemRobotMenu[5]=
{//MenuCountDisplayStringSubsChildrenMenusParentMenus
{5,"1.TurnLeft",NullSubs,Null,MainMenu},
{5,"2.TurnRight",NullSubs,Null,MainMenu},
{5,"3.GoAhead",NullSubs,Null,MainMenu},
{5,"4.GoBack",NullSubs,Null,MainMenu},
{5,"5.Back",NullSubs,MainMenu,MainMenu},
};
structMenuItemMainMenu[5]=
{//MenuCountDisplayStringSubsChildrenMenusParentMenus
{5,"1.TimeSet",NullSubs,TimeMenu,Null},
{5,"2.VoiceCenter",NullSubs,VoiceMenu,Null},
{5,"3.RobotControl",NullSubs,RobotMenu,Null},
{5,"4.FlashOption",NullSubs,FlashMenu,Null},
{5,"5.Back",NullSubs,MainMenu,MainMenu},
};
//------------------------------------------------------------------------------
/***********************
*全局变量声明区*
***********************/
structMenuItem(*MenuPoint)=MainMenu;//结构体指针,指向结构体后由内部函数指针指向功能函数
unsignedcharDisplayStart=0;//显示时的第一个菜单项
unsignedcharUserChoose=0;//用户所选菜单项
unsignedcharDisplayPoint=0;//显示指针
unsignedMaxItems;//同级最大菜单数
unsignedcharShowCount=2;//同屏显示菜单数
/***********************
*显示函数区*
***********************/
voidShowMenu(void)
{
unsignedcharn;
MaxItems=MenuPoint[0].MenuCount;//定义最大同级菜单
DisplayPoint=DisplayStart;
for(n=0;DisplayPoint{if(DisplayPoint==UserChoose)
LCD_write_string(0,n,"->");
LCD_write_string(2,n,MenuPoint[DisplayPoint++].DisplayString);
}
}
voidMenu_Change(unsignedcharKeyNum)
{
if(KeyNum)
{
switch(KeyNum)
{
caseUP:
UserChoose--;
if(UserChoose==255)
{
UserChoose=0;//上翻截至,如果要回滚赋值MaxItems-1
}
break;
caseEsc:
if(MenuPoint[UserChoose].ParentMenus!
=Null)
{
MenuPoint=MenuPoint[UserChoose].ParentMenus;
UserChoose=0;
DisplayStart=0;
}
break;
caseDown:
UserChoose++;
if(UserChoose==MaxItems)
{
UserChoose=MaxItems-1;//下翻截至,如要回滚赋值为0
}
break;
caseEnter:
if(MenuPoint[UserChoose].Subs!
=NullSubs)
{