如何使用为旧板编写的代码中断将 C++ 代码移植到 Esp8266 和 Esp32
How do I port C++ code to Esp8266 and Esp32 using interrupts from code written for older boards
我正在尝试将一些 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) {
我正在寻求建议以使其正常工作谢谢。
所有 ESP32 GPIO 引脚都是支持中断的引脚。
您可以使用中断,但方式不同。
attachInterrupt(GPIOPin, ISR, Mode);
模式——定义何时触发中断。五个常量被预定义为有效 values:HIGH、LOW、CHANGE、RISING、FALLING
void IRAM_ATTR ISR() {
Statements;
}
根据 ESP32 文档
,中断服务例程应具有 IRAM_ATTR 属性
我正在尝试将一些 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) {
我正在寻求建议以使其正常工作谢谢。
所有 ESP32 GPIO 引脚都是支持中断的引脚。 您可以使用中断,但方式不同。
attachInterrupt(GPIOPin, ISR, Mode);
模式——定义何时触发中断。五个常量被预定义为有效 values:HIGH、LOW、CHANGE、RISING、FALLING
void IRAM_ATTR ISR() {
Statements;
}
根据 ESP32 文档
,中断服务例程应具有 IRAM_ATTR 属性