C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。那麼用單片機C語言精確延時(定時)的方法都是怎樣的呢?以下僅供參考!
由於單片機C語言下利用軟件延時不容易做到精確的定時,所以很多人在編寫延時子程序的時候不能好好的把握延時的具體時間。C語言下,延時程序主要有以下幾種:
一:
void delay(unsigned char k)
{
unsigned char i,k; //定義變量
for(i=0;i<k;i++); //for循環語句
}
該程序在Keil環境下,會先將C語言轉化成彙編語言,那麼我們就可以根據彙編語言來計算出精確的時間,轉化具體步驟如下:
CLR A ;指令1
MOV R7,A ;指令2
LOOP:
INC R7 ;指令3
CJNE R7,k,LOOP ;指令4
這裏,指令1,指令2和指令3各消耗1個機器週期,指令4消耗兩個機器週期(可查文末附錄表),而在12M的晶振下一個機器週期是1us,在這個過程中,指令1和指令2分別執行1次,即消耗1+1us,而指令3和指令4分別執行了k次,那麼這樣加起來,這個延時子程序所消耗的具體時間就是t=1+1+(1+2)*k=3k+2us。
呵呵,這樣說來,如果我們定義的k爲100的話,這個延時子程序的精確時間就是302us。
二:
void delay(unsigned char i)
{
while(--i)
{;}
}
同樣的道理,將其反彙編,可以看到,只有一條語句:DJNZ i,$;
該語句消耗2us,一共執行i次,所以總共消耗時間t=i*2us。
三:
下面的將形參換爲整形int,這樣的.話,反彙編所執行的語句完全不同,用個具體的數字做例子:
void delay()
{
unsigned int i=10000;
while(--i)
;
}
反彙編後:
4: unsigned int i=10000;
C:0x0003 7F10 MOV R7,#0x10
C:0x0005 7E27 MOV R6,#0x27
5: while(--i)
6: ;
C:0x0007 EF MOV A,R7
C:0x0008 1F DEC R7
C:0x0009 7001 JNZ C:000C
C:0x000B 1E DEC R6
C:0x000C 14 DEC A
C:0x000D 4E ORL A,R6
C:0x000E 70F7 JNZ C:0007
具體計算如下
1.R7經過10H(16)次循環減爲0:
t1=10H*(1+1+2+1+1+2)
2.R6經過27H*256次循環減爲0:
t2=27H*256*(1+1+2+1+1+2)+27H*1
3.最後R7的是變爲255,因此還要多出255次的循環:
t3=255*(1+1+2+1+1+2)
4.加上之前消耗的2us,總消耗時間:
T=2+10H*(1+1+2+1+1+2)+27H*256*(1+1+2+1+1+2)+27H*1+255*(1+1+2+1+1+2)
=2+16*7+39*256*7+39*1+255*7
=71826us
大約爲72ms吧
如果定義一個unsigned int i,那麼延時計算公式爲T=2+(i%256)*7+(i/256)*256*7+i/256+255*7
關於其他類型的延時程序都可以按照這個方法對時間進行較爲精確的計算。