Сколько контактов прерывания может обрабатывать Uno?

Я рассматриваю использование 7-канального RC-ресивера с Arduino Uno R3. В документации упоминаются максимум два прерывания, в то время как в некоторых других блогах я видел упоминания о применении до 20 контактов в качестве прерываний с библиотекой PinChangeInt. Итак, сколько прерываний может Arduino обрабатывать изначально? И отличается ли это от того, сколько может быть обработано с помощью программного обеспечения, такого как PinChangeInt?

13 голосов | спросил asheeshr 31 Maypm14 2014, 12:58:03

2 ответа


10

Существует два типа прерываний типа «смены контактов». Внешние прерывания, из которых два на Uno. Они называются 0 и 1, однако они относятся к цифровым выводам 2 и 3 на плате. Они могут быть настроены для обнаружения роста, падения, изменения (повышение или ) или LOW.

В дополнение к этому, прерывания «смены пальцев», которые обнаруживают изменение состояния вывода в любом из 20 контактов (от A0 до A5 и от D0 до D13). Эти прерывания смены контактов также аппаратно , поэтому сами по себе будут такими же быстрыми, как внешние прерывания.

Оба типа слегка затрудняются использовать на уровне регистров, но стандартная среда IDE включает attachInterrupt (n) и detachInterrupt (n), что упрощает интерфейс для внешних прерываний. Вы также можете использовать библиотеку смены контактов , чтобы упростить прерывания смены контактов.

Однако, рулевая очистка библиотеки в течение минуты, мы можем установить, что прерывания смены контактов могут быть такими же быстрыми или быстрыми, чем внешние прерывания. Во-первых, хотя прерывания смены контактов работают над партиями контактов, вам не нужно включать всю партию. Например, если вы хотите обнаружить изменения на выводе D4, этого будет достаточно:

Пример эскиза:

 ISR (PCINT2_vect)
 {
 // handle pin change interrupt for D0 to D7 here
 if (PIND & bit (4))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of PCINT2_vect

void setup ()
  { 
  // pin change interrupt (example for D4)
  PCMSK2 |= bit (PCINT20);  // want pin 4
  PCIFR  |= bit (PCIF2);    // clear any outstanding interrupts
  PCICR  |= bit (PCIE2);    // enable pin change interrupts for D0 to D7
  pinMode (4, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

Мое тестирование показывает, что для «тестового» штыря (контакт 5) потребовалось 1,6 мкс для реакции на изменение на выводе прерывания (контакт 4).


Теперь, если вы примете простой (ленивый?) подход и используете attachInterrupt (), вы обнаружите, что результаты медленнее, а не быстрее.

Пример кода:

 void myInterrupt ()
 {
 if (PIND & bit (2))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of myInterrupt

void setup ()
  { 
  attachInterrupt (0, myInterrupt, CHANGE);
  pinMode (2, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

Это занимает 3,7 Â, чтобы изменить тестовый вывод, намного больше, чем 1,6 мкс выше. Зачем? Поскольку код, который компилятор должен генерировать для «общего» обработчика прерываний, должен сохранять каждый возможный регистр (нажимать) на запись в ISR, а затем восстанавливать их (всплывать) перед возвратом. Кроме того, есть накладные расходы на другой вызов функции.


Теперь мы можем обойти это, избегая attachInterrupt () и делая это сами:

 ISR (INT0_vect)
 {
 if (PIND & bit (2))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of INT0_vect

void setup ()
  { 
  // activate external interrupt 0

  EICRA &= ~(bit(ISC00) | bit (ISC01));  // clear existing flags
  EICRA |=  bit (ISC00);    // set wanted flags (any change interrupt)
  EIFR   =  bit (INTF0);    // clear flag for interrupt 0
  EIMSK |=  bit (INT0);     // enable it

  pinMode (2, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

Это самый быстрый из всех на 1.52 Âμs - похоже, что один тактовый цикл был где-то сохранен.


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

Пакеты:

  • от A0 до A5
  • от D0 до D7
  • D8 - D13

Если вам просто нужно еще несколько контактов прерывания, вы можете избежать любого тестирования, просто выбрав использовать контакты из разных партий (например, D4 и D8).


Подробнее на http://www.gammon.com.au/interrupts

ответил Nick Gammon 28 J0000006Europe/Moscow 2015, 08:49:38
7

Существует два типа прерываний. Что означает Игровая площадка Arduino :

  

Процессор, лежащий в основе любого Arduino, имеет два разных типа прерываний: «внешние» и «сменные изменения». На ATmega168 /328 (т. Е. В Arduino Uno /Nano /Duemilanove) есть только два внешних прерывания, а также INT0 и INT1, и они сопоставляются с контактами Arduino 2 и 3. Эти прерывания могут быть настроены на включение по RISING или ПАДЕНИЕ краев сигнала или на низком уровне. Триггеры интерпретируются аппаратными средствами, и прерывание происходит очень быстро. У Arduino Mega есть еще несколько внешних контактов прерывания.

     

С другой стороны, прерывания смены контактов могут быть активированы на многих других контактах. Для Arduinos, основанных на ATmega168 /328, они могут быть включены на любом или всех 20 сигнальных штырях Arduino; на ARduinos на основе ATmega они могут быть включены на 24 штырьках. Они срабатывают одинаково на RISING или FALLING краях сигнала, поэтому для прерывания необходимо установить правильные контакты для определения прерываний, чтобы определить, что произошло (какой вывод? ... сигнал поднялся или упал?) И для правильной обработки. Кроме того, прерывания смены контактов сгруппированы в 3 «порта» на MCU, поэтому для всего тела контактов имеется всего 3 вектора прерываний (подпрограммы). Это делает работу по разрешению действия на одном прерывании еще более сложным.

В принципе, внешние прерывания чрезвычайно быстры, так как все они основаны на оборудовании. Тем не менее, есть также прерывания смены контактов, но они выглядят намного медленнее, потому что они в основном основаны на программном обеспечении.

tl; dr: 20 контактов прерываний вместе намного медленнее. 2 прерывистых штыря являются самыми быстрыми и эффективными.


РЕДАКТИРОВАТЬ: Я просто посмотрел на таблицу данных, и в ней говорится, что прерывание смены контактов запускается для любых выбранных контактов, без указания того, какой контакт был изменен ( хотя он разделен на три вектора прерываний).

  • Для внешних прерываний он скажет вам, что контакт 3 только что изменился
  • Для изменения штифта он скажет вам, что изменился контакт, который вы мониторинг!

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

ответил Anonymous Penguin 31 Maypm14 2014, 16:54:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132