首页 > 解决方案 > 如何使用为旧板编写的代码中的中断将 C++ 代码移植到 Esp8266 和 Esp32

问题描述

我正在尝试将一些 C++ Arduino 代码移植到更新的 ESP8266 和 ESP32 板上。不幸的是,我已经检查了 Arduino Stack Exchange 论坛,但没有结果

将此 C++ 代码从旧 Arduino 移植到 Esp8266/Esp32 不起作用,我还在这个问题的底部添加了编译错误:

/*  rcTiming.ino -- JW, 30 November 2015 -- 
 * Uses pin-change interrupts on A0-A4 to time RC pulses
 *
 * Ref: https://arduino.stackexchange.com/questions/18183/read-rc-receiver-channels-using-interrupt-instead-of-pulsein
 *
 */
#include <Streaming.h>
static   byte rcOld;        // Prev. states of inputs
volatile unsigned long rcRises[4]; // times of prev. rising edges
volatile unsigned long rcTimes[4]; // recent pulse lengths
volatile unsigned int  rcChange=0; // Change-counter

// Be sure to call setup_rcTiming() from setup()
void setup_rcTiming() {
  rcOld = 0;
  pinMode(A0, INPUT);  // pin 14, A0, PC0, for pin-change interrupt
  pinMode(A1, INPUT);  // pin 15, A1, PC1, for pin-change interrupt
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  PCMSK1 |= 0x0F;       // Four-bit mask for four channels
  PCIFR  |= 0x02;       // clear pin-change interrupts if any
  PCICR  |= 0x02;       // enable pin-change interrupts
}
// Define the service routine for PCI vector 1
ISR(PCINT1_vect) {
  byte rcNew = PINC & 15;   // Get low 4 bits, A0-A3
  byte changes = rcNew^rcOld;   // Notice changed bits
  byte channel = 0;
  unsigned long now = micros(); // micros() is ok in int routine
 while (changes) {
    if ((changes & 1)) {  // Did current channel change?
      if ((rcNew & (1<<channel))) { // Check rising edge
        rcRises[channel] = now;     // Is rising edge
      } else {              // Is falling edge
        rcTimes[channel] = now-rcRises[channel];
      }
    }
    changes >>= 1;      // shift out the done bit
    ++channel;
    ++rcChange;
  }
  rcOld = rcNew;        // Save new state
}

void setup() {
  Serial.begin(115200);
  Serial.println("Starting RC Timing Test");
   setup_rcTiming();
}

void loop() {
  unsigned long rcT[4]; // copy of recent pulse lengths
  unsigned int rcN;
  if (rcChange) {

    // Data is subject to races if interrupted, so off interrupts
    cli();          // Disable interrupts
    rcN = rcChange;
    rcChange = 0;       // Zero the change counter
    rcT[0] = rcTimes[0];
    rcT[1] = rcTimes[1];
    rcT[2] = rcTimes[2];
    rcT[3] = rcTimes[3];
    sei();          // reenable interrupts

    Serial << "t=" << millis() << " " << rcT[0] << " " << rcT[1]
       << " " << rcT[2] << " " << rcT[3] << " " << rcN << endl;
  }
  sei();            // reenable interrupts
}

编译错误是:

'(' 标记之前的预期构造函数、析构函数或类型转换

在线:

ISR(PCINT1_vect){

我正在寻求建议以使其正常工作,谢谢。

标签: c++arduinoesp8266esp32arduino-esp8266

解决方案


所有 ESP32 GPIO 引脚都是具有中断功能的引脚。您可以使用中断,但方式不同。

attachInterrupt(GPIOPin, ISR, Mode);

模式——定义何时应该触发中断。五个常量预定义为有效值:HIGH、LOW、CHANGE、RISING、FALLING

void IRAM_ATTR ISR() {
Statements;
}

根据 ESP32 文档,中断服务程序应具有 IRAM_ATTR 属性


推荐阅读