51微控制器的C語言延時的一些總結

2021-06-26 16:44:55 字數 3661 閱讀 5299

在網上搜了一些關於c51微控制器c語言的精確延時(相對)的例子和方法

現總結如下:

1,_nop_()   適用於us級的少量延時

標準的c語言中沒有空語句。但在微控制器的c語言程式設計中,經常需要用幾個空指令產生短延時的效果。

這在組合語言中很容易實現,寫幾個nop就行了。

在keil c51中,直接呼叫庫函式:

#include// 宣告了void _nop_(void);

_nop_();                           // 產生一條nop指令

作用:對於延時很短的,要求在us級的,採用「_nop_」函式,這個函式相當彙編nop指令,延時幾微秒。

nop指令為單週期指令,可由晶振頻率算出延時時間,對於12m晶振,延時1us。

2,一般延時大於10us

一,定義的c51中迴圈變數,盡量採用無符號字元型變數。 

二,在for迴圈語句中,盡量採用變數減減來做迴圈。 

三,在do…while,while語句中,迴圈體內變數也採用減減方法

這因為在c51編譯器中,對不同的迴圈方法,採用不同的指令來完成的

例:unsigned char i; 

for(i=255;i>0;i--); 

用keil c51編譯後

mov 09h,#0ffh 

loop:            djnz 09h,loop 

指令相當簡潔,也很好計算精確的延時時間。

3,延時更長,達到ms級,這時需要巢狀迴圈

迴圈巢狀的方法常用於達到ms級的延時。 對於迴圈語句同樣可以採用for,do…while,while結構來完成,

每個迴圈體內的變數仍然採用無符號字元變數。

例:unsigned char i,j 

for(i=255;i>0;i--) 

for(j=255;j>0;j--); 

或 unsigned char i,j 

i=255; 

do while(j); 

i--; 

} while(i); 

或 unsigned char i,j 

i=255; 

while(i) 

; i--; 

} 下面給出有關在c51中延時子程式設計時要注意的問題(一些經驗之談) 

1、在c51中進行精確的延時子程式設計時,盡量不要或少在延時子程式中定義區域性變數,所有的延時子程式中變數通過有參函式傳遞。 

2、在延時子程式設計時,採用do…while,結構做迴圈體要比for結構做迴圈體好。 

3、在延時子程式設計時,要進行迴圈體巢狀時,採用先內迴圈,再減減比先減減,再內迴圈要好。

4,一些關於延時的例子(在此感謝那些奉獻的網友)

一. 500ms延時子程式

程式:void delay500ms(void)

產生的彙編:

c:0x0800    7f0f     mov      r7,#0x0f

c:0x0802    7eca     mov      r6,#0xca

c:0x0804    7d51     mov      r5,#0x51

c:0x0806    ddfe     djnz     r5,c:0806

c:0x0808    defa     djnz     r6,c:0804

c:0x080a    dff6     djnz     r7,c:0802

c:0x080c    22       ret     

計算分析:

程式共有三層迴圈

一層迴圈n:r5*2 = 81*2 = 162us                  djnz  2us

二層迴圈m:r6*(n+3) = 202*165 = 33330us          djnz  2us + r5賦值 1us = 3us

三層迴圈: r7*(m+3) = 15*33333 = 499995us        djnz  2us + r6賦值 1us = 3us

迴圈外:   5us            子程式呼叫 2us + 子程式返回 2us + r7賦值 1us  = 5us

延時總時間 = 三層迴圈 + 迴圈外 = 499995+5 = 500000us =500ms

計算公式:延時時間=[(2*r5+3)*r6+3]*r7+5

二. 200ms延時子程式

程式:void delay200ms(void)

產生的彙編

c:0x0800    7f05     mov      r7,#0x05

c:0x0802    7e84     mov      r6,#0x84

c:0x0804    7d96     mov      r5,#0x96

c:0x0806    ddfe     djnz     r5,c:0806

c:0x0808    defa     djnz     r6,c:0804

c:0x080a    dff6     djnz     r7,c:0802

c:0x080c    22       ret

三. 10ms延時子程式

程式:void delay10ms(void)

產生的彙編

c:0x0800    7f05     mov      r7,#0x05

c:0x0802    7e04     mov      r6,#0x04

c:0x0804    7df8     mov      r5,#0xf8

c:0x0806    ddfe     djnz     r5,c:0806

c:0x0808    defa     djnz     r6,c:0804

c:0x080a    dff6     djnz     r7,c:0802

c:0x080c    22       ret 

四. 1s延時子程式

程式:void delay1s(void)

產生的彙編

c:0x0800    7f05     mov      r7,#0x05

c:0x0802    7e04     mov      r6,#0x04

c:0x0804    7d74     mov      r5,#0x74

c:0x0806    7cd6     mov      r4,#0xd6

c:0x0808    dcfe     djnz     r4,c:0808

c:0x080a    ddfa     djnz     r5,c:0806

c:0x080c    def6     djnz     r6,c:0804

c:0x080e    dff2     djnz     r7,c:0802

c:0x0810    22       ret

晶振:12mhz

1:5~500us

void delay(unsigned char i)

計算方法:ix2+5 可完成5~515us的延時

2:10us~2ms

void delay(unsigned char i)

計算方法:ix8+10 可完成10us~2.050ms的延時

3:2ms~130ms

void delay(unsigned char i,unsigned char j)         

計算方法:(ix2+3)xj+5 u

51微控制器C語言延時函式

c程式中可使用不同型別的變數來進行延時設計。經實驗測試,使用unsigned char型別具有比unsigned int更優化的 在使用時應該使用unsigned char作為延時變數。以某晶振為12mhz的微控制器為例,晶振為12mhz即乙個機器週期為1us。一.500ms延時子程式 程式 voi...

51微控制器的一些複習

51微控制器的一些複習 sfr special function register特殊功能暫存器的縮寫 宣告可位元組定址的特殊功能暫存器,如sfr po 0x80,sbit 特殊功能暫存器位 宣告可位定址的特殊功能暫存器,如sbit a p0 0 這些都在標頭檔案中有定義 或reg51.h 中一共定...

51微控制器的幾種精確延時

實現延時通常有兩種方法 一種是硬體延時,要用到定時器 計數器,這種方法可以提高cpu的工作效率,也能做到精確延時 另一種是軟體延時,這種方法主要採用迴圈體進行。今天主要介紹軟體延時,關於硬體延時,之後定時器部分再做詳細說明。首先介紹微控制器的幾個週期 在電子技術中,脈衝訊號是乙個按一定電壓幅度,一定...