這也是大家最常在QQ裏問我的一個(ge) 問題,如果從(cong) keil裏看了c語言的反匯編代碼然後根據晶振和指令計算延時的時間這樣雖然非常的準確但是相當的麻煩而且容易搞錯,我這裏介紹一個(ge) 最簡單的方法.可以驗證你的延時函數
這裏用一個(ge) 例程詳細介紹一下。
過程參考如下:
在編譯器下建立一個(ge) 新項目,也可以利用已有項目。此過程中需要注意,單片機晶振的選擇,因為(wei) for循環裏指令的執行時間和晶振有直接關(guan) 係,本例中晶振使用11.0592M。

編寫一段關於延時的函數,主要利用for循環,代碼如下:
void delay_ms(unsigned int ms)
{
unsigned int i;
unsigned char j;
for(i=0;i<ms;i++)
{
for(j=0;j<200;j++);
for(j=0;j<102;j++);
}
}
其中ms是輸入參數,如果輸入1,就是要求程序延時1ms。
j變量是調整程序運行的時間參數。調整j的數值,使1次循環的時間在1ms。
將此程序編譯通過,然後利用軟件仿真,調整時間。
下麵這個(ge) sec就是程序運行到現在的這一行所用的時間。
兩(liang) 次時間差就是延時函數使用的時間,如果與(yu) 1ms相差比較多,用戶可以調整j參數的值,使延時時間盡量接近1ms。如增大j的值for(j=0;j<105;j++);
此方法得出延時函數,在晶振不同的情況下,延時時間會(hui) 不準。軟件調試結果,這個(ge) 程序的延時時間為(wei) :1.01779ms,一般的單片機係統中都可以應用。
下麵來說說匯編的傳(chuan) 統計算方法:
指令周期、機器周期與(yu) 時鍾周期
指令周期:CPU執行一條指令所需要的時間稱為(wei) 指令周期,它是以機器周期為(wei) 單位的,指令不同,所需的機器周期也不同。
時鍾周期:也稱為(wei) 振蕩周期,一個(ge) 時鍾周期 =晶振的倒數。
MCS-51單片機的一個(ge) 機器周期=6個(ge) 狀態周期=12個(ge) 時鍾周期。
MCS-單片機的指令有單字節、雙字節和三字節的,它們(men) 的指令周期不盡相同,一個(ge) 單周期指令包含一個(ge) 機器周期,即12個(ge) 時鍾周期,所以一條單周期指令被執行所占時間為(wei) 12*(1/12000000)=1us。
了解了上麵這些我們(men) 來看一個(ge) 例子
;============延時1秒子程序========================
DELAY_1S: ;延時子程序,12M晶振延時1.002035秒
MOV R4,#10
L3: MOV R2 ,#200 ;1指令周期
L1: MOV R3 ,#249 ;1指令周期
L2: DJNZ R3 ,L2 ;2指令周期
DJNZ R2 ,L1 ;2指令周期
DJNZ R4 ,L3 ;2指令周期
RET ;2指令周期
;循環體(ti) 延時時間: [(249*2+1+2)*200+1+2]*10*12/12000000=1.002030s
;加上ACALL指令和第一條mov指令以及最後一條RET指令算出來整個(ge) 函數的時間為(wei) 1.002035s
;===================================================
通常選用的是11.0592MHZ的晶振:
[(249*2+1+2)*200+1+2]*10*12/11059200=1.08727213541666666...S
匯編延時子程序的延時計算問題
對於(yu) 程序
DELAY: MOV R0,#00H
DELAY1: MOV R1,#0B3H
DJNZ R1,$
DJNZ R0,DELAY1
查指令表可知 MOV一個(ge) 機器周期,DJNZ 指令需用兩(liang) 個(ge) 機器周期,而一個(ge) 機器周期時間長度為(wei) 12/11.0592MHz,所以該段程序執行時間為(wei) :
((0B3×2+1+2)×256+1)×12÷11059200=100.2789mS
第一層:DJNZ R1,$:執行了B3H次,一次兩(liang) 個(ge) 周期,所以為(wei) 0B3×2;
第二層:MOV R1,#0B3H為(wei) 一個(ge) 周期,DJNZ R0,DELAY1為(wei) 兩(liang) 個(ge) 周期,這樣循環一次就是0B3×2+1+2個(ge) 周期;第二層的執行次數本來是255次,但因為(wei) 賦首值為(wei) 0,而DJNZ是先減1,再比較的,所以就應該是256次。
這樣的話,整個(ge) 循環執行完應該是(0B3×2+1+2)×256+1次。再加上開始賦值這一句,就是((0B3×2+1+2)×256+1)了
還說明一下:
nop指令或者_nop_(); 函數占一個(ge) 機器周期,
在stc單片機的12T模式下一個(ge) 機器周期是一個(ge) 振蕩周期的12分頻,如果你的晶振是12MHZ,那你的一個(ge) 機器周期就是1微秒.一個(ge) nop指令的執行時間也就是1US
當在6T模式(下載的時候可選擇模式)下12M晶振的時候,一個(ge) nop就是0.5US了.