ESP32 GPIO SPEED TEST

ESP32のGPIOにおける digitalwrite と GPIO_OUT_W1TS_REG のスピードの比較してみた。

結果から言うと実際の利用条件で扱う場合はそれほど変わらない。 ただLチカや単独のGPIOしか使わないような特殊な条件においてはGPIO_OUT_W1TS_REG の方が圧倒的に早い。 又GPIO_OUT_W1TS_REG のメリットとして一つの命令で複数のGPIOを同時にHIGHLOWの操作が可能になる。

一般的な利用用途においてはdigitalwriteで組んだ方がベターだと思う。

又GPIOの接続先(例えばシフトレジスタ)によってはいくら矩形パルスを速くしても正確に受け付けてくれない可能性もある。 実際手元の環境で74hc595をつなげて実験したが正確に動作しなかった。 途中にdelayを入れ調整すれば正確に動くがdelay値の細かい調整が必要になるしかえって遅くなる事も考えられる。

speed program

#if !defined( ESP32 )
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define START_MSG String(__FILE__) + " start."

//#define GPIO_OUT_W1TS_REG (*(volatile uint32_t*)0x60004008)/* GPIO0-31 Original addr  0x3FF44008    */
//#define GPIO_OUT_W1TC_REG (*(volatile uint32_t*)0x6000400c)/* GPIO0-31 Original addr  0x3FF4400C    */
#define GPIO_OUT_W1TS_REG (*(volatile uint32_t*)0x3FF44008)/* GPIO0-31 Original addr  0x3FF44008    */
#define GPIO_OUT_W1TC_REG (*(volatile uint32_t*)0x3FF4400C)/* GPIO0-31 Original addr  0x3FF4400C    */
#define PIN_5     5
#define GPIO_5 ((uint32_t)0x01 << 5)

uint32_t Time;

void setup() {
  Serial.begin(115200);
  Serial.println( START_MSG);
  pinMode(PIN_5, OUTPUT);
}

void loop() {
  for (;;) {
        Serial.println("Direct GPIO_OUT_W1TS_REG");
    for (uint8_t j = 0; j < 100; j++) {
      Time = micros();
      for (uint32_t i = 0; i < 1000000; i++) {
        GPIO_OUT_W1TS_REG = GPIO_5;
        GPIO_OUT_W1TC_REG = GPIO_5;
      }
      Serial.printf("%ld,", micros() - Time);
    }

    // -------------------
    Serial.println();
    // -------------------
    Serial.println("Direct GPIO_OUT_W1TS_REG [GPIO5 ONLY]");
    for (uint8_t j = 0; j < 100; j++) {
      Time = micros();
      for (uint32_t i = 0; i < 1000000; i++) {
        GPIO_OUT_W1TS_REG |= GPIO_5;
        GPIO_OUT_W1TC_REG |= GPIO_5;
      }
      Serial.printf("%ld,", micros() - Time);
    }

    // -------------------
    Serial.println();
    // -------------------
    Serial.println("Direct GPIO_OUT_W1TS_REG [Another Register]");
    for (uint8_t j = 0; j < 100; j++) {
      Time = micros();
      for (uint32_t i = 0; i < 1000000; i++) {
      GPIO.out_w1ts |= GPIO_5;
      GPIO.out_w1tc |= GPIO_5;
      }
      Serial.printf("%ld,", micros() - Time);
    }

    // -------------------
    Serial.println();
    // -------------------

    Serial.println("Normal digitalWrite");
    for (uint8_t j = 0; j < 100; j++) {
      Time = micros();
      for (uint32_t i = 0; i < 1000000; i++) {
        digitalWrite(PIN_5, HIGH);
        digitalWrite(PIN_5, LOW);
      }
      Serial.printf("%ld,", micros() - Time);
    }
    Serial.println();
  }
}

result


Direct GPIO_OUT_W1TS_REG
100800,100798,100806,100805,100807,100805,100799,

Direct GPIO_OUT_W1TS_REG [GPIO5 ONLY]
251956,251954,251953,251954,251954,251954,251953,

Direct GPIO_OUT_W1TS_REG [Another Register]
251955,251954,251953,251954,251954,251953,251954,

Normal digitalWrite
252461,252591,252587,252583,252594,252586,252592,
created:

Back to top