<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        C語言精確延時方法

        作者:西西   來源:本站原創   點擊數:  更新時間:2014年04月05日   【字體:

        有些特殊的應用會用到比較精確的延時(比如DS18B20等),而C不像匯編,延時精準度不好算。本人經過反復調試,對照KEIL編譯后的匯編源文件,得出了以下幾條精確延時的語句(絕對精確!本人已通過實際測試),今天貼上來,希望對需要的朋友有所幫助。

        sbit LED = P1^0; // 定義一個管腳(延時測試用)
        unsigned int i = 3; // 注意i,j的數據類型,
        unsigned char j = 3; // 不同的數據類型延時有很大不同
        //-----------------各種精確延時語句-----------------------------------
        while( (i--)!=1 ); // 延時10*i個機器周期
        i = 10; while( --i ); // 延時8*i+2個機器周期
        i = 10; while( i-- ); // 延時(i+1)*9+2個機器周期
        j = 5; while( --j ); // 延時2*j+1個機器周期
        j = 5; while( j-- ); // 延時(j+1)*6+1個機器周期

        i = 5;
        while( --i ) // 延時i*10+2個機器周期,在i*10+2個機器周期
        if( LED==0 ) break; // 內檢測到LED管腳為低電平時跳出延時

        i = 5;
        while( LED ) // 每隔10個機器周期檢測一次LED管腳狀態,當LED
        if( (--i)==0 ) break;// 為低時或者到了10*i+2個機器周期時跳出延時
        //--------------------------------------------------------------------

        例如18b20的復位函數(12M晶振):
        //***********************************************************************
        // 函數功能:18B20復位
        // 入口參數:無
        // 出口參數:unsigned char x: 0:成功 1:失敗
        //***********************************************************************
        unsigned char ow_reset(void)
        {
        unsigned char x=0; // 12M晶振 1個機器周期為1us
        DQ = 1; // DQ復位
        j = 10; while(--j);// 稍做延時(延時10*2+1=21個機器周期,21us)
        DQ = 0; // 單片機將DQ拉低
        j = 85; while(j--);// 精確延時(大于480us) 85*6+1=511us
        DQ = 1; // 拉高總線
        j = 10; while(j--);// 精確延時10*6+1=61us
        x = DQ; // 稍做延時后,
        return x; // 如果x=0則初始化成功 x=1則初始化失敗
        j = 25; while(j--);// 精確延時25*6+1=151us
        }
        //*********************************************************************************
        再如紅外解碼程序:
        (先說傳統紅外解碼的弊端:
        程序中用了while(IR_IO);while(!IR_IO);這樣的死循環,如果管腳一直處于一種狀態,就會一直執行while,造成“死機”現象。當然這種情況很少,但我們也的考慮到。而用以下程序則不會,在規定的時間內沒有正確的電平信號就會返回主程序,這樣就不會出現“死機”了)
        //***************************外部中斷0*******************************
        void int0(void) interrupt 0
        {
        unsigned char i,j;
        unsigned int count = 800;
        //--------------8.5ms低電平引導碼-------------------------------------
        while( --count )
        if( IR_IO==1 ) return; // 在小于8ms內出現高電平,返回
        count = 100; // 延時1ms
        while( !IR_IO ) // 等待高電平
        if( (--count)==0 ) return; // 在9ms內未出現高電平,返回
        //-------------4.5ms高電平引導碼------------------------------------
        count = 410; // 延時4.1ms
        while( --count ) // ...
        if( IR_IO==0 ) return; // 在4.1ms內出現低電平,返回
        count = 50; // 延時0.5ms
        while( IR_IO ) // 等待低電平
        if( (--count)==0 ) return; // 在4.7ms內未出現低電平,返回
        //-----------------------------------------------------------------
        //------------4個數據碼------------------------------------
        for( j=0;j<4;j++ )
        {
        for( i=0;i<8;i++ )
        {
        IR_data[j] <<= 1; // 裝入數據
        count = 60; // 延時0.6ms
        while( !IR_IO ) // 等待高電平
        if( (--count)==0 ) return; // 在0.6ms內未出現高電平,返回
        count = 40; // 低電平結束,繼續
        while( --count ) // 延時0.4ms
        if( IR_IO==0 ) return; // 在0.4ms內出現低電平,返回
        count = 100; // 延時1.4ms
        while( IR_IO ) // 檢測IO狀態
        if( (--count)==0 ) // 等待1.4ms到來
        { // 在1.4ms內都是高電平
        IR_data[j] |= 1; // 兩個單位高電平,為數據1
        break; // 跳出循環
        }
        count = 20; // 延時0.2ms
        while( IR_IO ) // 等待低電平跳出
        if( (--count)==0 ) return; // 0.2ms內未出現低電平,返回
        }
        }
        //-------------------------------------------------------------------
        flag_IR = 1; // 置位紅外接收成功標志
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮