Menu
CoddyTech

FALLING、RISING 和 CHANGE

本课属于 Coddy Arduino 学习旅程的“无需 delay 的计时”单元。第 13 课,共 18 课。

Uno 有两个引脚可以触发中断:引脚 2 和引脚 3。需要使用中断的按钮必须连接到其中一个引脚。在芯片内部,它们分别是中断 0 和中断 1,所以用 digitalPinToInterrupt() 将引脚转换为对应的中断编号。attachInterrupt(3, ...) 请求中断 3,但 Uno 没有这个中断,因此不会发生任何事情。

attachInterrupt() 的最后一部分指定要响应哪种变化:

  • FALLING:引脚从 HIGH 变为 LOW(使用上拉电阻时,表示按下按钮)
  • RISING:引脚从 LOW 变为 HIGH(表示松开按钮)
  • CHANGE:两种变化都会响应

使用 CHANGE 时,ISR 会在按下按钮和松开按钮时运行。它会读取引脚,以判断发生了哪种变化:

void onChange() {
  if (digitalRead(buttonPin) == LOW) {
    // 按钮被按下了
  } else {
    // 按钮松开了
  }
}

attachInterrupt(digitalPinToInterrupt(buttonPin), onChange, CHANGE);
challenge icon

挑战

简单

按钮连接在引脚 3 上,而 loop() 正忙着执行一项耗时的任务。让引脚 13 上的 LED 立即跟随按钮:

  • 在 onChange() 中读取按钮:LOW 点亮 LED,HIGH 则将其熄灭
  • 使用 CHANGE 将 onChange() 绑定到按钮引脚

按“运行”,按住再松开按钮,然后按“检查”。

亲手试试

const int ledPin = 13;
const int buttonPin = 3;

// 每次按钮引脚状态变化时运行。
void onChange() {
  // 按下按钮时点亮 LED,松开时熄灭
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  // 在这里将 onChange() 绑定到按钮引脚
}

void loop() {
  // 耗时的任务:保持原样
  Serial.println("working");
  delay(2000);
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

无需 delay 的计时中的所有课

自己练习: Arduino 在线编辑器