c語言精確時間的延時函數(shù) 精確延時程序c語言

C語言中 delay 函數(shù)如何運(yùn)用?

1、delay函數(shù)是一般自己定義的一個延時函數(shù)。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供鐵山港網(wǎng)站建設(shè)、鐵山港做網(wǎng)站、鐵山港網(wǎng)站設(shè)計(jì)、鐵山港網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、鐵山港企業(yè)網(wǎng)站模板建站服務(wù),十余年鐵山港做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

2、C語言定義延時函數(shù)主要通過無意義指令的執(zhí)行來達(dá)到延時的目的。下面給出一個經(jīng)典的延時函數(shù)。

//?定義一個延時xms毫秒的延時函數(shù)

void?delay(unsigned?int?xms)??//?xms代表需要延時的毫秒數(shù)

{

unsigned?int?x,y;

for(x=xms;x0;x--)

for(y=110;y0;y--);

}

51單片機(jī)用c語言怎么寫延時函數(shù)?

延時時間的計(jì)算與單片機(jī)的晶振頻率有關(guān)。若晶振頻率為12Mhz,那么單片機(jī)每震動一次所需要的時間是1/12M s。那么再來看看單片機(jī)執(zhí)行一次自減所需要的振動次數(shù)是96次,假如我們對時間要求不是特別精確的話,可以約等于100來計(jì)算?,F(xiàn)在通過上面兩個數(shù)據(jù)可以得出:單片機(jī)每執(zhí)行一次自減所需要的時間是1/12M *100(s),即1/120000 s,逆向計(jì)算一下,每1ms需要自減多少次?120次對吧。所以一個簡單的延時功能就誕生了,我們只需要自減120次,就可以延時1ms,如果我們要延時50ms呢,那就自減50*120=6000次。那么在程序上如何表達(dá)呢?我們可以用兩套for循環(huán)

void delay(int i){

int x,y;

for(x=i;x0;x--){

for(y=120;y0;y--)

}

}

參數(shù) i 代表該函數(shù)延時多少ms

怎么用C語言做單片機(jī)的精確延時

在單片機(jī)應(yīng)用中,經(jīng)常會遇到需要短時間延時的情況,一般都是幾十到幾百μs,并且需要很高的精度(比如用單片機(jī)驅(qū)動DS18B20時,誤差容許的范圍在十幾μs以內(nèi),不然很容易出錯);而某些情況下延時時間較長,用計(jì)時器往往有點(diǎn)小題大做。另外在特殊情況下,計(jì)時器甚至已經(jīng)全部用于其他方面的定時處理,此時就只能使用軟件定時了[1]。

1 C語言程序延時

Keil C51的編程語言常用的有2種: 一種是匯編語言;另一種是C 語言。用匯編語言寫單片機(jī)程序時,精確時間延時是相對容易解決的。比如,用的是晶振頻率為12 MHz的AT89C51,打算延時20 μs,51單片機(jī)的指令周期是晶振頻率的1/12,即一個機(jī)器周期為1 μs;“MOV R0,#X”需要2個機(jī)器周期,DJNZ也需要2個機(jī)器周期,單循環(huán)延時時間t=2X+3(X為裝入寄存器R0的時間常數(shù))[2]。這樣,存入R0里的數(shù)初始化為8即可,其精度可以達(dá)到1 μs。用這種方法,可以非常方便地實(shí)現(xiàn)512 μs以下時間的延時。如果需要更長時間,可以使用兩層或更多層的嵌套,當(dāng)然其精度誤差會隨著嵌套層的增加而成倍增加。

雖然匯編語言的機(jī)器代碼生成效率很高,但可讀性卻并不強(qiáng),復(fù)雜一點(diǎn)的程序就更難讀懂;而C語言在大多數(shù)情況下,其機(jī)器代碼生成效率和匯編語言相當(dāng),但可讀性和可移植性卻遠(yuǎn)遠(yuǎn)超過匯編語言,且C 語言還可以嵌入?yún)R編程序來解決高時效性的代碼編寫問題。就開發(fā)周期而言,中大型軟件的編寫使用C 語言的開發(fā)周期通常要比匯編語言短很多,因此研究C語言程序的精確延時性能具有重要的意義。

C程序中可使用不同類型的變量來進(jìn)行延時設(shè)計(jì)。經(jīng)實(shí)驗(yàn)測試,使用unsigned char類型具有比unsigned int更優(yōu)化的代碼,在使用時應(yīng)該使用unsigned char作為延時變量。

2 單層循環(huán)延時精度分析

下面是進(jìn)行μs級延時的while程序代碼。

延時函數(shù):

void delay1(unsigned char i) {

while(i );}

主函數(shù):

void main() {

while(1) {

delay1(i);

}

}

使用Keil C51的反匯編功能,延時函數(shù)的匯編代碼如下:

C:0x00E6AE07MOVR6,0x07

C:0x00E81FDECR7

C:0x00E9EEMOVA,R6

C:0x00EA70FAJNZC:00E6

C:0x00EC22RET

圖1 斷點(diǎn)設(shè)置位置圖

通過對i賦值為10,在主程序中圖1所示的位置設(shè)置斷點(diǎn)。經(jīng)過測試,第1次執(zhí)行到斷點(diǎn)處的時間為457 μs,再次執(zhí)行到該處的時間為531 μs,第3次執(zhí)行到斷點(diǎn)處的時間為605 μs,10次while循環(huán)的時間為74 μs,整個測試結(jié)果如圖2所示。

圖2 使用i--方式測試仿真結(jié)果圖

通過對匯編代碼分析,時間延遲t=7X+4(其中X為i的取值)。測試表明,for循環(huán)方式雖然生成的代碼與用while語句不大一樣,但是這兩種方法的效率幾乎相同。C語言中的自減方式有兩種,前面都使用的是i--的方式,能不能使用--i方式來獲得不同的效果呢?將前面的主函數(shù)保持不變,delay1函數(shù)修改為下面的方式:

void delay1(unsigned char i) {

while(--i);}

同樣進(jìn)行反匯編,得到如下結(jié)果:

C:0x00E3DFFEDJNZR7,

C:00E3C:0x00E522RET

比較發(fā)現(xiàn),--i的匯編代碼效率明顯高于i--方式。由于只有1條語句DJNZ,執(zhí)行只需要2個時鐘周期, 1個時鐘周期按1 μs計(jì)算,其延時精度為2 μs;另外,RET需要2個時鐘周期,能夠達(dá)到匯編語言代碼的效率。按前面的測試條件進(jìn)行測試,第1次執(zhí)行到斷點(diǎn)處的時間為437 μs,再次執(zhí)行到該處的時間為465 μs,第3次執(zhí)行到斷點(diǎn)處的時間為493 μs,10次while循環(huán)的時間為28 μs,整個測試結(jié)果如圖3所示。

圖3 使用--i方式測試仿真結(jié)果圖

調(diào)整i的取值,i取8時延時時間為24 μs,i取9時延時時間為26 μs。通過分析得出,10次循環(huán)為28 μs是由于外層循環(huán)造成的,其精度可以達(dá)到2 μs。在設(shè)計(jì)時應(yīng)該考慮參數(shù)傳遞和RET語句執(zhí)行所需要的時間周期。實(shí)驗(yàn)分析發(fā)現(xiàn),for語句使用--i方式,同樣能夠達(dá)到與匯編代碼相同的精度。i取不同值時延時仿真結(jié)果如圖4所示。

圖4 i取不同值時延時仿真結(jié)果圖

3 多重嵌套下的C程序延時

在某些情況下,延時較長,僅使用單層循環(huán)方式是不能完成的。此時,只能使用多層循環(huán)方式,那么多重循環(huán)條件下,C程序的精度如何呢?下面是一個使用for語句實(shí)現(xiàn)1 s延時的函數(shù)。

延時函數(shù)

void delay1s(void) {

for(k=100;k0;k--) //定時1 s

for(i=20;i0;i--)

for(j=248;j0;j--);

}

主函數(shù)調(diào)用延時函數(shù)代碼段:

while(1) {

delay1s();

scond+=1;

}

為了直接衡量這段代碼的效果,利用Keil C找出這段代碼產(chǎn)生的匯編代碼:

C:0x00B37002JNZ

C:00B7C:0x00B5150CDEC0x0C

C:0x00B7E50DMOVA,0x0D

C:0x00B9450CORLA,0x0C

C:0x00BB70DEJNZC:009B

C:0x00BDE50BMOVA,0x0B

C:0x00BF150BDEC0x0B

C:0x00C17002JNZC:00C5

C:0x00C3150ADEC0x0A

C:0x00C5E50BMOVA,0x0B

C:0x00C7450AORLA,0x0A

C:0x00C970CAJNZC:0095

C:0x00CB22RET

分析匯編代碼,其他匯編代碼使用的不是DJNZ跳轉(zhuǎn)方式,而是DEC和JNZ語句來實(shí)現(xiàn)循環(huán)判斷。1條JNZ指令要花費(fèi)2個時鐘周期,3條指令就需要6個機(jī)器周期,MOV指令和DEC指令各需要1小時鐘周期,1個時鐘周期按1 μs算,其精度最多達(dá)到8 μs,最后加上一條LCALL和一條RET語句,所以整個延時精度較差[4]。

利用Keil C的測試工具,在一處設(shè)置一個斷點(diǎn)。第1次執(zhí)行到中斷處的時間為0.000 513 s,第2次執(zhí)行到中斷處的時間為1.000 922 s,時間延遲為1.000 409 s,測試結(jié)果如圖5所示。對于上面的3種循環(huán)嵌套,循環(huán)次數(shù)為100×20×248=496 000,每次循環(huán)的時間約為2 μs。

圖5 三重嵌套循環(huán)1 s實(shí)現(xiàn)時間測試結(jié)果

為獲取與匯編語言延時的差距,同樣進(jìn)行1 s的延時,程序代碼段如下:

LCALL DELY1S

INC Second

DELY1S:MOV R5,#100

D2:MOV R6,#20

D1:MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

DJNZ R5,D2

RET

通過Keil C51測試,其實(shí)際延遲時間為0.997 943 s。雖然C語言實(shí)現(xiàn)延時方式的匯編代碼復(fù)雜度增加,但是與匯編語言實(shí)現(xiàn)的方式性能差距并不大。

4 總結(jié)

匯編語言在實(shí)時性方面具有較大的優(yōu)越性,雖然使用Keil C51可以在C語言程序中嵌入?yún)R編代碼,但是復(fù)雜度明顯提高。實(shí)驗(yàn)證明,只要合理地運(yùn)用C語言,在延時編程方面就可以達(dá)到與匯編語言相近的精度。為了獲得精確的時間延遲,可通過Keil C工具的仿真功能,調(diào)整延遲量,從而得到較理想的結(jié)果。

C語言延時函數(shù)

C語言的延遲函數(shù)一般是利用無意義程序運(yùn)行來控制時間從而達(dá)到延時的目的

舉個例子:

for(i=0;ix;i++)

for(j=0;j120;j++);

這是延時x毫秒的for循環(huán)語句。

值得注意的是記得最后的;一定得記得寫。

當(dāng)前名稱:c語言精確時間的延時函數(shù) 精確延時程序c語言
文章位置:http://muchs.cn/article14/doheode.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、關(guān)鍵詞優(yōu)化、域名注冊、移動網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管