attachInterrupt() / Arduino

Добавлено 10 ноября 2018 в 14:26

Описание

Цифровые выводы с прерываниями

Первый параметр attachInterrupt() – это номер прерывания. Как правило, вы должны использовать digitalPinToInterrupt(pin) для перевода реального цифрового вывода в конкретный номер прерывания. Например, если вы подключаетесь к выводу 3, используйте digitalPinToInterrupt(3) в качестве первого параметра attachInterrupt().

ПлатаЦифровые выводы, используемые для прерываний
Uno, Nano, Mini, other 328-based2, 3
Uno WiFi Rev.2все цифровые выводы
Mega, Mega2560, MegaADK2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based0, 1, 2, 3, 7
Zeroвсе цифровые выводы, кроме 4
MKR Family boards0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Dueвсе цифровые выводы
101все цифровые выводы (Выводы 2, 5, 7, 8, 10, 11, 12, 13 работают только с CHANGE)

Примечания и предупреждения

Внутри прикрепленной функции delay() работать не будет, а значение, возвращаемое millis(), не будет увеличиваться. Последовательные данные, принятые во время выполнения этой функции, могут быть потеряны. Вы должны объявлять как volatile любые переменные, которые вы изменяете в прикрепленной функции. Дополнительную информацию смотрите в разделе об обработчиках прерываний ниже.

Использование прерываний

Прерывания полезны для того, чтобы всё в программах микроконтроллеров происходило автоматически, и могут помочь решить проблемы с синхронизацией. Подходящие задачи для использования прерываний включают в себя считывание поворотного энкодера или мониторинг пользовательского ввода данных.

Если вы хотите обеспечить, чтобы программа всегда будет захватывать импульсы от поворотного энкодера, так чтобы она никогда не пропускала их, было бы сложно написать последовательно выполняемую программу, которая делала бы что-либо еще, потому что программе необходимо было бы постоянно выполнять опрос линий датчика, идущих от энкодера, чтобы отлавливать импульсы при их появлении. Другие датчики также имеют аналогичную динамику интерфейса, например, попытка прочитать звуковой датчик, который пытается отловить щелчок, или инфракрасный датчик (фотопрерыватель), который пытается отследить падение монеты. Во всех этих ситуациях использование прерывания может освободить микроконтроллер для выполнения какой-либо другой работы, не пропуская ввода данных.

О функциях обработчиков прерываний (ISR)

ISR – это специальные виды функций, которые имеют некоторые уникальные ограничения, которых нет у большинства других функций. ISR не может иметь никаких параметров, и они не должны чего-либо возвращать.

Как правило, ISR должна быть как можно короче и быстрее. Если ваш скетч использует несколько ISR, одновременно может быть запущен только один обработчик, другие прерывания будут обрабатываться после того, как текущий будет завершен, в зависимости от своего приоритета. millis() полагается на прерывания для счета, поэтому она никогда не будет инкрементироваться во время выполнения ISR. Поскольку delay() требует для работы прерываний, эта функция не будет работать, если будет вызвана внутри ISR. Функция micros() изначально работает, но начнет вести себя беспорядочно через 1-2 мс. Функция delayMicroseconds() не использует счетчиков, поэтому будет работать нормально.

Обычно глобальные переменные используются для передачи данных между ISR и основной программой. Чтобы убедиться, что переменные, используемые ISR и основной программой, обновляются правильно, объявляйте их как volatile (изменчивыми).

Синтаксис

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); // рекомендуется
attachInterrupt(interrupt, ISR, mode); // не рекомендуется
attachInterrupt(pin, ISR, mode); // не рекомендуется, только для Arduino Due, Zero, MKR1000, 101

Параметры

interrupt: номер прерывания (int).

pin: номер вывода (только для Arduino Due, Zero, MKR1000).

ISR: функция обработчика прерывания, которая вызывается, когда происходит прерывание; данная функция должна не принимать никаких параметров и ничего не возвращать.

mode: определяет, когда должно быть запущено прерывание. В качестве допустимых значений предопределены четыре константы:

  • LOW, чтобы вызывать прерывание, когда на выводе низкий логический уровень;
  • CHANGE, чтобы вызывать прерывание всякий раз, когда меняется состояние на выводе;
  • RISING для запуска, когда состояние на выводе переходит от низкого к высокому;
  • FALLING, когда состояние на выводе переходит от высокого к низкому.

Платы Due, Zero и MKR1000 также поддерживают:

  • HIGH, чтобы вызывать прерывание всякий раз, когда на выводе высокий логический уровень.

Возвращает

Ничего.

Пример кода

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() 
{
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() 
{
  digitalWrite(ledPin, state);
}

void blink() 
{
  state = !state;
}

Номера прерываний

Обычно вы должны использовать digitalPinToInterrupt(pin), а не помещать в свой скетч непосредственно номер прерывания. Конкретные выводы с прерываниями и их сопоставление с номером прерывания зависят от каждого типа платы. Прямое использование номеров прерываний может показаться простым, но оно может вызвать проблемы совместимости, когда ваш скетч будет запускаться на другой плате.

Однако более старые скетчи часто используют прямые номера прерываний. Часто использовались 0 (для цифрового вывода 2) или 1 (для цифрвого вывода 3). В приведенной ниже таблице показаны доступные выводы прерывний на различных платах.

Обратите внимание, что в приведенной ниже таблице номера прерываний это числа, которые должны быть переданы attachInterrupt(). По историческим причинам эта нумерация не всегда соответствует прерываниям на чипе ATmega (например, int.0 соответствует INT4 на чипе ATmega2560).

Соответствие номеров выводов номерам прерываний на платах Arduino
ПлатаINT.0INT.1INT.2INT.3INT.4INT.5
Uno, Ethernet23    
Mega25602321201918
На базе 32u4 (например, Leonardo, Micro)32017 

Для плата Uno WiFiRev.2, Due, Zero, семейства MKR и 101 номер прерывания = номер вывода.

 

Теги

ArduinoGPIOISR (обработчик прерывания)ПрерываниеПрерывание GPIOПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.