最新免费av在线观看,亚洲综合一区成人在线,中文字幕精品无码一区二区三区,中文人妻av高清一区二区,中文字幕乱偷无码av先锋

登錄 免費注冊 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術(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)的問題

作者:七月飛雪 欄目:單片機
請教一個關(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
還是聽你同事的吧.
   把鍵盤詢檢和液晶顯示的程序都放在主函數(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樓: >>參與討論
七月飛雪
擴展和維護么?
我知道PCI協(xié)議的狀態(tài)機,可是那個狀態(tài)比較少啊
我們這個,比如說我按下一個enter鍵或者數(shù)字鍵,程序得判斷當(dāng)前是哪個菜單下的第幾個條目,因為我同級菜單下可能還要翻屏的,這樣的話狀態(tài)太多了,很容易搞錯了的呀
而且可讀性應(yīng)該不怎么樣,因為我讀過他之前的一個程序,只有4個按鍵,沒有液晶,讀起來比較吃力,因為一個按鍵按下之后還要判斷之前的按鍵是什么,開始都不明白是什么意思,看不懂他程序的流程。
按我自己的方式我可以很容易知道這是第幾級菜單,它的上一級或下一級是什么。我覺得要擴展的話應(yīng)該也蠻容易的呀。
不知道是不是我自己一葉障目,歡迎大家提意見,謝謝!

4樓: >>參與討論
su_mj000
我倒是覺得LZ的想法更好一點
液晶顯示和鍵盤掃描應(yīng)該是公用函數(shù)/程序,獨立于
各菜單(同一個按鍵在不同的菜單里可有不同的定義)。
令外,每個菜單進入和返回可用鏈?zhǔn)蕉褩1Wo/恢復(fù)
上一級菜單。

這樣做的好處是容易擴展,模塊之間牽連少。壞處可
能是耗費內(nèi)存多些。

5樓: >>參與討論
七月飛雪
謝謝回復(fù)
一開始被要求按照別人的想法重寫程序時心里的抵觸情緒很強
現(xiàn)在冷靜下來覺得兩種方法各有各的優(yōu)缺點,他的程序結(jié)構(gòu)干凈,我的呢,可讀性要好一些
但是我還是覺得同事的方法適合寫簡單的程序,復(fù)雜一些的應(yīng)該寫起來比較累吧

6樓: >>參與討論
robin_ee
呵呵
建議采用你的方式,但也不完全和你的一樣。就是阻塞在每個調(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
呵呵
建議你參考我的菜單函數(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
呵呵
// 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
呵呵
同時在一些阻塞函數(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
將問題拆分成容易理解的小部分后編碼
有助于維護和閱讀!

11樓: >>參與討論
robin_ee
呵呵
你如果不是用一個GUI系統(tǒng)(包括自己寫的小的GUI),而把所有窗口,界面的輸入輸出操作都放在一個地方來統(tǒng)一處理,如果沒有好的組織方式,很難看清楚,看起代碼來很麻煩.
mfc的那些什么OnClick..() 之類的事件響應(yīng)函數(shù)就是一些組織方式,讓你只需要填充簡單的宏,來安裝你的響應(yīng)事件的響應(yīng)函數(shù),至于這個函數(shù)怎么和事件對應(yīng)起來,怎么被調(diào)用,這部分代碼是不需要看到的,這個包裝工作也是巧妙的.


12樓: >>參與討論
七月飛雪
謝謝大家
謝謝robin_ee的熱心回復(fù)
不過因為這是我用C寫的第一個程序,對于GUI,MFC等等還不是很熟悉(新手上路:))
要學(xué)習(xí)的東西太多了。。。

13樓: >>參與討論
robin_ee
呵呵
如果你要了解GUI,特別是嵌入式的GUI,可以先到windows上面去熏陶,windows的GUI是很成熟的,去感化一點點就不錯了.建議安裝一個vc6.0,寫基于win32 API的程序,里面會展示最簡單的win32程序,消息系統(tǒng).


14樓: >>參與討論
wenlw
robin_ee 的寫法是參照UC/OS的寫法,這樣較好!
robin_ee 的寫法是參照UC/OS的寫法,這樣較好!且實時性較強.

15樓: >>參與討論
七月飛雪

我現(xiàn)在還是按照原來的思路在寫,已經(jīng)可以在線編輯了,可以進行各種參數(shù)的設(shè)置和修改
robin_ee的寫法我會好好學(xué)習(xí)的:)

16樓: >>參與討論
ayb_ice
隨便說說
你的思路要好一些,不用管理復(fù)雜的狀態(tài)編碼,更重要的是修改方便,我也是這樣做的,只是把掃鍵顯示等程序放在定時中斷中處理更好.

參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
有沒有那位仁兄那里有用IAR-C寫的應(yīng)用例程啊?
條件編譯問題
哪個軟件好用?
avr比51編譯效率高嗎?
剛接觸AVR單片機,有一個問題.
免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入


Copyright © 1998-2006 udpf.com.cn 浙ICP證030469號