ESP8266搭配3144霍尔传感器测转速时中断功能异常求助
ESP8266搭配3144霍尔传感器测速故障排查与修复
问题描述
- 初始代码中执行
attachInterrupt(digitalPinToInterrupt(D1), exti_callback, FALLING)时触发系统错误,更换D2引脚后问题依旧,注释该行代码设备可正常运行。尝试更换波特率、上传速率、USB线缆和串口端口均无效,报错信息如下:
load 0x4010f000, len 3424, room 16 tail 0 chksum 0x2e load 0x3fff20b8, len 40, room 8 tail 0 chksum 0x2b csum 0x2b v00041f10 ~ld ⸮⸮⸮⸮o쒜p⸮⸮n|⸮l⸮⸮$`b⸮⸮|r⸮$⸮o⸮⸮o⸮ ets Jan 8 2013,rst cause:2, boot mode:(3,6)
- 修改代码改用D5引脚后,设备能正常输出初始值0,但用磁铁触发霍尔传感器中断时,串口出现乱码错误,修改后的代码如下:
int flag = 0; void ICACHE_RAM_ATTR hallInterrupt(); void setup() { Serial.begin(115200); pinMode(D5, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(D5), hallInterrupt, FALLING); } void loop() { Serial.println(flag); delay(500); } void hallInterrupt() { flag = 1; delay(500); }
故障原因分析
- 中断服务函数(ISR)非法调用阻塞函数:ESP8266的中断服务函数必须保持极简,不能调用
delay()这类依赖系统定时器的阻塞函数。delay()会在ISR中阻塞系统运行,触发看门狗复位,导致设备重启并输出乱码。 - 变量未加
volatile修饰:flag变量在中断中被修改,主循环读取时可能因编译器优化无法获取最新值,导致逻辑异常。
修复方案与代码
针对上述问题,做以下修改:
- 用
volatile修饰flag变量,确保主循环能正确读取中断修改的值; - 移除ISR中的
delay(),将防抖逻辑移至主循环处理; - 中断服务函数仅执行设置标志位的最小操作,避免阻塞系统。
修复后的代码:
volatile int flag = 0; unsigned long lastTriggerTime = 0; const unsigned long debounceDelay = 500; // 防抖延时 void ICACHE_RAM_ATTR hallInterrupt(); void setup() { Serial.begin(115200); pinMode(D5, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(D5), hallInterrupt, FALLING); } void loop() { // 处理防抖和标志位重置 if (flag == 1) { Serial.println(flag); // 等待防抖时间后重置标志位 if (millis() - lastTriggerTime >= debounceDelay) { flag = 0; } } else { Serial.println(flag); } delay(500); } void hallInterrupt() { // 仅设置标志位和记录触发时间,不做阻塞操作 flag = 1; lastTriggerTime = millis(); }
内容的提问来源于stack exchange,提问作者Ryu
相关产品推荐
相关产品推荐

