實(shí)現(xiàn)延時通常有兩種方法:一種是硬件延時,要用到定時器/計數(shù)器,這種方法可以提高CPU的工作效率,也能做到精確延時;另一種是軟件延時,這種方法主要采用循環(huán)體進(jìn)行。 今天主要介紹軟件延時以及單片機(jī)精確毫秒延時函數(shù)。
單片機(jī)的周期介紹
在電子技術(shù)中,脈沖信號是一個按一定電壓幅度,一定時間間隔連續(xù)發(fā)出的脈沖信號。脈沖信號之間的時間間隔稱為周期;而將在單位時間(如1秒)內(nèi)所產(chǎn)生的脈沖個數(shù)稱為頻率。頻率是描述周期性循環(huán)信號(包括脈沖信號)在單位時間內(nèi)所出現(xiàn)的脈沖數(shù)量多少的計量名稱;頻率的標(biāo)準(zhǔn)計量單位是Hz(赫)。電腦中的系統(tǒng)時鐘就是一個典型的頻率相當(dāng)精確和穩(wěn)定的脈沖信號發(fā)生器。
指令周期:CPU執(zhí)行一條指令所需要的時間稱為指令周期,它是以機(jī)器周期為單位的,指令不同,所需的機(jī)器周期也不同。對于一些簡單的的單字節(jié)指令,在取指令周期中,指令取出到指令寄存器后,立即譯碼執(zhí)行,不再需要其它的機(jī)器周期。對于一些比較復(fù)雜的指令,例如轉(zhuǎn)移指令、乘法指令,則需要兩個或者兩個以上的機(jī)器周期。通常含一個機(jī)器周期的指令稱為單周期指令,包含兩個機(jī)器周期的指令稱為雙周期指令。
時鐘周期:也稱為振蕩周期,一個時鐘周期 = 晶振的倒數(shù)。對于單片機(jī)時鐘周期,時鐘周期是單片機(jī)的基本時間單位,兩個振蕩周期(時鐘周期)組成一個狀態(tài)周期。
機(jī)器周期:單片機(jī)的基本操作周期,在一個操作周期內(nèi),單片機(jī)完成一項基本操作,如取指令、存儲器讀/寫等。
機(jī)器周期=6個狀態(tài)周期=12個時鐘周期。
51單片機(jī)的指令有單字節(jié)、雙字節(jié)和三字節(jié)的,它們的指令周期不盡相同,一個單周期指令包含一個機(jī)器周期,即12個時鐘周期,所以一條單周期指令被執(zhí)行所占時間為12*(1/ 晶振頻率)= x μs。常用單片機(jī)的晶振為11.0592MHz,12MHz,24MHz。其中11.0592MHz的晶振更容易產(chǎn)生各種標(biāo)準(zhǔn)的波特率,后兩種的一個機(jī)器周期分別為1 μs和2 μs,便于精確延時。
單片機(jī)精確毫秒延時函數(shù)
對于需要精確延時的應(yīng)用場合,需要精確知道延時函數(shù)的具體延時時間。以C語言編寫的單片機(jī)延時函數(shù)網(wǎng)上有兩個不同的版本(都說是延時n毫秒),分別如下:
void delay(uint x) //延時X毫秒
{
uint y,z;
for(z=x;z》0;z--)
for(y=110;y》0;y--);
}
void delay_ms(uint n) //延時n毫秒
{
uchar i;
while(n--)
{
for(i=0;i《120;i++);
}
}
上述兩個函數(shù)的實(shí)現(xiàn)方法是一樣的,只是給的時間常數(shù)不同,一個是110,另一個是120。近來工作因?yàn)閷r間的精度要求很高,就特地驗(yàn)證了下這兩個函數(shù)運(yùn)行時所用的時間。 主程序?yàn)椋?/p>
void main(void)
{
delay(1);
}
反匯編之后(推薦用C51智能反編譯器,不過要手工加上ORG地址和END結(jié)束符):
標(biāo)號 指令 地址 機(jī)器碼 機(jī)器周期
ORG 0000H
Q0000: LJMP Q0021 ;0000 02 00 21
;==========================================================================
ORG 0003H
Q0003: SETB C ;0003 D3 1
MOV A,R7 ;0004 EF 1
SUBB A,#00H ;0005 94 00 1
MOV A,R6 ;0007 EE 1
SUBB A,#00H ;0008 94 00 1
JC Q0020 ;000A 40 14 2
MOV R5,#6EH ;000C 7D 6E 1
MOV R4,#00H ;000E 7C 00 1
Q0010: MOV A,R5 ;0010 ED 1
DEC R5 ;0011 1D 1
JNZ Q0015 ;0012 70 01 2
DEC R4 ;0014 1C 1
Q0015: MOV A,R5 ;0015 ED 1
ORL A,R4 ;0016 4C 1
JNZ Q0010 ;0017 70 F7 2
MOV A,R7 ;0019 EF 1
DEC R7 ;001A 1F 1
JNZ Q0003 ;001B 70 E6 2
DEC R6 ;001D 1E 1
SJMP Q0003 ;001E 80 E3 2
Q0020: RET ;0020 22 2
;====================RESET 00-7F AND SET SP=07H============================
ORG 0021H
Q0021: MOV R0,#7FH ;0021 78 7F
CLR A ;0023 E4
Q0024: MOV @R0,A ;0024 F6
DJNZ R0,Q0024 ;0025 D8 FD
MOV SP,#07H ;0027 75 81 07
LJMP Q002D ;002A 02 00 2D
;====================MAIN PROGRAM==========================================
ORG 002DH
Q002D: MOV R7,#01H ;002D 7F 01 1
MOV R6,#00H ;002F 7E 00 1
LJMP Q0003 ;0031 02 00 03 2
;==========================================================================
END
單步執(zhí)行可以跟蹤程序的運(yùn)行,給個最終的結(jié)果就是總的執(zhí)行機(jī)器周期數(shù)為 :
第一個函數(shù):4+9+8*110+4+9=906
第二個函數(shù):4+9+8*120+4+9=986
如果單片機(jī)的晶振是12M,則一個機(jī)器周期的時間為12/(12*10e6)=1us
可見第二個程序更接近1ms(0.986us)的時間,第一個是0.906us
當(dāng)晶振是11.05926M時,第一個延時函數(shù)的精確延時時間是983us,第二個是1069.8us,可見第一個函數(shù)的延時時間更精確一些。
而且延時時間越長,誤差就越大。
評論