分享一個(gè)產(chǎn)品級(jí)MCU菜單框架設(shè)計(jì)
聲明:本處所說(shuō)的菜單是用在128*64這種小屏幕的菜單,例如下面這種,不是彩屏上的GUI。
void test_main(void) { while(1) { get_key(&key); switch(key) { case 1: test_key(); break; case 2: test_lcd(); break; .... } } }
- 管得太寬 菜單,你就管菜單切換就行了,到了最低一層,也就是實(shí)際的測(cè)試功能,就不要管了。菜單切換是類(lèi)似的,實(shí)際測(cè)試都是不同的。比如在菜單中,按鍵1,是進(jìn)入第一個(gè)菜單。但是在測(cè)試中,按鍵1,功能都不一樣。如果菜單連這個(gè)也要管,相同動(dòng)作功能太多,無(wú)法進(jìn)行統(tǒng)一抽象,就很難模塊化。
- 出發(fā)點(diǎn)不一樣 上面說(shuō)到的菜單,出發(fā)點(diǎn)都是如何設(shè)計(jì)一個(gè)好的菜單數(shù)據(jù)結(jié)構(gòu),讓程序快速,高效運(yùn)行。我想要的卻是一個(gè)容易維護(hù)的菜單結(jié)構(gòu),至于菜單的代碼有多亂多糾結(jié),沒(méi)關(guān)系, 而且,幾百上千個(gè)菜單,就算用輪詢(xún)的方法,也不過(guò)幾百u(mài)s吧,沒(méi)關(guān)系。
/** * @brief 菜單對(duì)象 */ typedef struct _strMenu { MenuLel l; ///<菜單等級(jí) char cha[MENU_LANG_BUF_SIZE]; ///中文 char eng[MENU_LANG_BUF_SIZE]; ///英文 MenuType type; ///菜單類(lèi)型 s32 (*fun)(void); ///測(cè)試函數(shù) } MENU;
const MENU EMenuListTest[]= { MENU_L_0,//菜單等級(jí) "測(cè)試程序",//中文 "test", //英文 MENU_TYPE_LIST,//菜單類(lèi)型 NULL,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_1,//菜單等級(jí) "LCD",//中文 "LCD", //英文 MENU_TYPE_LIST,//菜單類(lèi)型 NULL,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "VSPI OLED",//中文 "VSPI OLED", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_oled,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "I2C OLED",//中文 "I2C OLED", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_i2coled,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_1,//菜單等級(jí) "聲音",//中文 "sound", //英文 MENU_TYPE_LIST,//菜單類(lèi)型 NULL,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "蜂鳴器",//中文 "buzzer", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_test,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "DAC音樂(lè)",//中文 "DAC music", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_test,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "收音",//中文 "FM", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_test,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_1,//菜單等級(jí) "觸摸屏",//中文 "tp", //英文 MENU_TYPE_LIST,//菜單類(lèi)型 NULL,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "校準(zhǔn)",//中文 "calibrate", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_cal,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_2,//菜單等級(jí) "測(cè)試",//中文 "test", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_tp,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 MENU_L_1,//菜單等級(jí) "按鍵",//中文 "KEY", //英文 MENU_TYPE_FUN,//菜單類(lèi)型 test_key,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 /*最后的菜單是結(jié)束菜單,無(wú)意義*/ MENU_L_0,//菜單等級(jí) "END",//中文 "END", //英文 MENU_TYPE_NULL,//菜單類(lèi)型 NULL,//菜單函數(shù),功能菜單才會(huì)執(zhí)行,有子菜單的不會(huì)執(zhí)行 };
----------------------------------------------- 根節(jié)點(diǎn) 第1個(gè)1級(jí)菜單 第1個(gè)子菜單 第2個(gè)子菜單 第3個(gè)子菜單 第2個(gè)1級(jí)菜單 第1個(gè)子菜單 第1個(gè)孫菜單 第2個(gè)孫菜單 第2個(gè)子菜單 第3個(gè)子菜單 第3個(gè)1級(jí)菜單 第4個(gè)1級(jí)菜單 第5個(gè)1級(jí)菜單 結(jié)束節(jié)點(diǎn) ------------------------------------------------
emenu_run(WJQTestLcd, (MENU *)&WJQTestList[0], sizeof(WJQTestList)/sizeof(MENU), FONT_SONGTI_1616, 2);
顯示效果
128*64 OLED
128*128 tft lcd
320*240 tft lcd
總結(jié)
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!