如何将旧版Arduino的C++中断代码移植到ESP8266和ESP32并修复编译报错
报错根源与修复方案
错误原因
原代码是为AVR架构Arduino开发板编写的,大量使用了AVR专属的底层特性,而ESP8266/ESP32为XTensa架构,完全不兼容这些特性,才会触发语法报错:
ISR()是AVR专用的中断服务函数定义宏,ESP核心无此定义PCINT1_vect、PCMSK1、PCIFR、PCICR、PINC都是AVR专属的中断向量、端口寄存器cli()、sei()是AVR的中断开关指令Streaming.h是AVR平台常用的串口输出库,多数ESP核心未内置该库
具体修复步骤
1. 依赖替换
- 移除
Streaming.h引用,将Serial <<格式的输出改为标准Serial.print()/Serial.println()写法 - 移除所有AVR寄存器操作代码,改用ESP Arduino核心兼容的API
- 中断开关替换为通用的
noInterrupts()/interrupts()函数,ESP核心已做架构兼容
2. 中断逻辑适配
ESP系列支持单个GPIO独立绑定中断,不需要统一处理端口电平变化,直接为每个RC输入引脚绑定边沿中断即可,适配后逻辑更简洁。
适配后可用的示例代码(兼容ESP8266/ESP32)
/* rcTiming_ESP.ino 适配ESP8266/ESP32 * 可自行修改RC_INPUTS数组为你实际使用的GPIO引脚 */ // 定义4个RC输入引脚,可根据硬件修改 const uint8_t RC_INPUTS[] = {14, 12, 13, 15}; const uint8_t RC_CH_NUM = sizeof(RC_INPUTS)/sizeof(RC_INPUTS[0]); volatile unsigned long rcRises[RC_CH_NUM]; // 上升沿时间 volatile unsigned long rcTimes[RC_CH_NUM]; // 脉冲长度 volatile unsigned int rcChange = 0; // 变化计数器 // 中断回调函数 void IRAM_ATTR rcInterruptHandler(void* arg) { uint8_t channel = (uint32_t)arg; unsigned long now = micros(); if (digitalRead(RC_INPUTS[channel]) == HIGH) { // 上升沿,记录时间 rcRises[channel] = now; } else { // 下降沿,计算脉冲宽度 rcTimes[channel] = now - rcRises[channel]; rcChange++; } } void setup_rcTiming() { for (uint8_t i = 0; i < RC_CH_NUM; i++) { pinMode(RC_INPUTS[i], INPUT); // 绑定边沿中断,传入通道号作为参数 attachInterruptArg(digitalPinToInterrupt(RC_INPUTS[i]), rcInterruptHandler, (void*)i, CHANGE); } } void setup() { Serial.begin(115200); Serial.println("Starting RC Timing Test"); setup_rcTiming(); } void loop() { unsigned long rcT[RC_CH_NUM]; unsigned int rcN; if (rcChange) { noInterrupts(); rcN = rcChange; rcChange = 0; memcpy(rcT, (void*)rcTimes, sizeof(rcT)); interrupts(); Serial.print("t="); Serial.print(millis()); Serial.print(" "); for (uint8_t i = 0; i < RC_CH_NUM; i++) { Serial.print(rcT[i]); Serial.print(" "); } Serial.println(rcN); } }
代码说明
IRAM_ATTR是ESP专属的属性标记,保证中断函数运行在RAM中,避免Flash读取延迟导致的中断异常- 使用
attachInterruptArg绑定中断,支持传入通道参数,不需要为每个通道单独写中断函数 - 引脚定义可根据自己的硬件连接自由修改,只要是支持中断的GPIO即可
内容的提问来源于stack exchange,提问作者Luca Spuntoni
相关产品推荐
相关产品推荐

