测试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代码执行生命周期

    1

  • 方式2代码执行生命周期

    2

其中有Loop time = Free time + Work time


arduino

1103 字

2015-10-15 12:34 +0800