| 
  |||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe  | 
  
請教一個關(guān)于程序結(jié)構(gòu)的問題 | 
  
| 作者:七月飛雪 欄目:單片機 | 
要用MEGA16寫一個程序,用于人機界面,控制液晶和鍵盤。主菜單下可能包含幾級子菜單。我的思路是每個子菜單用一個函數(shù)來實現(xiàn),在進入某個菜單后程序一直在該函數(shù)里循環(huán),直到有外部事件觸發(fā)(比如鍵盤)才退回上級或進入下級菜單。鍵盤的詢檢也是放在各個子函數(shù)里的。 可是我的同事和我的意見相左。他把鍵盤詢檢和液晶顯示的程序都放在主函數(shù)里,當(dāng)檢查到某個按鍵按下時要根據(jù)系統(tǒng)當(dāng)前的狀態(tài)來判斷下面系統(tǒng)應(yīng)該進入哪種狀態(tài)。其實就是針對每個子菜單起碼要設(shè)一個狀態(tài)碼。我覺得這樣的話寫程序時可能會把邏輯搞亂了,而且別人讀程序的話可能也比較費勁。 我自己的方法也有問題就是程序里的嵌套和循環(huán)比較多,如果菜單級數(shù)越多那我的嵌套也就越多了。 請問大家是怎么想的?謝謝!  | 
  
| 2樓: | >>參與討論 | 
| 作者: zhaoruixbj 于 2007/1/16 17:13:00 發(fā)布:
         還是聽你同事的吧. 把鍵盤詢檢和液晶顯示的程序都放在主函數(shù)里,當(dāng)檢查到某個按鍵按下時要根據(jù)系統(tǒng)當(dāng)前的狀態(tài)來判斷下面系統(tǒng)應(yīng)該進入哪種狀態(tài)。其實就是針對每個子菜單起碼要設(shè)一個狀態(tài)碼 這就跟FPGA里面似的,做成狀態(tài)機,一個主循環(huán),根據(jù)判斷狀態(tài)碼轉(zhuǎn)移. 比較好擴展和維護  | 
  |
| 3樓: | >>參與討論 | 
| 作者: 七月飛雪 于 2007/1/16 17:38:00 發(fā)布:
         擴展和維護么? 我知道PCI協(xié)議的狀態(tài)機,可是那個狀態(tài)比較少啊 我們這個,比如說我按下一個enter鍵或者數(shù)字鍵,程序得判斷當(dāng)前是哪個菜單下的第幾個條目,因為我同級菜單下可能還要翻屏的,這樣的話狀態(tài)太多了,很容易搞錯了的呀 而且可讀性應(yīng)該不怎么樣,因為我讀過他之前的一個程序,只有4個按鍵,沒有液晶,讀起來比較吃力,因為一個按鍵按下之后還要判斷之前的按鍵是什么,開始都不明白是什么意思,看不懂他程序的流程。 按我自己的方式我可以很容易知道這是第幾級菜單,它的上一級或下一級是什么。我覺得要擴展的話應(yīng)該也蠻容易的呀。 不知道是不是我自己一葉障目,歡迎大家提意見,謝謝!  | 
  |
| 4樓: | >>參與討論 | 
| 作者: su_mj000 于 2007/1/17 1:37:00 發(fā)布:
         我倒是覺得LZ的想法更好一點 液晶顯示和鍵盤掃描應(yīng)該是公用函數(shù)/程序,獨立于 各菜單(同一個按鍵在不同的菜單里可有不同的定義)。 令外,每個菜單進入和返回可用鏈?zhǔn)蕉褩1Wo/恢復(fù) 上一級菜單。 這樣做的好處是容易擴展,模塊之間牽連少。壞處可 能是耗費內(nèi)存多些。  | 
  |
| 5樓: | >>參與討論 | 
| 作者: 七月飛雪 于 2007/1/17 17:37:00 發(fā)布:
         謝謝回復(fù) 一開始被要求按照別人的想法重寫程序時心里的抵觸情緒很強 現(xiàn)在冷靜下來覺得兩種方法各有各的優(yōu)缺點,他的程序結(jié)構(gòu)干凈,我的呢,可讀性要好一些 但是我還是覺得同事的方法適合寫簡單的程序,復(fù)雜一些的應(yīng)該寫起來比較累吧  | 
  |
| 6樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/17 17:46:00 發(fā)布:
         呵呵 建議采用你的方式,但也不完全和你的一樣。就是阻塞在每個調(diào)用函數(shù)里面,這樣問題比較容易處理,特別是沒有os的系統(tǒng)。 對應(yīng)菜單這里有一個我自己寫的,可以參考 void SuperMenu(unsigned CHAR ucMenuItemNum, // menu total num unsigned CHAR ucStartLineNo, // first menu ITEM row pos 1 unsigned CHAR ucEndLineNo, // last menu ITEM row pos 3 unsigned LONG ulWaitKeyTimeOut, // wait key timeout unsigned CHAR ucKeySoundOpen, // key beep SWITCH unsigned CHAR ucDectectCard, // return from menu if card present CHAR *pMenuTitle, // menu main title CHAR *MenuText[], // menu ITEM content void (*function[])(void)) // menu ITEM function { unsigned CHAR ucItemNumPerScr; // menu ITEM num per screen unsigned CHAR i,j,ucRnt, // ucLastScrLineNum, // menu ITEM num in last screen ucScrNum, // menu screen num ucCurScr, // current screen ucCurLine; // current row unsigned LONG ulDelay; unsigned CHAR ucShowMargin; ucItemNumPerScr = ucEndLineNo - ucStartLineNo + 1; UpdateFace(); lcd_disp(0, 0, "", LCD_CLS); ucCurLine = 0; ucCurScr = 0; ulDelay = ulWaitKeyTimeOut; ucShowMargin = 1; ucScrNum = ucMenuItemNum / ucItemNumPerScr; ucLastScrLineNum = ucMenuItemNum % ucItemNumPerScr; if(ucLastScrLineNum) ucScrNum ++; else ucLastScrLineNum = ucItemNumPerScr; // while(1) { if(ucShowMargin) { lcd_disp(0, 0, (CHAR *)pMenuTitle, NULL); ucShowMargin = 0; } // disp a screen info for(i=0; i<ucItemNumPerScr; i++) { j = ucCurScr*ucItemNumPerScr+i; if( j>(ucMenuItemNum-1) ) { lcd_disp((ucStartLineNo+i) * 2 , 0, " ", NULL); continue; } if(i == ucCurLine) lcd_disp((ucStartLineNo+i)*2, 0, MenuText[j], LCD_REVERT); else lcd_disp((ucStartLineNo+i)*2, 0, MenuText[j], 0);  | 
  |
| 7樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/17 17:48:00 發(fā)布:
         呵呵 建議你參考我的菜單函數(shù)參數(shù)設(shè)置,他可以嵌套調(diào)用,調(diào)用方便,而且條理清楚。給足夠的靈活性。 void SuperMenu(unsigned CHAR ucMenuItemNum, // menu total num unsigned CHAR ucStartLineNo, // first menu ITEM row pos 1 unsigned CHAR ucEndLineNo, // last menu ITEM row pos 3 unsigned LONG ulWaitKeyTimeOut, // wait key timeout unsigned CHAR ucKeySoundOpen, // key beep SWITCH unsigned CHAR ucDectectCard, // return from menu if card present CHAR *pMenuTitle, // menu main title CHAR *MenuText[], // menu ITEM content void (*function[])(void)); // menu ITEM function  | 
  |
| 8樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/17 17:49:00 發(fā)布:
         呵呵 // some SYSTEM config entrance void SYSTEMMenu(void) { unsigned CHAR sMenuTitle[]= " --Sys Config-- "; CHAR *menu[]={ {"① SYSTEM Ver "}, {"② DEVICE ID "}, {"③ Set Clock "}, {"④ Debug Menu "}, }; void (*function[])(void) = { ShowSysVer, SetDEVICEID, SetClock, DebugMenu, }; SuperMenu( 4, // menu num 1, // first row pos 1 3, // last row pos 3 0x8ffffL, // timeout TRUE, // key beep opern TRUE, sMenuTitle, menu, function); return; }  | 
  |
| 9樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/17 17:56:00 發(fā)布:
         呵呵 同時在一些阻塞函數(shù)里面還要循環(huán)調(diào)用(或者稱呼為 “象征性調(diào)用”)一個類似IdleSchedule()的函數(shù),這樣系統(tǒng)日程任務(wù)也可以得到執(zhí)行機會 void IdleSchedule(void) { ;; // if SD/MMC card inserted and save event status ;; // other schedule ;; // clock update .... } void SuperMenu() { ... while(true) { if(IdleSchedule()) return; if(!Getkey(&key)) continue(); SWITCH(key) { case 'KEY_ENGER': ... } } }  | 
  |
| 10樓: | >>參與討論 | 
| 作者: Bitfu 于 2007/1/17 22:47:00 發(fā)布:
         將問題拆分成容易理解的小部分后編碼 有助于維護和閱讀!  | 
  |
| 11樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/18 9:20:00 發(fā)布:
         呵呵 你如果不是用一個GUI系統(tǒng)(包括自己寫的小的GUI),而把所有窗口,界面的輸入輸出操作都放在一個地方來統(tǒng)一處理,如果沒有好的組織方式,很難看清楚,看起代碼來很麻煩. mfc的那些什么OnClick..() 之類的事件響應(yīng)函數(shù)就是一些組織方式,讓你只需要填充簡單的宏,來安裝你的響應(yīng)事件的響應(yīng)函數(shù),至于這個函數(shù)怎么和事件對應(yīng)起來,怎么被調(diào)用,這部分代碼是不需要看到的,這個包裝工作也是巧妙的.  | 
  |
| 12樓: | >>參與討論 | 
| 作者: 七月飛雪 于 2007/1/18 10:21:00 發(fā)布:
         謝謝大家 謝謝robin_ee的熱心回復(fù) 不過因為這是我用C寫的第一個程序,對于GUI,MFC等等還不是很熟悉(新手上路:)) 要學(xué)習(xí)的東西太多了。。。  | 
  |
| 13樓: | >>參與討論 | 
| 作者: robin_ee 于 2007/1/18 11:03:00 發(fā)布:
         呵呵 如果你要了解GUI,特別是嵌入式的GUI,可以先到windows上面去熏陶,windows的GUI是很成熟的,去感化一點點就不錯了.建議安裝一個vc6.0,寫基于win32 API的程序,里面會展示最簡單的win32程序,消息系統(tǒng).  | 
  |
| 14樓: | >>參與討論 | 
| 作者: wenlw 于 2007/1/20 17:10:00 發(fā)布:
         robin_ee 的寫法是參照UC/OS的寫法,這樣較好! robin_ee 的寫法是參照UC/OS的寫法,這樣較好!且實時性較強.  | 
  |
| 15樓: | >>參與討論 | 
| 作者: 七月飛雪 于 2007/1/22 11:33:00 發(fā)布:
         嘿 我現(xiàn)在還是按照原來的思路在寫,已經(jīng)可以在線編輯了,可以進行各種參數(shù)的設(shè)置和修改 robin_ee的寫法我會好好學(xué)習(xí)的:)  | 
  |
| 16樓: | >>參與討論 | 
| 作者: ayb_ice 于 2007/3/7 11:14:00 發(fā)布:
         隨便說說 你的思路要好一些,不用管理復(fù)雜的狀態(tài)編碼,更重要的是修改方便,我也是這樣做的,只是把掃鍵顯示等程序放在定時中斷中處理更好.  | 
  |
  | 
    
 
  | 
  
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 | 
Copyright © 1998-2006 udpf.com.cn 浙ICP證030469號  |