新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機的程序框架

        單片機的程序框架

        作者: 時間:2016-11-28 來源:網絡 收藏

        INT8U ChkRxFrame(void)
        {
        INT8Udat;
        INT8Ucnt;
        INT8Usum;
        INT8Uret;
        ret =RX_NULL;
        if (RxBufCnt != 0){
        RxTimer = 0; //清接收計數時間,UARTimeEvent()中對于接收超時做了放棄整幀數據的處理
        //Display();
        cnt = RxCnt;
        dat = RxBuf[RxBufRdIdx];// Get Char
        if (++RxBufRdIdx == RX_BUFFER_SIZE)
        RxBufRdIdx = 0;
        Cli();
        --RxBufCnt;
        Sei();
        FrameBuf[cnt++] = dat;
        if (cnt >= FRAME_LEN)// 組成一幀
        {
        sum = 0;
        for (cnt = 0;cnt < (FRAME_LEN - 1);cnt++)
        sum+= FrameBuf[cnt];
        if (sum == dat)
        ret = FrameBuf[0];
        cnt = 0;
        }
        RxCnt = cnt;
        }
        return ret;
        }
        以上的代碼ChkRxFrame()可以放于串口接收數據處理函數RxProcess() 中,然后放入主循環中執行即可。以上用一個計時變量RxTimer,很微妙的解決了接收幀超時的放棄幀處理,它沒有用任何等待,而且主循環中每次只是接收一個字節數據,時間很短。


        我們開始架構整個系統的框架:
        我們選用一個系統不常用的TIMER來產生系統所需的系統基準節拍,這里我們選用4ms;
        在meg8中我們代碼如下:
        // Timer 0 overflow interrupt service routine
        interrupt [TIM0_OVF] void timer0_ovf_isr(void)
        {
        // Reinitialize Timer 0 value
        TCNT0=0x83;
        // Place your code here
        if ((++Time1ms & 0x03) == 0)
        TimeIntFlg = 1;
        }
        然后我們設計一個TimeEvent()函數,來調用一些在以指定的頻率需要循環調用的函數,
        比如每個4ms我們就進行喂狗以及數碼管動態掃描顯示,每隔1s我們就調用led閃爍程序,每隔20ms我們進行鍵盤掃描程序;
        void TimeEvent (void)
        {
        if (TimeIntFlg){
        TimeIntFlg = 0;
        ClearWatchDog();
        display(); // 在4ms事件中,調用LED掃描顯示,以及喂狗
        if (++Time4ms > 5){
        Time4ms = 0;
        TimeEvent20ms();//在20ms事件中,我們處理鍵盤掃描read_keyboard_FUN2()

        if (++Time100ms > 10){
        Time100ms = 0;
        TimeEvent1Hz();// 在1s事件中,我們使工作指示燈閃爍
        }
        }
        UARTimeEvent();//串口的數據接收事件,在4ms事件中處理
        }
        }
        顯然整個思路已經很清晰了,cpu需要處理的循環事件都可以根據其對于時間的要求很方便的加入該函數中。但是我們對這事件有要求:
        執行速度快,簡短,不能有太長的延時等待,其所有事件一次執行時間和必須小于系統的基準時間片4ms(根據需要可以加大系統基準節拍)。所以我們的鍵盤掃描程序,數碼管顯示程序,串口接收程序都如我先前所示。如果逼不得已需要用到較長的延時(如模擬IIc時序中用到的延時)
        我們設計了這樣的延時函數:
        void RunTime250Hz (INT8U delay)//此延時函數的單位為4ms(系統基準節拍)
        {
        while (delay){
        if (TimeIntFlg){
        --delay;
        TimeEvent();
        }
        TxProcess();
        RxProcess();
        }
        }
        我們需要延時的時間=delay*系統記住節拍4ms,此函數就確保了在延時的同時,我們其它事件(鍵盤掃描,led顯示等)也并沒有被耽誤;

        好了這樣我們的主函數main()將很簡短:
        Void main (voie)
        {
        Init_all();
        while (1)
        {
        TimeEvent(); //對于循環事件的處理
        RxProcess();//串口對接收的數據處理
        TxProcess();// 串口發送數據處理

        }
        }
        整體看來我們的系統就成了將近一個萬能的模版了,根據自己所選的cpu,選個定時器,在添加自己的事件函數即可,非常靈活方便實用,一般的單片機能勝任的場合,該模版都能搞定。
        整個系統以全局標志作為主線,形散神不散;系統耗費比較小,只是犧牲了一個Timer而已,在資源缺乏的單片機中,非常適;曾經看過一個網友的模版“單片機實用系統”,其以51為例子寫的,整體思路和這個差不多,不過他寫得更為規范緊湊,非常欣賞;但個人覺得代碼開銷量要大些,用慣了都一樣哦。但是由于本系統以全局標志為驅動事件,所以比較感覺比較凌亂,全局最好都做好注釋,而其要注意一些隱形的函數遞歸情況,千萬不要遞歸的太深哦(有的單片機不支持)。
        單片機使用系統
        外鏈1 http://bbs.elecfans.com/jishu_209334_1_1.html21IC的,有介紹,貌似下載鏈接失效了
        外鏈2 http://download.csdn.net/detail/my_automation/5069829#commentCSDN的下載鏈接

        上一頁 1 2 3 下一頁

        關鍵詞: 單片機程序框

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 焦作市| 宁海县| 内江市| 文水县| 新巴尔虎左旗| 阳泉市| 和平县| 翼城县| 临沧市| 平顶山市| 哈尔滨市| 宜州市| 佛冈县| 新津县| 林西县| 兴安盟| 北安市| 改则县| 江源县| 安远县| 天长市| 闽清县| 南安市| 万宁市| 马鞍山市| 仪陇县| 鱼台县| 乐平市| 彰武县| 铁岭县| 理塘县| 磐安县| 阿坝| 沅陵县| 房产| 阳谷县| 务川| 通辽市| 兴安县| 东乡族自治县| 临桂县|