【发布时间】:2015-10-26 23:48:49
【问题描述】:
我在 arduino Mega 2650 上连接了一个限位开关,用于运动控制。限位开关的两个常开触点连接到 Arduino 引脚和接地,这样当限位开关接合时,Arduino 引脚会短路到接地。
正如预期的那样,我在此设置中遇到了弹跳问题。我使用 ISR 中的计数器确认了这一点。最后,我编写了以下代码,该代码似乎可以可靠地识别我的限位开关在任何给定时间点是接合还是分离。
const int lsOuterLeftIn = 18; // lsOuterLeftIn is my Limit Switch
const int LED = 9;
volatile bool lsEngaged = false; // flag for limit switch engaged
void setup() {
pinMode(lsOuterLeftIn, INPUT_PULLUP);
pinMode(LED, OUTPUT);
attachInterrupt(digitalPinToInterrupt(lsOuterLeftIn), ISR1, FALLING);
attachInterrupt(digitalPinToInterrupt(lsOuterLeftIn), ISR2, RISING);
}
void loop() {
if (lsEngaged) digitalWrite(LED, HIGH);
else digitalWrite(LED, LOW);
}
void ISR1(){
delay(100);
lsEngaged = (digitalRead(lsOuterLeftIn));
}
void ISR2(){
delay(100);
lsEngaged = (digitalRead(lsOuterLeftIn));
}
但是,这是我的问题。我遇到了这个Arduino documentation page,上面写着
"由于delay()需要中断才能工作,所以调用它就不起作用 在 ISR 内部。 "
但是,我确实在 ISR 中使用了delay(),而且它似乎有效,这是怎么回事?我是否有一种情况,目前一切正常,但很容易中断,因为 delay() 函数可能会像文档所说的那样在我身上发生故障?
【问题讨论】:
-
Here is an answer 应该可以解决你所有的问题。
-
在中断中使用忙等待循环是一个非常糟糕的主意——总是这样!
-
您应该(也)提供去抖动硬件(RC低通),因为反弹可能太快而无法由µC处理。
-
开关弹跳会导致许多 MHz 的杂散脉冲,远远超过 IO 的施密特触发器或 FF 或任何指定处理的脉冲。这些脉冲很难在软件中可靠地处理,但可能会导致输入电路或 µC 的其他部分发生一些不希望的操作。首先最好让它们远离 IO 引脚。
-
嗯,很奇怪。我似乎找不到有关这些“A/C 电气特性”的任何信息。然而,我确实发现50ns(= 20MHz)是中断逻辑保证检测到的最小脉冲长度。无论如何,我不会超过零件的最大值。时钟频率。
标签: arduino embedded interrupt debouncing