關於51單片機中C語言編寫的精確延時函數

2021-01-12 電子產品世界

有些特殊的應用會用到比較精確的延時(比如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; // 置位紅外接收成功標誌
}


相關焦點

  • 單片機C語言精確延時值的計算
    關於單片機C語言的精確延時,網上很多都是大約給出延時值沒有準確那值是多少,也就沒有達到精確高的要求,而51hei給出的本函數克服了以上缺點,能夠精確計數出要延時值且精確達到1us,本舉例所用CPU為STC12C5412系列12倍速的單片機,只要修改一下參數值其它系例單片機也通用
  • 單片機中C語言延時函數
    單片機C語言延時程序計算2009-11-02 22:15單片機C語言延時程序用C語言寫出來程序非常的簡練,它是一種模塊化的語言,一種比彙編更高級的語言,但是就是這樣一種語言也還是有它不足之處:它的延時很不好控制
  • 51單片機C語言延時函數
    C程序中可使用不同類型的變量來進行延時設計。經實驗測試,使用unsigned char類型具有比unsigned int更優化的代碼,在使用時應該使用unsigned char作為延時變量。
  • 單片機c語言中nop函數的使用方法和延時計算
    標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在彙編語言中很容易實現,寫幾個nop就行了。這個函數相當彙編NOP指令,延時幾微秒。同樣對於更長時間的延時,可以採用多重循環來完成。只要在程序設計循環語句時注意以上幾個問題。下面給出有關在C51中延時子程序設計時要注意的問題1、在C51中進行精確的延時子程序設計時,儘量不要或少在延時子程序中定義局部變量,所有的延時子程序中變量通過有參函數傳遞。
  • 單片機C語言延時分析
    標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在彙編語言中很容易實現,寫幾個nop就行了。
  • 51單片機教程之基礎編(基於C語言)
    很多初學者有很多的疑惑,我究竟是先學C語言,還是彙編語言?其實我告訴你,本人認為,先學C語言!為什麼呢?C語言是目前使用最廣泛的中級語言,就連現在的windows7也是C語言編寫的,C語言易讀性好,無需對單片機內部結構十分熟悉即會編程,可移植性高,便於維護。C語言只有32個關鍵字,9種控制語句,而且編譯器提供了很多函數庫,使用十分方便。
  • 編寫延時函數的簡單方法
    如果從keil裡看了c語言的反彙編代碼然後根據晶振和指令計算延時的時間這樣雖然非常的準確但是相當的麻煩而且容易搞錯,我這裡介紹一個最簡單的方法.可以驗證你的延時函數這裡用一個例程詳細介紹一下。此過程中需要注意,單片機晶振的選擇,因為for循環裡指令的執行時間和晶振有直接關係,本例中晶振使用11.0592M。
  • 51單片機C語言教程(四) 數據類型
    先來簡單說說C語言的標識符和關鍵字。標識符是用來標識源程序中某個對象的名字的,這些對象可以是語句、數據類型、函數、變量、數組等等。C語言是大小字敏感的一種高級語言,如果我們要定義一個定時器1,可以寫做"Timer1",如果程序中有"TIMER1",那麼這兩個是完全不同定義的標識符。
  • Keil C51程序設計中幾種精確延時方法
    實際的單片機應用系統開發過程中,由於程序功能的需要,經常編寫各種延時程序,延時時間從數微秒到數秒不等,對於許多C51開發者特別是初學者編制非常精確的延時程序有一定難度。
  • 單片機C語言模塊化編程方法
    模塊化程序設計應該理解以下概述:(1) 模塊即是一個.c 文件和一個.h 文件的結合,頭文件(.h)中是對於該模塊接口的聲明;這一條概括了模塊化的實現方法和實質:將一個功能模塊的代碼單獨編寫成一個.c文件,然後把該模塊的接口函數放在.h文件中.舉例:假如你用到液晶顯示,那麼你可能會寫一個液晶驅動模塊,以實現字符、漢字和圖像的現實,命名為: led_device.c,該模塊的.
  • PIC單片機C語言程序實例
    編者按:為了幫助具有PIC單片機彙編語言知識的技術人員或工程師,快速掌握利用C語言編寫PIC單片機程序的方法,本刊特推出《PIC單片機C語言程序設計》系列連載文章。丈中給出的C語言程序實例,均是可執行的,讀者可以放心引用。      一、彙編語言與C語言      早期的單片機程序多採用彙編語言編寫。
  • 用C51編寫單片機延時函數
    參考了51單片機 Keil C 延時程序的簡單研究,自己也親身測試和計算了一些已有的延時函數。這裡假定單片機是時鐘頻率為12MHz,則一個機器周期為:1us.
  • 單片機C語言中的空語句
    標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在彙編語言中很容易實現,寫幾個nop就行了。
  • 單片機延時程序經驗
    標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在彙編語言中很容易實現,寫幾個nop就行了。
  • 單片機c語言教程:建立你的第一個KeilC51項目
    KEIL uVISION2 是眾多單片機應用開發軟體中優秀的軟體之一,它支持眾多不一樣公司的MCS51架構的晶片,它集編輯,編譯,仿真等於一體,同時還支持,PLM,彙編和C語言的程序設計,它的界面和常用的微軟 VC++的界面相似,界面友好,易學易用,在調試程序,軟體仿真方面也有很強大的功能。本站提供的單片機c語言教程都是基於keilc51的。
  • 基於proteus的51單片機開發實例30-模塊化程序設計
    到了第29個實例,我們的程序量已經接近500行了,假設我們要找最後一個函數的內容,那就要用滑鼠撥拉好一會才能找到這個函數,是不是會有「好長啊」的感慨?更為致命的是,我們這個程序中既有延時程序、又有液晶顯示程序、還有DS18B20的讀寫程序。所有這個程序都擠在一個main.c文件中,即使我們已經按照延時、顯示、讀寫進行了劃分,整體感覺是不是有些亂?
  • 單片機C語言知識點全攻略(三)
    第八課、運算符和表達式(位運算符)  學過彙編的朋友都知道彙編對位的處理能力是很強的,但是單片機C語言也能對運算對象進行按位操作,從而使單片機C語言也能具有一定的對硬體直接進行操作的能力。位運算符的作用是按位對變量進行運算,但是並不改變參與運算的變量的值。如果要求按位改變變量的值,則要利用相應的賦值運算。
  • PIC單片機C語言程序設計(2)
    1.C語言的標識符  所謂標識符,實際上是一些由程序編寫者自定義的名稱,類似於PIC單片機彙編語言中給寄存器(RAM)的命名。C語言中所用到的變量名、函數名、數組名、文件名等都是由標識符組成的。  標識符是由一串字母(常指英語字母)、數字和下線符(或稱下劃線)組成的字符串。標識符的第一個字符必須是字母或下線符。
  • 單片機提高C語言代碼效率的方法
    #i ncludereg52.h>//包含頭文件sbit led=P2^0;//定義位變量led,使其關聯單片機管腳P2.0void Delayms(unsigned int t);//定義延時函數int main(void)//主函數(C語言程序入口函數)
  • 51單片機基礎剖析(基於C語言)
    一、51單片機內存剖析 在編寫應用程式時,定義一個變量,一個數組,或是說一個固定表格,到底存儲在什麼地方;當定義變量大小超過MCU的內存範圍時怎麼辦;如何控制變量定義不超過存儲範圍;本文引用地址:http://www.eepw.com.cn/article/201611/318636.htm以及如何定義變量才能使得變量訪問速度最快