用什麼循環編譯時間短
❶ 為什麼使用do…while循環編譯後生成的代碼的長度短於while循環
一般情況下兩種方法下,while會比do while多一條進去循環的跳轉指令,如下圖匯編代碼,黃色是多出來的。
原因是do while是直接進去循環,先執行再判斷,while是先判斷再執行,所以在進入時先要跳到判斷的地方。
這里的影響太小了,不用太過於關注,而且大部分情況下還是要先判斷再執行,所以while還是用的最多的。
❷ 單片機匯編中為什麼要用NOP
在單片機C語言中加入NOP指令是因為標準的C語言中沒有空語句。
但備檔桐在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。
這在匯編語言中很容易實現,寫幾個nop就行了。
在AVR-GCC中,如下方法嵌入匯編指令:
asm ("nop; nop; nop; nop;" ::);
在keil C51中,直接調用庫函數:
#include// 聲明了void _nop_(void);
_nop_();// 產生一條NOP指令
(2)用什麼循環編譯時間短擴展閱讀
執行NOP指令只使程序計數器PC加1,所以佔用一個機器周期。實例:MOVLW 0xOF ;送OFH到W MOVWF PORT_B ;W內容寫入B口 NOP ;空操作 MOVF PORT_B,W 。
讀操作說明:該三條指令是一種對I/O口的B口連續操作的實例,其目的達到寫入B口的蠢源內容要讀出時,應保證寫、讀之間有個穩定時間,因此加入了空操作指令NOP。
作用:對於延時很短的,要求在us級的,採用「_nop_ 」函數,這個函數相當匯編NOP指令,延時幾微秒。NOP指令為單周期指令,可由晶振頻率算出延時時間,對於12M晶振,延時1uS。
對於延時比較長的,要求在大於10us,採用C51中的循環語句來實現。
在選擇C51中循環語句時,要注意以下幾個問題:
第一、定義的C51中循環變數,盡量採用無符號字元型變數。
第二、在FOR循環語句中,盡量採用變數減減來做循環。
第三、在do,, while, while 語句中,循環體內變數也採用減減方法。
這因為在C51編譯器中,對不同的循環方法,採用不同的指令來完成的。仿坦
❸ for循環編寫延時函數的用法是什麼
步驟如下所示:
1、在編譯器下建立一個新項目,也可以利用已有項目。此過程中需要注意,單片機晶振的選擇,因為for循環里指令的執行時間和晶振有直接關系,本例中晶振使用11.0592M。
2、編寫一段關於延時的函數,主要利用for循環,代碼如下:
void delay_ms(unsigned int ms)
{
unsigned int i;
unsigned char j;
for(i=0;ims;i++)
{
for(j=0;j200;j++);
for(j=0;j102;j++);
}
}
其中ms是輸入參數,如果輸入1,就是要求程序延時1ms。j變數是調整程序運行的時間參數。調整j的數值,使1次循環的時間在1ms。
3、將此程序編譯通過,然後利用軟體模擬,調整時間。
4、兩次時間差就是延時函數使用的時間,如果與1ms相差比較多,用戶可以調整j參數的值,使延時時間盡量接近1ms。如增大j的值for(j=0;j105;j++);此方法得出延時函數,在晶振不同的情況下,延時時間會不準。另外這種方法不是完全精確的延時,所以不要太深研究誤差的問題。軟體調試結果,這個程序的延時時間為:1.01779ms,一般的單片機系統中都可以應用。
❹ 單片機C語言延時需要注意的問題
標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在匯編語言中很容易實現,寫幾個nop就行了。
在keil C51中,直接調用庫函數:
#include // 聲明了void _nop_(void);
_nop_(); // 產生一條NOP指令
作用:對於延時很短的,要求在us級的,採用「_nop_」函數,這個函數相當匯編NOP指令,延時幾微秒。NOP指令為單周期指令,可由晶振頻率算出延時時間,對於12M晶振,延時1uS。對於延時比較長的,要求在大於10us,採用C51中的循環語句來實現。
在選擇C51中循環語句時,要注意以下幾個問題
第一、定義的C51中循環變數,盡量採用無符號字元型變數。
第二、在FOR循環語句中,盡量採用變數減減來做循環。
第三、在do…while,while語句中,循環體內變數也採用減減方法。
這因為在C51編譯器中,對不同的循環方法,採用不同的指令來完成的。
下面舉例說明:
unsigned char i;
for(i=0;i<255;i++);
unsigned char i;
for(i=255;i>0;i--);
其中,第二個循環語句C51編譯後,就用DJNZ指令來完成,相當於如下指令:
MOV09H,#0FFH
LOOP: DJNZ09H,LOOP
指令相當簡潔,也很好計算精確的延時時間。
同樣對do…while,while循環語句中,也是如此
例:
unsigned char n;
n=255;
do{n--}
while(n);
或
n=255;
while(n)
{n--};
這兩個循環語句經過C51編譯之後,形成DJNZ來完成的方法,
故其精確時間的計算也很方便。
其三:對於要求精確延時時間更長,這時就要採用循環嵌套的方法來實現,因此,循環嵌套的方法常用於達到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{j=255;
do{j--}
while(j);
i--;
}
while(i);
或
unsigned char i,j
i=255;
while(i)
{j=255;
while(j)
{j--};
i--;
}
這三種方法都是用DJNZ指令嵌套實現循環的,由C51編譯器用下面的指令組合來完成的
MOVR7,#0FFH
LOOP2: MOVR6,#0FFH
LOOP1: DJNZR6,LOOP1
DJNZR7,LOOP2
這些指令的組合在匯編語言中採用DJNZ指令來做延時用,因此它的時間精確計算也是很簡單,假上面變數i的初值為m,變數j的初值為n,則總延時時 間為:m×(n×T+T),其中T為DJNZ指令執行時間(DJNZ指令為雙周期指令)。這里的+T為MOV這條指令所使用的時間。同樣對於更長時間的延 時,可以採用多重循環來完成。
只要在程序設計循環語句時注意以上幾個問題。
下面給出有關在C51中延時子程序設計時要注意的問題
1、在C51中進行精確的延時子程序設計時,盡量不要或少在延時子程序中定義局部變數,所有的延時子程序中變數通過有參函數傳遞。
2、在延時子程序設計時,採用do…while,結構做循環體要比for結構做循環體好。
3、在延時子程序設計時,要進行循環體嵌套時,採用先內循環,再減減比先減減,再內循環要好。
unsigned char delay(unsigned char i,unsigned char j,unsigned char k)
{unsigned char b,c;
b="j";
c="k";
do{
do{
do{k--};
while(k);
k="c";
j--;};
while(j);
j=b;
i--;};
while(i);
}
這精確延時子程序就被C51編譯為有下面的指令組合完成
delay延時子程序如下:
MOV R6,05H
MOV R4,03H
C0012: DJNZ R3, C0012
MOV R3,04H
DJNZ R5, C0012
MOV R5,06H
DJNZ R7, C0012
RET
假設參數變數i的初值為m,參數變數j的初值為n,參數變數k的初值為l,則總延時時間為:l×(n×(m×T+2T)+2T)+3T,其中T為 DJNZ和MOV指令執行的時間。當m=n=l時,精確延時為9T,最短;當m=n=l=256時,精確延時到16908803T,最長。