首先定义一个菜单结构
typedef struct menu//定义一个菜单
{
u8 range_from,range_to; //当前显示的项开始及结束序号 u8 itemCount;//项目总数 u8 selected;//当前选择项 u8 *menuItems[17];//菜单项目 struct menu **subMenus;//子菜单
struct menu *parent;//上级菜单 ,如果是顶级则为null void (**func)();//选择相应项按确定键后执行的函数 }Menu;
Menu MainMenu = { //定义主菜单
0,3,4,0,//默认显示0-3项,总共4项,当前选择第0项 {
\设置1 \\x10\ \设置2 \\x10\ \输入指令发送 \ \查询 \\x10\ }
};
Menu searchMenu = {//查询菜单 0,3,6,0,
{
\记帐记录明细 \ \未采集记录数 \ \设备机号 \ \本机IP地址 \ \记录空间大小 \ \软件版本 \ }
};
Menu *currentMenu;//当前的菜单
用于显示菜单项
void display(u8 line) //显示菜单项并设置选中的项反白 { int i;
line = 3-(currentMenu->range_to-line); Lcd_Fill(0x00); for(i = 0;i<4;i++) {
Lcd_Disp(i+1,0,currentMenu->menuItems[i+currentMenu->range_from]); }
highlight(0,line,8,255);//反白显示指定行 }
void func(void) {
printf(\}
初始化菜单: void initMenu() {
MainMenu.subMenus = malloc(sizeof(&MainMenu)*4);
MainMenu.subMenus[0] = NULL;//第1到3项没有子菜单置null,选择后程序会调用func中相应项中的函数
MainMenu.subMenus[1] = NULL;
MainMenu.subMenus[2] = NULL;
MainMenu.subMenus[3] = &searchMenu;//第四项查询有子菜单 MainMenu.func = malloc(sizeof(&func)*4); MainMenu.func[0] = NULL;
MainMenu.func[1] = NULL;
MainMenu.func[2] = &func;//当选择了并按了确定,会执行func函数 MainMenu.func[3] = NULL;
MainMenu.parent = NULL;//表示是顶级菜单
searchMenu.subMenus = malloc(sizeof(&searchMenu)*6);
searchMenu.subMenus[0] = searchMenu.subMenus[1] = searchMenu.subMenus[2] = searchMenu.subMenus[3] = searchMenu.subMenus[4] = searchMenu.subMenus[5] = NULL;
searchMenu.func = malloc(sizeof(&printf)*6);
searchMenu.func[0] = searchMenu.func[2] = searchMenu.func[2] =
searchMenu.func[3] = searchMenu.func[4] = searchMenu.func[5] = NULL;
searchMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询子菜单后按返回键,将会显示这个菜单 项
currentMenu = &MainMenu; } main
int main(void) {
delay_init(); uart_init(9600); Lcd_Init(); KEY_Init(); initMenu();
display(currentMenu->selected); while(1) {
key = KEY_Scan(); if(key == 0) {
delay_ms(10); continue; }
printf(\ switch(key) {
case 12://向上
if(currentMenu->selected == 0)//到了第一项 break; else {
currentMenu->selected--;
if(currentMenu->selected < currentMenu->range_from)//更新显示的区域 {
currentMenu->range_from = currentMenu->selected; currentMenu->range_to = currentMenu->range_from+3; }
display(currentMenu->selected); break; }
case 8://向下
if(currentMenu->selected == currentMenu->itemCount-1) break; else {
currentMenu->selected++;
if(currentMenu->selected>currentMenu->range_to)
{
currentMenu->range_to = currentMenu->selected; currentMenu->range_from = currentMenu->range_to-3; }
display(currentMenu->selected); break;
}
case 4://Enter键 {
if(currentMenu->subMenus[currentMenu->selected] !=NULL) {
currentMenu = currentMenu->subMenus[currentMenu->selected]; display(0); } else {
if(currentMenu->func[currentMenu->selected] != NULL) {
currentMenu->func[currentMenu->selected]();//执行相应的函数 display(currentMenu->selected);//返回后恢复原来的菜单状态 } } break; }
case 3://返回键
{
if(currentMenu->parent!=NULL)//父菜单不为空,将显示父菜单 {
currentMenu = currentMenu->parent; display(currentMenu->selected); } break; } default: break; }
delay_ms(10); }
}
void Lcd_Disp(unsigned char x,unsigned char y,unsigned char *s) {
Lcd_Write_Cmd(0x30); //进入标准模式 LCD_Set_XY(x,y); while (*s) {
Lcd_Write_Data(*s); s++; }
Lcd_Write_Cmd(0x36); //返回图形模式 }
void highlight(uchar x,uchar y,uchar width,u8 mode) //反白,X值为0-7,Y值为0-3,width为行反白格数 {
uchar i,j,flag=0x00; if(y>1) {
flag=0x08; y=y-2; }
Lcd_Write_Cmd(0x34); //写数据时,关闭图形显示,且打开扩展指令集 for(i=0;i<16;i++) {
Lcd_Write_Cmd(0x80+(y<<4)+i); Lcd_Write_Cmd(0x80+flag+x); for(j=0;j Lcd_Write_Data(mode); Lcd_Write_Data(mode); } } Lcd_Write_Cmd(0x36); //写完数据,开图形显示 }