AVR Урок 42

Урок 42

EXINT або зовнішні переривання

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

Так як я випадково залочив свій контролерATMega328, розташований на недорогій платі, то ми працюватимемо з платоюArduino UNO.

Ні, не лякайтеся, ми не будемо працювати з середовищем програмування Arduino IDE, ми також будемо працювати з тим же Atmel Studio, тільки Arduino ми будемо використовувати як налагоджувальну плату і будемо його програмувати через роз'ємISP.

Втім, поки не приїдуть плати дрібніші, я буду свої уроки писати із застосуванням Arduino UNO, а також з модулем LAN я також працюватиму з тією ж платою.

Також чим виявився хороший Arduino, що до нього не потрібний перехідник TTL-USB, тому що він там вже чудово апаратно реалізований. Причому, мало того, ми через штатний USB-роз'єм Arduino не тільки користуватимемося USART-ом, а й живитимемо наш Arduino через нього ж.

Як програматор ми також будемо використовувати дешевий USBASP. Так як він у мене з перемикачем піанія 3,3В/5В, то прибравши з нього зовсім перемичку, ми взагалі відключимохарчування з програматора на плату і через ISP виключно тільки програмувати нашу плату.

Так як на платі Arduino знаходиться 6-контактний роз'єм ISP, будемо використовувати стандартний ISP-перехідник

Arduino

Після підключення програматора до плати ми отримаємо таку картину

INT0

Підключимо USB-роз'єм до комп'ютера - тепер у нас є готовий вихід USART на ПК, а також і живлення

INT0

Повернемося до наших переривань. Зовнішні переривання – це такі переривання, які обробляються внаслідок виникнення деяких подій на певній ніжці порту мікроконтролера. Таких подій є кілька. Переривання у контролера AVR можуть спрацьовувати як за рівнем, так і фронтом. За рівнем вони спрацьовують, коли буде помічено певний логічний рівень. Тобто, якщо буде налагоджено спрацьовування за рівнем логічної одиниці, то якщо цей рівень залишатиметься на ніжці зовнішнього переривання, то переривання буде циклічно працювати, поки не встановиться інший логічний рівень. А по фронту — коли буде помічено перехід із одного логічного стану до іншого. Фронт, як відомо буває висхідний або низхідний. Говорять ще замість висхідного просто фронт, а замість низхідного - спад. Також ще називають передній та задній фронт. Втім - це кому як зручно.

Ніжок для відстеження зовнішніх переривань у контролера існує дві -INT0 іINT1. Перша ніжка збігається з ніжкою портуPD2, а друга - зPD3

Arduino

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

Перший регістр - це регістр управління типом події, що обробляється -EICRA

урок

Пара бітівICS01 таICS00 керує типом подій на ніжціINT0, а друга -ICS11 таICS10 -INT1

Ось залежність типів подій від включення бітівICS01 таICS00

А це дляICS11 таICS10

Відповідно отримаємо ми таку залежність:

00 - Низький рівень на ніжці,

01 — Будь-яка зміна на ніжці,

10 - низхідний фронт на ніжці,

11 - висхідний фронт на ніжці.

Другий регістр - це регістр включення ніжки перериваньEIMSK

Arduino

У цьому регістрі існує лише два біти, що дозволяють переривання на відповідних ніжках - INT1 і INT0. Біти так і називаються, тому не переплутаємо.

Третій регістр - регістр прапорівEIFR, які встановлюються та скидаються при певних подіях

INT0

Безпосередньо ми до цього регістру не звертаємося, тому що працюватимемо з функцією-обробником.

Тепер начебто щось прояснилося щодо зовнішніх переривань.

Залишилася справа за малим. Створити та прошити проект, який якось наочно демонструватиме роботу зовнішніх переривань.

Запустимо Atmel Studio 7, створимо проект з ім'ямEXTI01, виберемо контролерATmega328P, додамо в main.c функцію ініціалізації портівport_ini, в якій увімкнемо ніжку світлодіода на вихід . Світлодіод на платі розташовується на ніжціB6

void port_ini (void)

//Включимо ніжку світлодіода на вихід

DDRB = 0b00100000;

Викликаємо цю функцію вmain()

int main (void)

port_ini ();

while (1)

Підключимо кнопку між ніжкою PD2 (D2) та загальним проводом

буде

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

void int_ini (void)

//включимо переривання INT0 по низхідному фронту

EICRA = (1

// дозволимо зовнішні переривання INT0

EIMSK = (1

Викликаємо цю функцію в main(), а також не забуваємо включитиглобальні переривання

int_ini();

sei();

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

//Включимо ніжку INT0 (PD2) на вхід

//Підтягнемо резистор на ніжці INT0 (PD2) до живлення

PORTD = 0b00000100;

Також ще нам необхідно додати сам обробник переривання, в якому за виникненням налаштованої події на ніжці порту будемо запалювати наш світлодіод.

ISR ( INT0_vect )

PORTB = 0b00100000;

Зберемо код, пройдемо контролер і спробуємо натиснути кнопку

INT0

Як ми бачимо, світлодіод у нас спалахнув.

Тепер спробуємо також випробувати й іншу ніжку - INT1.

Для цього спочатку налаштуємо цю ніжку вport_ini()

//Включимо ніжкі INT0і INT1 (PD2і PD3 ) на вхід

(0b00001 100);

//Підтягнеморезистори на ніжках INT0і INT1 (PD2і PD3 ) до харчування

PORTD = 0b00001 100;

Потім переналаштуємо переривання з урахуванням даної ніжки і функціїint_ini()

//включимо переривання INT0і INT1 по низхідному фронту

EICRA =(1

// дозволимо зовнішнє переривання INT0та INT1

EIMSK =(1

А ось обробник у цієї ніжки свій окремий, тому додамо його і світлодіод у ньому гаситимемо

ISR (INT1_vect)

Тепер ми можемо підключити ще кнопку на ніжкуPD3 (D3), вторим проводам також підключивши її до спільного дроту, зібрати код, прошити контролер і натиснути кнопки і відстежити результати зміни рівнів світлодіода

INT0

Тепер, якщо ми зберемо код і пройдемо контролер, то перша кнопка буде у нас світлодіод запалювати, а друга гаситиме.

Здавалося б, що тут такого? А те, що відбувається це вже незалежно від ходу самої програми, не в нескінченному циклі, коли під час написаного там обробленого по натисканню кнопки ми можемо взагалі не знаходитися і буде вже не ясно, чи обробиться наша подія. Тому, вивчивши зовнішні переривання, ми зробили великий крок до незалежності обробки тих чи інших подій на ніжках портів мікроконтролера. Звичайно, враховуючи наш уже тепер дуже багатий досвід, нам було це зробити не дуже тяжко.

Придбати плату Arduino UNO R3 можнатут.

Дивитись ВІДЕОУРОК (натисніть на картинку)