實(shí)現(xiàn)延時(shí)通常有兩種方法:一種是硬件延時(shí),要用到定時(shí)器/計(jì)數(shù)器,這種方法可以提高CPU的工作效率,也能做到精確延時(shí);另一種是軟件延時(shí),這種方法主要采用循環(huán)體進(jìn)行。 今天主要介紹軟件延時(shí)以及單片機(jī)精確毫秒延時(shí)函數(shù)。
單片機(jī)的周期介紹
在電子技術(shù)中,脈沖信號(hào)是一個(gè)按一定電壓幅度,一定時(shí)間間隔連續(xù)發(fā)出的脈沖信號(hào)。脈沖信號(hào)之間的時(shí)間間隔稱為周期;而將在單位時(shí)間(如1秒)內(nèi)所產(chǎn)生的脈沖個(gè)數(shù)稱為頻率。頻率是描述周期性循環(huán)信號(hào)(包括脈沖信號(hào))在單位時(shí)間內(nèi)所出現(xiàn)的脈沖數(shù)量多少的計(jì)量名稱;頻率的標(biāo)準(zhǔn)計(jì)量單位是Hz(赫)。電腦中的系統(tǒng)時(shí)鐘就是一個(gè)典型的頻率相當(dāng)精確和穩(wěn)定的脈沖信號(hào)發(fā)生器。
指令周期:CPU執(zhí)行一條指令所需要的時(shí)間稱為指令周期,它是以機(jī)器周期為單位的,指令不同,所需的機(jī)器周期也不同。對(duì)于一些簡(jiǎn)單的的單字節(jié)指令,在取指令周期中,指令取出到指令寄存器后,立即譯碼執(zhí)行,不再需要其它的機(jī)器周期。對(duì)于一些比較復(fù)雜的指令,例如轉(zhuǎn)移指令、乘法指令,則需要兩個(gè)或者兩個(gè)以上的機(jī)器周期。通常含一個(gè)機(jī)器周期的指令稱為單周期指令,包含兩個(gè)機(jī)器周期的指令稱為雙周期指令。
時(shí)鐘周期:也稱為振蕩周期,一個(gè)時(shí)鐘周期 = 晶振的倒數(shù)。對(duì)于單片機(jī)時(shí)鐘周期,時(shí)鐘周期是單片機(jī)的基本時(shí)間單位,兩個(gè)振蕩周期(時(shí)鐘周期)組成一個(gè)狀態(tài)周期。
機(jī)器周期:?jiǎn)纹瑱C(jī)的基本操作周期,在一個(gè)操作周期內(nèi),單片機(jī)完成一項(xiàng)基本操作,如取指令、存儲(chǔ)器讀/寫等。
機(jī)器周期=6個(gè)狀態(tài)周期=12個(gè)時(shí)鐘周期。
51單片機(jī)的指令有單字節(jié)、雙字節(jié)和三字節(jié)的,它們的指令周期不盡相同,一個(gè)單周期指令包含一個(gè)機(jī)器周期,即12個(gè)時(shí)鐘周期,所以一條單周期指令被執(zhí)行所占時(shí)間為12*(1/ 晶振頻率)= x μs。常用單片機(jī)的晶振為11.0592MHz,12MHz,24MHz。其中11.0592MHz的晶振更容易產(chǎn)生各種標(biāo)準(zhǔn)的波特率,后兩種的一個(gè)機(jī)器周期分別為1 μs和2 μs,便于精確延時(shí)。
單片機(jī)精確毫秒延時(shí)函數(shù)
對(duì)于需要精確延時(shí)的應(yīng)用場(chǎng)合,需要精確知道延時(shí)函數(shù)的具體延時(shí)時(shí)間。以C語言編寫的單片機(jī)延時(shí)函數(shù)網(wǎng)上有兩個(gè)不同的版本(都說是延時(shí)n毫秒),分別如下:
void delay(uint x) //延時(shí)X毫秒
{
uint y,z;
for(z=x;z》0;z--)
for(y=110;y》0;y--);
}
void delay_ms(uint n) //延時(shí)n毫秒
{
uchar i;
while(n--)
{
for(i=0;i《120;i++);
}
}
上述兩個(gè)函數(shù)的實(shí)現(xiàn)方法是一樣的,只是給的時(shí)間常數(shù)不同,一個(gè)是110,另一個(gè)是120。近來工作因?yàn)閷?duì)時(shí)間的精度要求很高,就特地驗(yàn)證了下這兩個(gè)函數(shù)運(yùn)行時(shí)所用的時(shí)間。 主程序?yàn)椋?/p>
void main(void)
{
delay(1);
}
反匯編之后(推薦用C51智能反編譯器,不過要手工加上ORG地址和END結(jié)束符):
標(biāo)號(hà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)行,給個(gè)最終的結(jié)果就是總的執(zhí)行機(jī)器周期數(shù)為 :
第一個(gè)函數(shù):4+9+8*110+4+9=906
第二個(gè)函數(shù):4+9+8*120+4+9=986
如果單片機(jī)的晶振是12M,則一個(gè)機(jī)器周期的時(shí)間為12/(12*10e6)=1us
可見第二個(gè)程序更接近1ms(0.986us)的時(shí)間,第一個(gè)是0.906us
當(dāng)晶振是11.05926M時(shí),第一個(gè)延時(shí)函數(shù)的精確延時(shí)時(shí)間是983us,第二個(gè)是1069.8us,可見第一個(gè)函數(shù)的延時(shí)時(shí)間更精確一些。
而且延時(shí)時(shí)間越長(zhǎng),誤差就越大。
評(píng)論