在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 單片機多級菜單編程實現(xiàn)

            單片機多級菜單編程實現(xiàn)

            作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
            建立一個樹狀的菜單結(jié)構(gòu),用鏈表實現(xiàn)

            鏈表中包含:

            本文引用地址:http://www.biyoush.com/article/201611/322426.htm

            1、指向同級左右菜單和指向父菜單、子菜單的四個菜單結(jié)構(gòu)體指針;

            2、進入該菜單時需要執(zhí)行的初始化函數(shù)指針

            3、退出該菜單時需要執(zhí)行的結(jié)束函數(shù)指針

            4、該菜單內(nèi)的按鍵處理函數(shù)指針數(shù)組的指針操作菜單模塊需要的按鍵操作有:左、右、確

            認、退出。

            采用這種辦法,可以方便的添加或刪減菜單。并且只需要在其頭文件中修改初始變量就可

            以實現(xiàn),完全無須修改C文件中的任何函數(shù)。

            具體結(jié)構(gòu)定義

            我的定義,做個參考:

            #defineMENU_HLP_EN//菜單幫助信息使能

            typedef struct

            {

            void (*pMenuTaskInit)(void);//指向菜單任務(wù)初始化函數(shù)的指針

            void (*pMenuTaskEnd)(void);//指向菜單任務(wù)結(jié)束函數(shù)的指針

            }MENU_TASK_TYP;

            typedef struct MenuTyp

            {

            INT8U*MenuName;//菜單名稱字符串

            WORK_MODWorkMod;//工作狀態(tài)編號

            MENU_TASK_TYP*pMenuTask;//指向菜單任務(wù)的指針

            void (**pTaskKeyDeal)(void);//指向菜單任務(wù)按鍵處理函數(shù)數(shù)組的指針

            #ifdef MENU_HLP_EN

            INT8U*MenuHlp;//菜單幫助字符串

            #endif

            struct MenuTyp*pParent;//指向上層菜單的指針

            struct MenuTyp*pChild;//指向子菜單的指針

            struct MenuTyp*pRight;//指向右菜單的指針

            struct MenuTyp*pLeft;//指向左菜單的指針

            }MENU_TYP;

            我根據(jù)網(wǎng)上的資料做的一個菜單:

            struct KeyTabStruct{

            uint8MenuIndex;//當前狀態(tài)索引號

            uint8MaxItems;//本級菜單最大條目數(shù)

            uint8ShowLevel;//菜單顯示內(nèi)容

            uint8PressOk;//按下"回車"鍵時轉(zhuǎn)向的狀態(tài)索引號

            uint8PressEsc;//按下"返回"鍵時轉(zhuǎn)向的狀態(tài)索引號

            uint8PressDown;//按下"向下"鍵時轉(zhuǎn)向的狀態(tài)索引號

            uint8PressUp;//按下"向上"鍵時轉(zhuǎn)向的狀態(tài)索引號

            void(*CurrentOperate)();//當前狀態(tài)應(yīng)該執(zhí)行的功能操作

            };

            uint8MenuID;//菜單ID號

            uint8MenuNextID;//下級菜單ID號

            //CurMenuID=本菜單ID

            //MaxMenuItem=同級菜單最大項數(shù)

            //OkMenuID=子菜單層所對應(yīng)的菜單ID,ID=999為菜單已經(jīng)到底了

            //EscMenuID=父菜單層所對應(yīng)的菜單ID,ID=999為菜單已經(jīng)到頂了

            //DownMenuID=弟菜單層所對應(yīng)的菜單ID,ID=999為菜單是獨生子

            //UpMenuID=兄菜單層所對應(yīng)的菜單ID,ID=999為菜單是獨生子

            //CurFunction=本菜單所對應(yīng)的菜單函數(shù)指針

            const struct KeyTabStruct KeyTab[MAX_KEYTABSTRUCT_NUM]={

            //CurMenuID,axMenuItem,MenuShowLevel,OkMenuID,EscMenuID,DownMenuID,UpMenuID,CurFunction

            {MENU_EDIT,0,0,MENU_DATA_VIEW,MENU_NO,MENU_NO,MENU_NO,*MenuEdit},

            {MENU_DATA_VIEW,3,1,MENU_DATA_VIEW_FIRE,MENU_EDIT,MENU_SYS_EDIT,MENU_PRINT_DATA,*MenuEdit},

            {MENU_DATA_VIEW_FIRE,5,MENU_NO,MENU_NO,MENU_DATA_VIEW,MENU_DATA_VIEW_TROUBLE, MENU_STEP_FOLLOW, *MenuDataViewIn},

            {MENU_DATA_VIEW_TROUBLE, 5,MENU_NO,MENU_NO,MENU_DATA_VIEW,MENU_DATA_VIEW_REPEAT,MENU_DATA_VIEW_FIRE,*MenuDataViewIn},

            {MENU_DATA_VIEW_REPEAT,5,MENU_NO,

            MENU_NO,MENU_DATA_VIEW,MENU_FACE_CHECK,

            MENU_DATA_VIEW_TROUBLE,*MenuDataViewIn},

            {MENU_FACE_CHECK,5,MENU_NO,

            MENU_NO,MENU_DATA_VIEW,MENU_STEP_FOLLOW,

            MENU_DATA_VIEW_REPEAT,*MenuFaceCheck},

            {MENU_STEP_FOLLOW,5,MENU_NO,

            MENU_NO,MENU_DATA_VIEW,MENU_DATA_VIEW_FIRE,MENU_FACE_CHECK,

            *MenuStepFollow},

            {MENU_SYS_EDIT,3,

            2,MENU_SUM_SET,MENU_EDIT,

            MENU_PRINT_DATA,MENU_DATA_VIEW,*MenuEdit},

            {MENU_SUM_SET,6,MENU_NO,

            MENU_NO,MENU_SYS_EDIT,MENU_EDIT_INSULATE,

            MENU_TIME_SET,*MenuSumSet},

            {MENU_EDIT_INSULATE,6,MENU_NO,

            MENU_NO,MENU_SYS_EDIT,MENU_EDIT_HZ,MENU_SUM_SET,

            *MenuEditInsulate},

            {MENU_EDIT_HZ,6,MENU_NO,

            MENU_NO,MENU_SYS_EDIT,MENU_LD_CONTROL,

            MENU_EDIT_INSULATE,*MenuEditHZ},

            {MENU_LD_CONTROL,6,

            MENU_NO,MENU_NO,MENU_SYS_EDIT,MENU_LD_DELAY,

            MENU_EDIT_HZ,*MenuLDControl},

            {MENU_LD_DELAY,6,

            MENU_NO,MENU_NO,MENU_SYS_EDIT,MENU_TIME_SET,

            MENU_LD_CONTROL,*MenuLDDelay},

            {MENU_TIME_SET,6,MENU_NO,

            MENU_NO,MENU_SYS_EDIT,MENU_SUM_SET,MENU_LD_DELAY,

            *MenuTimeSet},

            {MENU_PRINT_DATA,3,3,

            MENU_PRINT_DATA_FIRE,MENU_EDIT,MENU_DATA_VIEW,

            MENU_SYS_EDIT,*MenuEdit},

            {MENU_PRINT_DATA_FIRE,4,

            MENU_NO,MENU_NO,MENU_PRINT_DATA,

            MENU_PRINT_DATA_TROUBLE,MENU_PRINT_SET,*MenuPrintDataIn},

            {MENU_PRINT_DATA_TROUBLE,4,MENU_NO,

            MENU_NO,MENU_PRINT_DATA,MENU_PRINTER_CHECK,

            MENU_PRINT_DATA_FIRE,*MenuPrintDataIn},

            {MENU_PRINTER_CHECK,4,MENU_NO,

            MENU_NO,MENU_PRINT_DATA,MENU_PRINT_SET,

            MENU_PRINT_DATA_TROUBLE,*MenuPrintDataIn},

            {MENU_PRINT_SET,4,MENU_NO,

            MENU_NO,MENU_PRINT_DATA,MENU_PRINT_DATA_FIRE,

            MENU_PRINTER_CHECK,*MenuPrintSet},

            };

            const struct MenuDispDataMenuEditShow[][MENU_MAX] = {

            {{MENU_NO, 0, 0, "選擇:消音→退出"},//主菜單

            {MENU_DATA_VIEW, 1, 6, "⒈數(shù)據(jù)查看"},

            {MENU_SYS_EDIT, 2, 6, "⒉系統(tǒng)編程"},

            {MENU_PRINT_DATA, 3, 6, "⒊數(shù)據(jù)打印"}},

            {{MENU_NO, 0, 0, "數(shù)據(jù)查看:消音→退出"},//數(shù)據(jù)查

            {MENU_DATA_VIEW_FIRE, 1, 4, "⒈火警"},

            {MENU_DATA_VIEW_TROUBLE, 2, 4, "⒉故障"},

            {MENU_DATA_VIEW_REPEAT , 3, 4, "⒊重碼"},

            {MENU_FACE_CHECK, 1,12, "⒋面板檢測"},

            {MENU_STEP_FOLLOW, 2,12, "⒌單步跟蹤"}},

            {{MENU_NO, 0, 0, "系統(tǒng)編程:消音→退出"},//系統(tǒng)編程

            {MENU_SUM_SET, 1, 0, "⒈容量設(shè)置"},

            {MENU_EDIT_INSULATE, 2, 0, "⒉隔離點"},

            {MENU_EDIT_HZ, 3, 0, "⒊漢字描述"},

            {MENU_LD_CONTROL, 1,12, "⒋聯(lián)動控制"},

            {MENU_LD_DELAY, 2,12, "⒌模塊延時"},

            {MENU_TIME_SET, 3,12, "⒍時鐘調(diào)整"}},

            {{MENU_NO, 0, 0, "數(shù)據(jù)打印:消音→退出"},//數(shù)據(jù)打印

            {MENU_PRINT_DATA_FIRE, 1, 0, "⒈火警數(shù)據(jù)"},

            {MENU_PRINT_DATA_TROUBLE,2, 0, "⒉故障數(shù)據(jù)"},

            {MENU_PRINTER_CHECK, 3, 0, "⒊打印機自檢"},

            {MENU_PRINT_SET, 1,12, "⒋打印設(shè)置"}},

            };

            void WaitKey(void)

            {

            uint32 time;

            time = RTCFlag;

            WhichKey = KEY_NONE;

            while(!EscFlag){

            if(RTCFlag - time >= EDIT_TIME)

            EscFlag = TRUE;

            if(WhichKey != KEY_NONE){

            KeySound(300);//按鍵音

            return;

            }

            }

            }

            void MenuEdit()

            {

            uint32 i,j=0;

            uint32 oldid;

            j = KeyTab[MenuID].ShowLevel;

            if(WhichKey == KEY_ESC || WhichKey == KEY_OK){

            ClearScreen();

            for(i=0;i

            ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j]

            [i].Column,MenuEditShow[j][i].Pdata,0);//初始化顯示

            oldid =

            0;

            //沒有原先選擇的項

            }else{

            if(WhichKey == KEY_UP)

            oldid = KeyTab[MenuNextID].PressDown;

            else

            oldid = KeyTab

            [MenuNextID].PressUp;

            //指示原先的項

            }

            for(i=1;i

            if(MenuEditShow[j][i].Id == oldid)

            ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j]

            [i].Column,MenuEditShow[j][i].Pdata,0);//正常顯示原先的項

            else{

            if(MenuEditShow[j][i].Id == MenuNextID)

            ShowString(MenuEditShow[j][i].Lin,MenuEditShow

            [j][i].Column,MenuEditShow[j][i].Pdata,1);//反顯當前選擇的項

            }

            }

            WhichKey = KEY_NONE;

            }

            uint32 Edit(void)

            {

            struct KeyTabStruct NowKeyTab;//指示當前的菜單值

            uint32 escflag = FALSE;

            ResetFlag = FALSE;

            ChangeFlag = FALSE;

            EscFlag = FALSE;

            MenuID = MENU_EDIT;

            NowKeyTab = KeyTab[MenuID];

            MenuNextID = NowKeyTab.PressOk;

            (*NowKeyTab.CurrentOperate)();//顯示主菜單

            do{

            if(WhichKey == KEY_NONE)

            WaitKey();//等待按鍵

            switch(WhichKey){

            case KEY_ESC : if(NowKeyTab.PressEsc != MENU_NO)

            {

            MenuID =

            NowKeyTab.PressEsc;

            MenuNextID =

            NowKeyTab.MenuIndex;

            NowKeyTab = KeyTab

            [MenuID];

            NowKeyTab.PressOk =

            MenuNextID;

            (*NowKeyTab.CurrentOperate)

            ();//顯示當前菜單

            }else

            escflag =

            TRUE;//退出編程狀態(tài)

            break;

            case KEY_OK:if(NowKeyTab.PressOk != MENU_NO)

            {

            MenuID =

            NowKeyTab.PressOk;

            NowKeyTab = KeyTab

            [MenuID];

            MenuNextID =

            NowKeyTab.PressOk;

            }

            (*NowKeyTab.CurrentOperate)

            ();//執(zhí)行當前按鍵的操作

            break;

            case KEY_UP:if((MenuNextID != MENU_NO) &&

            (KeyTab[MenuNextID].PressUp != MENU_NO)){

            NowKeyTab.PressOk =

            KeyTab[MenuNextID].PressUp;

            MenuNextID = KeyTab

            [MenuNextID].PressUp;

            (*NowKeyTab.CurrentOperate)();//執(zhí)行當前按鍵的操作

            }

            break;

            case KEY_DOWN:if((MenuNextID != MENU_NO) &&

            (KeyTab[MenuNextID].PressDown != MENU_NO)){

            NowKeyTab.PressOk =

            KeyTab[MenuNextID].PressDown;

            MenuNextID = KeyTab

            [MenuNextID].PressDown;

            (*NowKeyTab.CurrentOperate)();//執(zhí)行當前按鍵的操作

            }

            break;

            case KEY_RESET: ResetFlag = TRUE;

            break;

            default: break;

            }

            }while(!ResetFlag && !EscFlag && !escflag);

            if(ChangeFlag && !EscFlag && !ResetFlag)

            EditDataChange();

            if(ResetFlag)

            returnSYS_RESET;

            else{

            return0;

            }

            }

            關(guān)于這個菜單的說明:

            1.我用的是ARM處理器,所以51的時候把const改成code,uint32改成unsigned char。

            2.在網(wǎng)上的資料中,結(jié)構(gòu)體數(shù)組是存在RAM中的,我把它放在也flash中了,然后再定義一個

            結(jié)構(gòu)體變量,就樣就可以省很多RAM,比較適合51.

            3.在網(wǎng)上資料中,因為保存了原來的選擇,當你離開編程狀態(tài)重新進行后,會發(fā)現(xiàn)選擇上會

            是原來進行的順序,我改動之后,退出上一級菜單還是你選的那一項,但重新進入后就是第

            一個指定項。

            4.增加UP和DOWN顯示,可以反顯最新選定的選項,正常顯示原來的選項。



            關(guān)鍵詞: 單片機多級菜單編程實

            評論


            技術(shù)專區(qū)

            關(guān)閉