在網上搜了一些關於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的工作效率,也能做到精確延時 另一種是軟體延時,這種方法主要採用迴圈體進行。今天主要介紹軟體延時,關於硬體延時,之後定時器部分再做詳細說明。首先介紹微控制器的幾個週期 在電子技術中,脈衝訊號是乙個按一定電壓幅度,一定...