我在完全消除连接到中断的按钮时遇到了一些麻烦。目标是在按下/释放按钮时使语句void loop()
恰好运行一次。
通常最终发生的事情是两件事之一
- ISR 标志在按下按钮时设置一次。正如预期的那样,释放按钮没有任何作用。
- ISR 标志在按钮被按下时设置一次,在按钮被释放时再次设置。
这是我拥有的确切代码:
#define interruptPin 2
#define DBOUNCE 100
volatile byte state = LOW; //ISR flag, triggers code in main loop
volatile unsigned long difference;
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), ISR_0, CHANGE);
Serial.begin(115200);
}
void loop() {
if(state){ //If we have a valid interrupt
Serial.println(difference); //Print the time since the last ISR call
state = LOW; //Reset the flag
}
}
void ISR_0() {
static unsigned long last_interrupt = 0;
if(millis()-last_interrupt > DBOUNCE && digitalRead(interruptPin)){
difference=millis()-last_interrupt;
state = HIGH;
}
last_interrupt = millis(); //note the last time the ISR was called
}
这似乎是一种消除中断的流行方式,但无论出于何种原因,它都不适合我。
我希望在按钮释放的第一个下降沿digitalRead(interruptPin)
会显示low
,因此state
不会设置标志。
由于 ISR 更新last_interrupt
时间,第一个下降沿之后的连续反弹似乎仍然被成功忽略。这让我相信去抖动不是问题,而是问题digitalRead(interruptPin)
。
去抖动似乎可以处理除一个状态之外的所有状态。当按钮被释放时,代码仍然偶尔将state
标志设置为HIGH
。
这是一些示例输出:
3643
(从开机等待约 3.6 秒后,我按下按钮,约 1 秒后松开)
在与上述相同的场景中,输出有时如下所示:
3643
1018
这显示我按下按钮,但也释放按钮。
我正在使用一个 UNO R3 和一个带有 1k 下拉电阻的瞬时触觉按钮。
我不确定此时出了什么问题。我希望这很简单,如果他们愿意,任何人都可以轻松地在他们的 arduino 上进行测试。