Arduino中断教程

Arduino Interrupts Tutorial

中断是微控制器的强大功能,使您可以异步处理事件。与不断检查事件的投票不同,当发生特定事件时,请立即中断响应,例如按钮按下或计时器溢出。本教程将指导您了解和使用Arduino中断。


你需要什么

  1. Arduino Uno(或兼容板)
  2. 按钮
  3. 10k-Ohm电阻(用于下拉配置)
  4. LED和220-OHM电阻(可选)
  5. 面包板和跳线电线
  6. Arduino IDE安装在您的计算机上

步骤1:什么是中断?

中断会暂时停止主计划的执行以处理特定事件。事件处理后,该程序将恢复其关闭的位置。使用称为的特殊功能来管理中断 中断服务例程(ISRS).

Arduino中断的类型

  1. 外部中断: 由在特定引脚上的事件(例如,Arduino uno上的引脚2或3)触发。
  2. 引脚更改中断: 由任何数字别针上的更改触发。
  3. 计时器中断: 由计时器溢出或比较匹配触发。

步骤2:使用外部中断

Arduino Uno支持引脚2和3上的外部中断。您可以配置这些中断以触发:

  • 上升: 信号从低到高。
  • 跌倒: 信号从高到低。
  • 改变: 信号变化状态(低至高或高至低)。
  • 低的: 信号保持较低。

示例代码:检测按钮按下

当按下连接到引脚2的按钮时,此示例将切换LED。

#define buttonPin 2 // Interrupt pin
#define ledPin 13   // Built-in LED

volatile bool ledState = false; // Shared variable between ISR and main code

void handleInterrupt() {
  ledState = !ledState; // Toggle LED state
  digitalWrite(ledPin, ledState);
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Enable internal pull-up resistor
  pinMode(ledPin, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(buttonPin), handleInterrupt, FALLING); // Trigger on button press
}

void loop() {
  // Main loop does nothing; interrupt handles the LED
}

解释

  • attachInterrupt(digitalPinToInterrupt(pin), ISR, mode):配置中断。
    • pin:中断引脚(例如,在Arduino Uno上的引脚2或3)。
    • ISR:执行的中断服务例程。
    • mode:触发​​条件(RISING, FALLING, CHANGE, 或者 LOW).
  • digitalPinToInterrupt(pin):将PIN号转换为其中断号码。

步骤3:使用PIN更改中断

PIN更换中断可让您检测任何数字引脚上的更改。这需要其他图书馆,例如 启用中断.

示例代码:PIN更改中断

#include <EnableInterrupt.h>
#define pin 4 // Pin to monitor

void handlePinChange() {
  Serial.println("Pin state changed!");
}

void setup() {
  Serial.begin(9600);
  enableInterrupt(pin, handlePinChange, CHANGE); // Trigger on any state change
}

void loop() {
  // Main loop does nothing; interrupt handles the event
}

库安装

要使用PIN更改中断,请安装 启用中断 通过Arduino Library Manager库。


步骤4:计时器中断

计时器中断对于精确的间隔安排任务很有用。参考 Arduino Timer教程 有关配置计时器中断的详细信息。

示例:用timer1中断闪烁LED

#define ledPin 13

void setup() {
  pinMode(ledPin, OUTPUT);

  // Configure Timer1
  noInterrupts(); // Disable interrupts during setup
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 15624; // Compare match value for 1Hz (1-second interval)
  TCCR1B |= (1 << WGM12); // CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
  TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt

  interrupts(); // Enable interrupts
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle LED
}

void loop() {
  // Main loop does nothing; Timer1 handles the LED
}

步骤5:使用中断的最佳实践

  1. 保持ISRS简短: 避免在ISR中延迟或复杂的计算,以确保快速响应。
  2. 避免在ISRS中串行交流: 串行功能可能无法可靠地在ISR内部起作用。
  3. 使用 volatile 对于共享变量: ISR和主程序之间共享的标记变量为 volatile 为了防止编译器优化问题。
  4. 调试输入: 处理软件或硬件中的删除逻辑,以获取诸如按钮按下的嘈杂信号。
  5. 在关键部分中禁用中断: 使用 noInterrupts()interrupts() 保护关键代码部分。

中断的应用

  1. 处理按钮按不进行轮询
  2. 读取旋转编码器
  3. 定时关键事件(例如,精确的电动机控制)
  4. 安排周期性任务
  5. 对外部信号反应(例如,传感器,通信事件)

故障排除

  • 中断没有触发: 确保配置正确的销钉和模式。
  • 不稳定的行为: 召集噪音信号,避免长时间的ISR。
  • 与图书馆发生冲突: 一些库在内部使用中断(例如,伺服,PWM)。确保与您的代码没有冲突。

结论

中断可以在Arduino项目中对事件进行响应迅速,有效的处理。通过学习使用外部,PIN更改和计时器中断,您可以创建强大而精确的应用程序。尝试不同类型的中断,以增强您的项目并优化性能!

发表评论

Notice an Issue? Have a Suggestion?
If you encounter a problem or have an idea for a new feature, let us know! Report a problem or request a feature here.