许多朋友说C中不能准确操控延时时刻,不能象汇编那样直观。
其实不然,对延时函数深化了解一下就能规划出一个抱负的框价出来。
一般的咱们都用
for(x=100;–x;){;}此句同等与x=100;while(–x){;};
或for(x=0;x<100;x++){;}
来写一个延时函数。
在这儿要特别留意:X=100,并不表明只运转100个指令时刻就跳出循环。
能够看看编译后的汇编:
x=100;while(–x){;}
汇编后:
movlw 100
bcf 3,5
bcf 3,6
movwf_delay
l2 decfsz _delay
goto l2
return
从代码能够看出总的指令是是303个,其公式是8+3*(X-1)。留意其间循环周期是X-1是99个。
这儿总结的是x为char类型的循环体,当x为int时分,其间受X值的影响较大。
主张规划一个char类型的循环体,然后再用一个循环体来调用它,能够完成准确的长时刻的延时。
下面给出一个能准确操控延时的函数,此函数的汇编代码是最简练、最能准确操控指令时刻的:
void delay(char x,char y){
char z;
do{
z=y;
do{;}while(–z);
}while(–x);
}
其指令时刻为:7+(3*(Y-1)+7)*(X-1)
假如再加上函数调用的call指令、页面设定、传递参数花掉的7个指令。
则是:14+(3*(Y-1)+7)*(X-1)。
假如要求不是特别严厉的延时,能够用这个函数:
void delay(){
unsigned int d=1000;
while(–d){;}
}
此函数在4M晶体下发生10003us的延时,也便是10MS。
假如把D改成2000,则是20003us,以此类推。
有朋友不明白,为什么不必while(x–)后减量,来操控设定X值是多少就循环多少周期呢?
现在看看编译它的汇编代码:
bcf 3,5
bcf 3,6
movlw 10
movwf _delay
l2
decf _delay
incfsz _delay,w
goto l2
return
能够看出循环体中多了一条指令,不简练。所以在PICC中最好用前减量来操控循环体。
再谈谈这样的句子:
for(x=100;–x;){;}和for(x=0;x<100;x++){;}
从字面上看2者意思相同,但能够经过汇编检查代码。后者代码雍长,而前者就很好的汇编出了简练的代码。
所以在PICC中最好用前者的方式来写循环体,好的C编译器会主动把增量循环化为减量循环。由于这是由处理器硬件特性决议的。
PIC并不是一个很智能的C编译器,所以仍是人脑才是榜首的,把握一些经历对写出高效,简练的代码是有优点的。