测试Arduino中digital函数的执行时间
好久没有玩Arduino了,也没记录过多少关于Arduino的东西,现在有了时间,就写点东西吧,因为Arduino封装了基本功能的函数,方便很多,但好多函数内部可能添加了我们不知道的代码,我很自然地想到一个问题,运行时间是怎么样的呢,影响多大呢?测试一下,看看什么情况。
测试digitalWrite和digitalRead函数
sketch代码如下
程序中会使板上led以2秒为周期闪烁:
int ledState = 0;
long exeTime = 0;
long dletaTime = 0;
String timeInfo = "Delta Time(write):";
void setup() {
pinMode(13, OUTPUT);
pinMode(12, INPUT);
Serial.begin(9600);
}
void loop() {
if(micros() - exeTime >= 1000000){
// 测试digitalWrite的执行时间
exeTime = micros();
digitalWrite(13, ledState);
dletaTime = micros() - exeTime;
timeInfo = "Delta Time: Write->" + String(dletaTime) + "us";
// 测试digitalRead的执行时间
exeTime = micros();
digitalRead(12);
dletaTime = micros() - exeTime;
timeInfo += ", Read->" + String(dletaTime) + "us";
Serial.println(timeInfo);
ledState = HIGH - ledState;
}
}
结果及分析
结果如下:
Delta Time: Write->8us, Read->8us
Delta Time: Write->8us, Read->8us
Delta Time: Write->8us, Read->4us
Delta Time: Write->8us, Read->8us
Delta Time: Write->4us, Read->4us
Delta Time: Write->8us, Read->4us
Delta Time: Write->8us, Read->8us
Delta Time: Write->4us, Read->4us
Delta Time: Write->8us, Read->8us
Delta Time: Write->8us, Read->8us
...
分析
如上结果可以看到digitalWrite和digitalRead函数的执行时间大约8us,有时也会是4us,不太清楚这是怎么回事儿,不知道会不会是micros的时间误差导致的,不过看时间的话,这两个函数不会太影响运行时间的要求。
测试digitalWrite与寄存器直接赋值
sketch代码如下
int ledState = 0;
long exeTime = 0;
long dletaTime = 0;
String timeInfo = "Delta Time(write):";
void setup() {
pinMode(13, OUTPUT);
pinMode(12, INPUT);
Serial.begin(9600);
}
void loop() {
if(micros() - exeTime >= 2000000){
// 测试digitalWrite的执行时间
exeTime = micros();
digitalWrite(13, ledState);
dletaTime = micros() - exeTime;
timeInfo = "Delta Time: Write" + String(dletaTime) + "us";
// 测试直接配置寄存器的执行时间
delay(1000);
exeTime = micros();
PORTB = 0x00;
dletaTime = micros() - exeTime;
timeInfo += ", Reg->" + String(dletaTime) + "us";
Serial.println(timeInfo);
}
}
结果及分析
结果如下:
Delta Time: Write8us, Reg->4us
Delta Time: Write4us, Reg->4us
Delta Time: Write8us, Reg->4us
Delta Time: Write8us, Reg->4us
Delta Time: Write8us, Reg->4us
Delta Time: Write8us, Reg->4us
Delta Time: Write8us, Reg->4us
...
分析:
根据结果可以看到,直接寄存器复制占用4us,虽比调用函数的速度快,但也差别不大,所以不用太担心调用digital函数会影响执行效率。
对比两种实现LED闪烁的方式
实现:
-
方式1:利用delay延时做到闪烁,每次loop打印Arduino运行的时间。
int ledState = 0; long exeTime = 0; String timeInfo = "Time(write):"; void setup() { pinMode(13, OUTPUT); Serial.begin(9600); exeTime = millis(); } void loop() { exeTime = millis(); timeInfo = "time:" + String(exeTime) + "ms"; digitalWrite(13, ledState); ledState = 1 - ledState; Serial.println(timeInfo); delay(1000); }
-
方式2:利用时间判断,做到精确1000ms循环,每个loop打印运行时间;
int ledState = 0; long exeTime = 0; String timeInfo = "Time(write):"; void setup() { pinMode(13, OUTPUT); Serial.begin(9600); exeTime = millis(); } void loop() { if(millis() - exeTime >= 1000){ exeTime = millis(); timeInfo = "time:" + String(exeTime) + "ms"; digitalWrite(13, ledState); ledState = 1 - ledState; Serial.println(timeInfo); } }
对比结果
-
方式1
time:0ms time:999ms time:1999ms time:3000ms time:4001ms time:5002ms time:6002ms time:7003ms time:8003ms time:9004ms time:10004ms time:11004ms time:12005ms time:13005ms time:14006ms time:15006ms
-
方式2
time:1000ms time:2000ms time:3000ms time:4000ms time:5000ms time:6000ms time:7000ms time:8000ms time:9000ms time:10000m time:11000ms time:12000ms time:13000ms time:14000ms time:15000ms time:16000ms
分析
可以看到两种方式的结果对比,打印时间是ms级别的,第一种方式就明显的看到的时间差的累加,而第二种方式做到了精确时间的循环,有效的避免中间代码执行时间的不确定性所造成周期时间的变化,这种方法提供的思路还是比较有用处的。
-
方式1代码执行生命周期
-
方式2代码执行生命周期
其中有Loop time = Free time + Work time