中断是微控制器的强大功能,使您可以异步处理事件。与不断检查事件的投票不同,当发生特定事件时,请立即中断响应,例如按钮按下或计时器溢出。本教程将指导您了解和使用Arduino中断。
你需要什么
- Arduino Uno(或兼容板)
- 按钮
- 10k-Ohm电阻(用于下拉配置)
- LED和220-OHM电阻(可选)
- 面包板和跳线电线
- Arduino IDE安装在您的计算机上
步骤1:什么是中断?
中断会暂时停止主计划的执行以处理特定事件。事件处理后,该程序将恢复其关闭的位置。使用称为的特殊功能来管理中断 中断服务例程(ISRS).
Arduino中断的类型
- 外部中断: 由在特定引脚上的事件(例如,Arduino uno上的引脚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:使用中断的最佳实践
- 保持ISRS简短: 避免在ISR中延迟或复杂的计算,以确保快速响应。
- 避免在ISRS中串行交流: 串行功能可能无法可靠地在ISR内部起作用。
-
使用
volatile
对于共享变量: ISR和主程序之间共享的标记变量为volatile
为了防止编译器优化问题。 - 调试输入: 处理软件或硬件中的删除逻辑,以获取诸如按钮按下的嘈杂信号。
-
在关键部分中禁用中断: 使用
noInterrupts()
和interrupts()
保护关键代码部分。
中断的应用
- 处理按钮按不进行轮询
- 读取旋转编码器
- 定时关键事件(例如,精确的电动机控制)
- 安排周期性任务
- 对外部信号反应(例如,传感器,通信事件)
故障排除
- 中断没有触发: 确保配置正确的销钉和模式。
- 不稳定的行为: 召集噪音信号,避免长时间的ISR。
- 与图书馆发生冲突: 一些库在内部使用中断(例如,伺服,PWM)。确保与您的代码没有冲突。
结论
中断可以在Arduino项目中对事件进行响应迅速,有效的处理。通过学习使用外部,PIN更改和计时器中断,您可以创建强大而精确的应用程序。尝试不同类型的中断,以增强您的项目并优化性能!