|
關于時間單位1s=1000ms毫秒=10-3秒
1ms=1000us微秒=10-6秒
1us=1000ns納秒=10-9秒
1ns=1000ps皮秒=10-12秒
1ps=1000fs飛秒=10-15秒
目前51單片機只能精確到微秒級,若對時間精度要求較高,需達到微秒級,則一般需用匯編語言編程,若只需達到秒或毫秒級,則用C語言編程就可滿足要求。
==》作為預備知識,建議先了解下機器周期、數(shù)據(jù)類型和存儲器類型,可以參照
機器周期:http://www.torrancerestoration.com/bbs/dpj-43300-1.html
數(shù)據(jù)類型:http://www.torrancerestoration.com/bbs/dpj-43301-1.html
存儲器類型:http://www.torrancerestoration.com/bbs/dpj-43302-1.html
==》下面先介紹匯編語言編程
根據(jù)定時時間長度可以編制不同循環(huán)重數(shù)的程序。
===》單循環(huán)延遲程序
MOV R7,#TIME
LOOP:NOP 1機器周期
NOP 1機器周期
DJNZ R7,LOOP 2機器周期
延遲時間=4 X T X TIME
以常見的12M晶振為例,則一個機器周期T=1us
因為R7是8位寄存器,所以TIME只能為char型,其值域為0~255
則定時范圍為 4us~1020us
===》雙循環(huán)延時程序
MOV R7,#TIME1 1機器周期
LOOP1:MOV R6,#TIME2 1機器周期
LOOP2:NOP 1機器周期
NOP 1機器周期
DJNZ R6,LOOP2 2機器周期
DJNZ R7,LOOP1 2機器周期
延時時間=(TIME2 X 4 +2+1) X TIME1 X T+T
定時范圍為 8us~260 866us
===》三重循環(huán)延時程序
MOV R7,#TIME1 1機器周期
LOOP1:MOV R6,#TIME2 1機器周期
LOOP2:MOV R5,#TIME3 1機器周期
LOOP3:NOP 1機器周期
NOP 1機器周期
DJNZ R5,LOOP3 2機器周期
DJNZ R6,LOOP2 2機器周期
DJNZ R7,LOOP1 2機器周期
延遲時間=((TIME3 X 4 +2+1) X TIME2 +2+1) X TIME1 X T +T
定時范圍為 11us~66 521 341us
根據(jù)需要還可以編寫4重5重或更多重程序,滿足不同延時需要。
==》C語言編程
C語言中通過循環(huán)結構的程序達到延時的目的,還可以通過循環(huán)嵌套滿足不同的定時要求,常用循環(huán)語句有以下三種:
while(表達式){語句;}
do{語句;}while(表達式)
for(表達式1;表達式2;表達式3){語句;}
我是通過keil仿真時數(shù)匯編指令的數(shù)目來確定循環(huán)語句執(zhí)行時間的(我不知道是不是還有更好的方法),結果如下:
====》while語句
下面的例子可以不看,后面跟著結果。
例子:int i; while(i<1000); {i++;}
keil編譯成的匯編代碼循環(huán)執(zhí)行段為:
循環(huán)代碼 消耗的機器周期
C:0x0003 C3 CLR C 1
C:0x0004 E509 MOV A,0x09 1
C:0x0006 94E8 SUBB A,#0xE8 1
C:0x0008 E508 MOV A,0x08 1
C:0x000A 6480 XRL A,#P0(0x80) 1
C:0x000C 9483 SUBB A,#DPH(0x83) 1
C:0x000E 500A JNC C:001A 2
5: {i++;}
C:0x0010 0509 INC 0x09 1
C:0x0012 E509 MOV A,0x09 1
C:0x0014 70ED JNZ main(C:0003) 2
根據(jù)每條指令的機器周期可以確定,循環(huán)一次消耗的機器周期數(shù)為:12個
依然以12M晶振為例,每個機器周期為1us,則循環(huán)一次耗時12us,循環(huán)一千次耗時12 000us
(signed int)i 能取到的最大值為32767,所以此循環(huán)語句的定時范圍為10us~393 204us
====》do while 語句
同樣例子后面有結果,可以不看例子。
例子: int i=10; do{i--;} while(i>0);
keil編譯的匯編程序循環(huán)段代碼:
循環(huán)段代碼 消耗的機器周期
C:0x0007 EF MOV A,R7 1
C:0x0008 1F DEC R7 1
C:0x0009 7001 JNZ C:000C 2
C:0x000B 1E DEC R6
5: while(i>0);
C:0x000C D3 SETB C 1
C:0x000D EF MOV A,R7 1
C:0x000E 9400 SUBB A,#0x00 1
C:0x0010 EE MOV A,R6 1
C:0x0011 6480 XRL A,#P0(0x80) 1
C:0x0013 9480 SUBB A,#P0(0x80) 1
C:0x0015 50F0 JNC C:0007 2
循環(huán)一次消耗的機器周期數(shù):12個
晶振12M,i 最大值32767,定時范圍:10us~393 204us
====》for語句
例子: int i; for(i=1000;i>0;i--);
循環(huán)段代碼 消耗的機器周期
C:0x0007 EF MOV A,R7 1
C:0x0008 1F DEC R7 1
C:0x0009 7001 JNZ C:000C 2
C:0x000B 1E DEC R6
C:0x000C EF MOV A,R7 1
C:0x000D 4E ORL A,R6 1
C:0x000E 70F7 JNZ C:0007 2
循環(huán)一次消耗的機器周期數(shù):8個
依然以12M晶振為例,則定時范圍:6us~262 136us
for語句中,若 i 定義為 unsigned int ,則 i 的最大值可取65535,則定時范圍:6us~524 280us
|
|