Скільки шпильок для переривання може працювати Uno?


16

Я дивлюся на використання 7-канального RC-приймача з Arduino Uno R3. У документації згадується максимум 2 шпильки для переривання, тоді як у деяких інших блогах я бачив згадки про використання до 20 штифтів як переривання, з бібліотекою PinChangeInt. Отже, скільки перерв може ардуїно впоратися споконвічно? І чим це відрізняється від того, скільки можна обробити за допомогою програмного забезпечення, такого як PinChangeInt?

Відповіді:


13

Існує два типи переривань типу "pin pin". Зовнішні переривання, яких на Уно є два. Вони називаються 0 і 1, однак вони посилаються на цифрові штифти 2 і 3 на дошці. Вони можуть бути налаштовані для виявлення підйому, падіння, зміни (піднесення або падіння) або НИЗКО.

На додаток до цього є переривання "pin pin", які виявляють зміну стану штифта в будь-якому з 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 ()
  {
  }

Моє тестування вказує, що реакція на зміну штифта переривання (контакт 4) знадобилася 1,6 мкс, щоб контактний "тест" (контакт 5) реагував на зміну.


Тепер, якщо ви скористаєтеся простим (лінивим?) Підходом і використовуєте 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, а потім відновити їх (спливати) перед поверненням. Плюс є накладні витрати іншого виклику функції.


Тепер ми можемо обходити це, уникаючи приєднання InterInrupt () і робимо це самостійно:

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 мкс - схоже, що один тактовий цикл десь врятувався.


Однак є одне застереження для перерв на переключення. Вони видозмінені, тому, якщо ви хочете мати перерви на багатьох штирях, вам потрібно перевірити всередині переривання, яке змінилося. Ви можете зробити це, збереживши попередній статус штифта та порівнявши його з новим статусом шпильки. Це не обов'язково особливо повільно, але чим більше штифтів потрібно перевірити, тим повільніше буде.

Партії:

  • Від A0 до A5
  • Від D0 до D7
  • Від D8 до D13

Якщо ви хочете отримати ще кілька шпильок для переривання, ви можете уникнути будь-якого тестування, просто вибравши використовувати штифти різних партій (наприклад, D4 і D8).


Детальніше на http://www.gammon.com.au/interrupts


9

Існує два типи переривань. Що засказала майданчик Arduino :

Процесор в основі будь-якого Arduino має два різні види переривань: "зовнішня" та "зміна штифтів". На ATmega168 / 328 (тобто в Arduino Uno / Nano / Duemilanove), INT0 і INT1, є лише два зовнішніх перериваючих штифта, і вони відображаються на шпильки Arduino 2 і 3. Ці переривання можуть бути встановлені для запуску в RISING або ВІДКАЛЕННЯ ребер сигналу або на низькому рівні. Тригери інтерпретуються апаратними засобами, і переривання відбувається дуже швидко. У Arduino Mega доступні ще кілька зовнішніх штифтів для переривання.

З іншого боку, переривання зміни штифтів можна ввімкнути на багатьох інших штирях. Для Arduinos на основі ATmega168 / 328 вони можуть бути включені на будь-якому або всіх 20 сигнальних штифтах Arduino; на Arduinos на базі ATmega їх можна вмикати на 24 штирі. Вони спрацьовують однаково на краях сигналу ВІДКЛЮЧЕННЯ або ПІДТРИМКА, тому до коду переривання потрібно встановити належні штифти для отримання переривань, щоб визначити, що сталося (на який штифт? ... сигнал піднявся чи впав?), І правильно поводитися. Крім того, переривання зміни штифтів групуються у 3 "порти" на MCU, тому для всього корпусу штирів є лише 3 вектори переривання (підпрограми). Це ще більше ускладнює роботу щодо вирішення дії на одному перериванні.

В основному, зовнішні переривання надзвичайно швидкі, оскільки всі вони базуються на апараті. Однак є і переривання зміни штифтів, але вони здаються набагато повільнішими, оскільки в основному вони базуються на програмному забезпеченні.

tl; dr: 20 штифтів переривання разом набагато повільніше. 2 шпильки для переривання - це найшвидший і найефективніший.


EDIT: Я щойно переглянув таблицю даних, і в ній написано, що для будь-якого із вибраних штифтів запускається переривання зміни штифта, не вказуючи, який штифт змінився (хоча він розділений на три вектори переривання).

  • Що стосується зовнішніх переривань, він підкаже вам щойно змінений PIN-код 3
  • Щодо зміни пін, він скаже вам, що ви змінили шпильку, яку ви контролювали!

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.