<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于51單片機(jī)中C語言編寫的精確延時(shí)函數(shù)

          關(guān)于51單片機(jī)中C語言編寫的精確延時(shí)函數(shù)

          作者: 時(shí)間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
          有些特殊的應(yīng)用會(huì)用到比較精確的延時(shí)(比如DS18B20等),而C不像匯編,延時(shí)精準(zhǔn)度不好算。本人經(jīng)過反復(fù)調(diào)試,對(duì)照KEIL編譯后的匯編源文件,得出了以下幾條精確延時(shí)的語句(絕對(duì)精確!本人已通過實(shí)際測(cè)試),今天貼上來,希望對(duì)需要的朋友有所幫助
          sbit LED = P1^0; // 定義一個(gè)管腳(延時(shí)測(cè)試用)
          unsigned int i = 3; // 注意i,j的數(shù)據(jù)類型,
          unsigned char j = 3; // 不同的數(shù)據(jù)類型延時(shí)有很大不同
          //-----------------各種精確延時(shí)語句-----------------------------------
          while( (i--)!=1 ); // 延時(shí)10*i個(gè)機(jī)器周期
          i = 10; while( --i ); // 延時(shí)8*i+2個(gè)機(jī)器周期
          i = 10; while( i-- ); // 延時(shí)(i+1)*9+2個(gè)機(jī)器周期
          j = 5; while( --j ); // 延時(shí)2*j+1個(gè)機(jī)器周期
          j = 5; while( j-- ); // 延時(shí)(j+1)*6+1個(gè)機(jī)器周期

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

          i = 5;
          while( LED ) // 每隔10個(gè)機(jī)器周期檢測(cè)一次LED管腳狀態(tài),當(dāng)LED
          if( (--i)==0 ) break;// 為低時(shí)或者到了10*i+2個(gè)機(jī)器周期時(shí)跳出延時(shí)
          //--------------------------------------------------------------------

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


          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();