文章目录
https://www.arduino.cn/thread-12611-1-1.html
虽然 delayMicroseconds( ) 很好用,
可是常常有人喜欢用 for 来做 delay 延迟, 然后就发现怪怪的 !!
其实如下这句写法是等于没写的:
for(int i=0; i < 32000; ++i);
如果你这样测量:
unsigned long begt = micros( );
for(int i=0; i < 32000; ++i);;;
unsigned long endt = micros( );
Serial.println(String("Run time=") + (endt-begt) );
你会发现印出 Run time=4
甚至有时还出现 Run time=0
怎会这样?
Arduino 的 CPU 有这么快吗?.. Arduino当然不可能那么快 !
阿那怎会只用 4 us ?
其实是因为 Compiler 很聪明, 发现你那 for Loop 根本没做事, 于是就很好心的帮你移除了, 等于没写!
所以, 如果发现 Run time=4 是因为 micros( ) 一定是四的倍数,
而这个 4 其实是因为执行了 begt = micros( ); 需要大约 2 us 的时间!
偶而会出现 0 则是刚好做 endt = micros( ); 正好还没变化, 但很可能快要变化了,
注意刚说了, micros( ) 每次变化就是多 4, 一定是四的倍数 !
如果控制 for 的 i 是全局变量, 则目前的 Arduino 就不会把空白的 for 移除掉!
为了方便好奇的网友测试,
以下我写了五个版本如下, 都只改一句, 大家可以测试看看
(1) for Loop 会被移除, Run time 大约 4
注意然在 setup( ) 与 loop( ) 之间有一个全局变量 int i;
但以下这 for(int i 的 i 当然不是外面在 void loop( ) 之前那个 i,
因为局部变量本来就可以与外面全局变量同名!
Compiler 发现这 for Loop 没事可做, 主动把整个 for Loop 全部移除!
void setup( ) {
Serial.begin(9600);
Serial.println("Test for Loop 3200 times,V.1, for(int i=...");
}
int i;
void loop( ) {
unsigned long begt, endt;
delay(258);
begt=micros( );
for(int i=0; i < 3200; ++i) { // 16 clocks = 1 us
// __asm__("NOP"); // 1 clock = 0.0625 us
}
endt = micros( );
Serial.println(String("Run time =") + (endt-begt) +"us" );
delay(3388);
} // loop(
(2) for Loop 正常执行, Run time 大约 1608us
注意这 for(int i 当然也不是外面在 void loop( ) 之前那个 i,
还有, 因为这 for Loop 内部有指令 “NOP”,
编译程序 Compiler 知道不可以把 for Loop 移除 !
void setup( ) {
Serial.begin(9600);
Serial.println("Test for Loop 3200 times,V.2, for(int i=... whth NOP");
}
int i;
void loop( ) {
unsigned long begt, endt;
delay(258);
begt=micros( );
for(int i=0; i < 3200; ++i) {
__asm__("NOP"); // 1 clock = 0.0625 us
}
endt = micros( );
Serial.println(String("Run time =") + (endt-begt) +"us" );
delay(3388);
} // loop(
(3) for Loop 正常执行, Run time 至少 1400us (留给你测
注意以下这个 for( ) 的 i 是外面全局变量的 i
void setup( ) {
Serial.begin(9600);
Serial.println("Test for Loop 3200 times,V.3, for(i=...");
}
int i;
void loop( ) {
unsigned long begt, endt;
delay(258);
begt=micros( );
for(i=0; i < 3200; ++i) { // i is Global
// __asm__("NOP"); // 1 clock = 0.0625 us
}
endt = micros( );
Serial.println(String("Run time =") + (endt-begt) +"us" );
delay(3388);
} // loop(
//(4) for Loop 正常执行, Run time 至少 1600us (留给你测
注意以下这个 for( ) 的 i 也是外面全局变量的 i
void setup( ) {
Serial.begin(9600);
Serial.println("Test for Loop 3200 times,V.4, for(i=... whth NOP");
}
int i;
void loop( ) {
unsigned long begt, endt;
delay(258);
begt=micros( );
for(i=0; i < 3200; ++i) {
__asm__("NOP"); // 1 clock = 0.0625 us
}
endt = micros( );
Serial.println(String("Run time =") + (endt-begt) +"us" );
delay(3388);
} // loop(
(5) for Loop 会被移除, Run time 大约 4
怎么会 ?!
for Loop 内不是有 kk = i; 要做事吗?
可是 Run time 只有 4 us, 你认为 for Loop 有存在吗?
不过, 很神奇的, kk 答案是正确的喔 (3199)!
可见 compiler 有多聪明了
void setup( ) {
Serial.begin(9600);
Serial.println("Test for Loop 3200 times,V.5, for(int i=...){kk=i;}");
}
int i, kk;
void loop( ) {
unsigned long begt, endt;
delay(258);
begt=micros( );
for(int i=0; i < 3200; ++i) { // 16 clocks = 1 us
kk = i;
}
endt = micros( );
Serial.println(String("Run time =") + (endt-begt) +"us" );
Serial.println("String("kk=") + kk + ",, should be 3199");
delay(3388);
} // loop(