4

在下面的代码中,为什么ISR2从不运行?

const int in = 19;
const int LED = 9;
int flag;
void setup() {
    pinMode(in, INPUT_PULLUP);
    pinMode(LED, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(in), ISR2, RISING);
    attachInterrupt(digitalPinToInterrupt(in), ISR1, FALLING);

}
void  loop() {
    if (flag) {delay (100); flag = false;}// debounce
}
void ISR1(){
    digitalWrite(LED, LOW);
    // Turn Off the motor, since, Limit Switch was engaged
    flag = true;
}
void ISR2(){ // Limit Switch was disengaged. 
    digitalWrite(LED, HIGH);
    delay(100); // Debounce, so I do not receive spurious FALLING edges from this.
}

即使中断是为不同的事件编程的,Arduino是否不允许您在同一个引脚上附加两个中断?

在我的设置中,引脚 19 从运动控制设置中使用的限位开关获取信号。当限位开关接合时,in销获得LOW信号。因此,由于机械弹跳,我首先看到一个FALLING边缘,然后是RISING边缘和边缘。FALLING在这种情况下,我正确处理了去抖动。

然而,想象一下限位开关处于接合状态一段时间,然后我反转电机导致限位开关脱离,这将发送一个RISING边沿,然后是FALLING边沿RISING。我需要忽略这些边缘,因为没有任何危险。编写的ISR2目的是在限位开关脱离时捕获第一个RISING边沿,然后对其进行去抖动,以便FALLING忽略后面的边沿。但是现在ISR2永远不会被调用,我该如何处理这种情况?

PS 我的微控制器是 ATMEGA 2650,它是一个 Arduino Mega 板。

4

2 回答 2

11

ISR2 永远不会运行,因为任何中断源只能有一个中断服务程序,并且您已将 ISR2 替换为 ISR1 作为该中断的服务程序。如果您重新排序了代码并在 ISR2 之前附加了 ISR1,那么您可能会看到 ISR2 运行但不是 ISR1。

典型的微控制器有一个中断向量表,它将中断服务程序与每个中断源相关联。每个中断源只能有一个服务程序。如果您分配新的服务程序,那么您将替换旧的服务程序。上升沿和下降沿没有单独的服务程序。上升沿与下降沿是中断源的配置设置,用于确定何时触发该中断。中断源不能配置为同时在两个边沿触发。

但是,在您收到第一个边沿的中断并消除跳变后,您可以重新配置另一个边沿的中断。这样,您的代码将为一个 ISR 和另一个 ISR 来回配置。

于 2015-10-28T15:22:36.190 回答
1

你为什么说它永远不会被调用?我认为它被调用了,但你没有注意到它,因为 LED 不会改变它的状态(因为有反弹)。

无论如何,你没有正确地去抖动它。让我们举个例子:你到达了终点。ISR1被调用,所以flag是真的。好的,在下一个循环中,电机将停止。但是......现在开关弹起。ISR2被调用,并且其中的delay函数在退出 ISR 之前等待 100 毫秒。结果:您将电机停止功能延迟了 100 毫秒。

我建议您在这里阅读我的答案,尤其是第二种情况。而且我建议您使用我的代码而不是您的代码,因为这样您就可以立即停止电机,而不会出现反弹或任何其他类型的问题。

于 2015-10-28T09:12:06.473 回答