我正在使用带有 ESP32 的 Arduino IDE。硬件很简单:ESP32开发板+ LED和簧片开关。我现在想检测簧片开关输入(1Hz 到 40Hz 频率)并让 LED 闪烁。
代码很简单:
const int button = 27;
const int led = 25;
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;
void IRAM_ATTR buttonInput() {
Serial.println("IN");
digitalWrite(led, HIGH);
startTimer = true;
lastTrigger = millis();
}
void setup() {
Serial.begin(115200);
pinMode(button, INPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
attachInterrupt(digitalPinToInterrupt(button), buttonInput, RISING);
}
void loop() {
now = millis();
if(startTimer && (now - lastTrigger > 25)) { // switch of led after 25 ms
digitalWrite(led, LOW);
startTimer = false;
}
}
但是我遇到了核心恐慌并在中断时重新启动(看起来与簧片开关触发的频率无关):
IN
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
Core 1 register dump:
PC : 0x4008a0dc PS : 0x00060435 A0 : 0x80089352 A1 : 0x3ffbed1c
A2 : 0x3ffb8a00 A3 : 0x3ffb8890 A4 : 0x00000004 A5 : 0x00060423
A6 : 0x00060423 A7 : 0x00000001 A8 : 0x3ffb8890 A9 : 0x00000018
A10 : 0x3ffb8890 A11 : 0x00000018 A12 : 0x3ffc1804 A13 : 0x00060423
A14 : 0x007bee78 A15 : 0x003fffff SAR : 0x0000000a EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x40085fb5 LEND : 0x40085fc5 LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400d8e2f EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000
Backtrace:0x4008a0d9:0x3ffbed1c |<-CORRUPTED
Core 0 register dump:
PC : 0x4008a259 PS : 0x00060035 A0 : 0x80088f7f A1 : 0x3ffbe7cc
A2 : 0x3ffbee78 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060023
A6 : 0x00060021 A7 : 0x0000cdcd A8 : 0x0000cdcd A9 : 0xffffffff
A10 : 0x3ffc160c A11 : 0x00000000 A12 : 0x3ffc1608 A13 : 0x00000007
A14 : 0x007bee78 A15 : 0x003fffff SAR : 0x0000001a EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace:0x4008a256:0x3ffbe7cc |<-CORRUPTED
ELF file SHA256: 0000000000000000
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1324
ho 0 tail 12 room 4
load:0x40078000,len:13508
load:0x40080400,len:3604
entry 0x400805f0
IN
IN
IN
<-CORRUPTED
是什么意思?我做错了什么?
该代码在中断处理程序中使用串行通信 (
buttonInput()
)。这不行。
当调用中断处理程序时,它会阻塞整个系统。因此它必须只做最少的工作并快速返回。然而串行通信速度很慢并且会导致长时间的延迟。因此,您的程序被看门狗终止(“wdt”是看门狗的缩写)。
您的按钮很可能在按下时弹起,即它会在几分之一秒内重复调用中断处理程序。这会加剧问题。
最好在中断处理程序中设置一个标志,并在主循环中完成所有相关工作。
问题是我在中断函数中使用了
Serial.println("IN");
。在 loop()
函数中使用它不是问题。
我有一个带有中断的代码,用于读取连接有 ps2keyboard 的 gpio,在 arduino UNO 中运行正常,当我将其移植到 ESP32 时,出现了相同的错误。(恐慌(CPU1 上的中断 wdt 超时))。 解决办法是利用Serial.println来调试,代码运行良好。