Главная chevron_right Функции chevron_right Внешние прерывания chevron_right detachInterrupt()

detachInterrupt()

detachInterrupt() отключает внешнее прерывание на указанном выводе — после этого Arduino перестаёт вызывать обработчик. Рекомендуемый синтаксис: detachInterrupt(digitalPinToInterrupt(pin)).

Полная статья

Описание

Когда внешнее прерывание больше не нужно — например, после завершения инициализации или при переходе в режим ожидания — его можно отключить с помощью detachInterrupt(). После вызова этой функции Arduino перестанет реагировать на сигналы на указанном выводе и вызывать связанный обработчик.

Это полезно, если прерывание нужно только на короткое время, или если вы хотите временно «заморозить» реакцию на внешний сигнал, а потом включить её снова через attachInterrupt().

Синтаксис

Доступны три варианта вызова:

  • detachInterrupt(digitalPinToInterrupt(pin))рекомендуемый способ: использует digitalPinToInterrupt() для преобразования номера вывода в номер прерывания. Работает на всех платах Arduino.
  • detachInterrupt(interrupt) — устаревший вариант, принимает номер прерывания напрямую. Не рекомендуется, так как нумерация прерываний различается от платы к плате.
  • detachInterrupt(pin) — не рекомендуется. Принимает номер вывода, но работает только на ограниченном наборе плат.

Для переносимого кода всегда используйте первый вариант.

Параметры

  • interrupt: номер прерывания, которое нужно отключить. Подробнее о нумерации — см. attachInterrupt().
  • pin: номер вывода Arduino, к которому привязано прерывание. Передаётся внутрь digitalPinToInterrupt(), которая возвращает правильный номер прерывания для текущей платы.

Возвращает

Функция ничего не возвращает.

Пример кода

void setup() {
  // Подключаем прерывание на цифровом пине 2 (например, для кнопки или датчика)
  //  attachInterrupt(digitalPinToInterrupt(2), myInterruptRoutine, RISING);

  // ... остальной код setup ...

  // Позже можно отключить прерывание, когда оно больше не нужно
  detachInterrupt(digitalPinToInterrupt(2)); // или detachInterrupt(2);
}

void loop() {
  // ... код основного цикла ...
}

void myInterruptRoutine() {
  // Эта функция выполняется при срабатывании прерывания на пине 2,
  // пока оно подключено. После вызова detachInterrupt() функция вызываться не будет.
}

Где применяется

  • Однократная реакция на событие: подключить прерывание, поймать первый импульс от кнопки или датчика, затем сразу отключить, чтобы не обрабатывать дребезг или повторные срабатывания.
  • Управление режимами работы: в активном режиме прерывание включено, при переходе в энергосберегающий режим — отключается, чтобы не мешать логике пробуждения.
  • Временная блокировка: если в критическом участке кода нежелательны прерывания по конкретному выводу, можно отключить их на время выполнения этого участка, а потом включить снова.
  • Смена обработчика: перед тем как подключить новый обработчик через attachInterrupt(), старый можно явно отключить через detachInterrupt().

Практические замечания

  • Всегда используйте форму detachInterrupt(digitalPinToInterrupt(pin)) — она работает корректно на всех платах и не зависит от того, как в конкретной плате пронумерованы прерывания.
  • После вызова detachInterrupt() обработчик не будет вызываться, но сам вывод остаётся настроенным так, как вы его настроили (INPUT, INPUT_PULLUP и т.д.).
  • Если вы отключили прерывание, а потом хотите его снова включить — просто вызовите attachInterrupt() с теми же или новыми параметрами.
  • detachInterrupt() не сбрасывает и не очищает флаги прерываний аппаратно — она просто перестаёт вызывать обработчик. Это важно учитывать при работе с низкоуровневыми регистрами.
  • Если прерывание уже было отключено или никогда не подключалось, повторный вызов detachInterrupt() безопасен и не вызовет ошибки.

Полезные материалы