Переривання на контролері AVR Atmel AVR Studio. Переривання - Вивчаємо AVR - Каталог статей - Мікроконтролери – це просто! У якому середовищі програмувати переривання мікроконтролера

Системи переривань - важлива частина будь-якої системи, що управляє.

Від роботи багато в чому залежить те, наскільки ефективно мікропроцесорна система виконує свої функції. Загальна структура системи переривань МК-51 представлена ​​на рис. 14.3.

Мікроконтролери сімейства МК-51 забезпечують підтримку п'яти джерел переривань:

* двох зовнішніх переривань, що надходять по входах INT0 та INT1 (лінії порту Р3: Р3.2 та Р3.3 відповідно);

* двох переривань від таймерів/лічильників Т/С0 та Т/С1;

* Переривання від послідовного порту.

Запити на переривання фіксуються в регістрах спеціальних функцій мікроконтролера: прапори IE0, IE1, TF0, TF1 запитів на переривання від INT0, INT1, T/C0 та T/C1 містяться в регістрі управління TCON (табл. 14.4), а прапори RI та TI запитів на переривання від послідовного порту - у регістрі SCON управління послідовним портом.

Таблиця 14.4. Формат регістру TCON

0 IT0 Налаштування виду переривання INT0

1 IE0 Прапор запиту переривання INT0

2 IT1 Налаштування виду переривання INT1

3 IE1 Прапор запиту переривання INT1

4 TR0 Увімкнення таймера/лічильника 0

5 TF0 Прапор переповнення (запит переривання) таймера/лічильника 0

6 TR1 Увімкнення таймера/лічильника 1

7 TF1 Прапор переповнення (запит переривання) таймера/лічильника 1

Прапори TF0 і TF1 встановлюються апаратно при переповненні відповідного таймера/лічильника (точніше, при переході T/Cx зі стану "усі одиниці" у стан "усі нулі").

Прапори IE0 та IE1 встановлюються апаратно від зовнішніх переривань IT0 та IT1 відповідно. Зовнішній запит може викликати встановлення прапора або за низького рівня сигналу на відповідному вході, або при перемиканні цього сигналу з високого рівня на низький (з частотою, що не перевищує половини частоти зовнішньої синхронізації МК).

Налаштування на тип запиту здійснюється програмною установкою біт IT0 та IT1 у регістрі управління TCON. Установка ITx = 0 налаштовує систему переривання на запит за низьким рівнем сигналу, ITx = 1 - запит переривання по спаду сигналу.

Прапори TI та RI встановлюються апаратно схемою послідовного інтерфейсу після закінчення передачі або після закінчення прийому відповідно.

Усі вказані прапори запитів на переривання програмно доступні для встановлення та скидання. Програмна установка прапора запиту на переривання призводить до такої реакції мікроконтролера, що і апаратна установка того ж прапора.

Прапори TF0 і TF1 скидаються апаратно під час передачі управління програмі обробки відповідного переривання.

Скидання прапорів IEx виконується апаратно при обслуговуванні переривання лише в тому випадку, якщо переривання було налаштоване на сприйняття спаду сигналу INTx. Якщо переривання було налаштоване на сприйняття рівня сигналу запиту, то скидання прапора IEx має виконувати програму обслуговування переривання, впливаючи на джерело переривання для зняття запиту.

Прапори TI та RI скидаються лише програмним шляхом.

Кожен вид переривання індивідуально дозволяється або забороняється установкою або скиданням відповідних розрядів регістру дозволу переривання IE. Цей регістр містить і біт загальної заборони всіх переривань. ФорматреєструIE наведено в табл. 14.5.

Таблиця 14.5. Призначення розрядів регістру IE

Позиція у регістрі

Мнемоніка бита

Функція

Заборона переривання від усіх джерел

Не використовується

Не використовується

Заборона переривання від послідовного порту

Заборона переривання від таймера/лічильника T/C1

Заборона переривання від зовнішнього джерела INT1

Заборона переривання від таймера/лічильника T/C0

Заборона переривання від зовнішнього джерела INT0

Кожному виду переривання може бути програмно присвоєний один із двох можливих пріоритетів: 0 – нижчий або 1 – вищий.

Налаштування пріоритетів здійснюється встановленням або скиданням відповідного біта регістру пріоритетів переривань IP. Формат цього регістру наведено у табл. 14.6.

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

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

IT0 -> TF0 -> IT1 -> TF1 -> (RI, TI)

Таблиця 14.6. Призначення розрядів регістру IP

Позиція в регістрі Мнемоніка біта Функція

7 - Не використовується

6 - Не використовується

5 - Не використовується

4 PS Пріоритет переривання від послідовного порту

3 PT1 Пріоритет переривання від таймера/лічильника T/C1

2 PX1 Пріоритет переривання від зовнішнього джерела INT1

1 PT0 Пріоритет переривання від таймера/лічильника T/C0

0 PX0 Пріоритет переривання від зовнішнього джерела INT0

Апаратно реалізований виклик обробника переривань складається з наступних дій:

* Збереження значення програмного лічильника в стеку;

Точки входу в обробник переривання для кожного джерела переривань апаратно зафіксовані. Їхні значення наведені в табл. 14.7.

Таблиця 14.7. Адреси точок входу в обробники переривань

Джерело переривання

Адреси точок входу в обробники переривань

Зовнішнє переривання ( ITO)

Таймер-лічильник (TFO)

Зовнішнє переривання (IT1)

Таймер-лічильник (TF1)

Послідовний порт (R1 або T1)

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

При переході на підпрограму обробки переривання автоматично незалежно від стану регістру IE забороняються всі переривання, які мають рівень пріоритету, що дорівнює рівню пріоритету переривання, що обслуговується, - тобто вкладені переривання з рівним рівнем пріоритету заборонені. Таким чином, низькопріоритетне переривання (має "0" у відповідному розряді регістра IP) може перериватися високопріоритетним (має "1" у відповідному розряді регістра IP), але не низькопріоритетним. Обслуговування високопріоритетного переривання може бути перервано іншим джерелом.

Повернення з обробника переривань здійснюється за допомогою команди RETI, яка відновлює зі стека значення програмного лічильника PC, збереженого там у момент виклику обробника переривання, та логіку пріоритетів переривань.


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

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

На цьому прикладі видно два види переривань, перше – пов'язане з виконанням основної роботи – пошук засобу для жирного посуду – внутрішнє переривання, друге – телефонний дзвінок- Зовнішнє переривання.
У мікроконтролері зовнішні переривання виникають за рахунок сигналів, що надходять від інших джерел, внутрішні – за рахунок пристроїв, вбудованих у сам мікроконтролер. Чим же такі привабливі переривання?
Перше - те, що ми можемо зупинити основний процес до виконання будь-яких інших функції, з наступним продовженням цього процесу.
Другим, і напевно у багатьох випадках основним вважається прискорення процесу виконання всіх функцій, за рахунок внутрішніх додаткових пристроїв. Повернемося до нашого прикладу. Допустимо, мій друг взявся мити посуд, коли його дружина вже прийшла додому. Побачивши жирний посуд, він просить його знайти засіб для миття посуду, і доки він миє, вона вже принесе йому цей засіб. Але, ось задзвонив телефон, слухавку підніме дружина, поговорить із мамою і сходить до магазину. Спільно всі справи зроблено дуже швидко!
А ще простіше зациклиться - тобто. основної програми немає.
Мій друг сидить на дивані і нічого не робить, доморобітниця побачивши брудний посуд, говорить йому про це, і отримавши дозвіл, починає мити сама. Коли дзвонить телефон, він каже дружині, щоб вона підняла слухавку, дружина розмовляє телефоном, і поле розмови йде до магазину за продуктами… Краса! У такому разі в мікроконтролері одночасно працюють кілька пристроїв введення-виведення (у сучасних мікроконтролерах їх може бути досить багато) і загальна продуктивність процесора зростає у багато разів, але переривання від пристроїв обробляються послідовно одне за одним (не одночасно), залежно від пріоритету ( у нашому прикладі дружина має більший пріоритет, ніж доморобітниця).

За управління перериваннями відповідають кілька регістрів
SREG - регістр статусу(Стану). Дивимося таблицю пристроїв вводу-виводу. Сьомий біт регістру SREG – прапор I (interrupt), який називається прапором глобального дозволу переривань.Якщо прапор опущений (сьомий біт дорівнює нулю), всі переривання заборонені. Якщо підняти прапор (встановити I в 1), ми дозволимо переривання.

Встановлюється та скидається прапор І командами:
SEI - дозволити переривання
CLI - заборонити переривання
Які з переривань працюватимуть, задається за допомогою регістрів званих – масками переривань.
Позначаються маски переривань наступним чином:
TIMSK,..,..,.. – керування перериваннями від таймерів та інших вбудованих пристроїв.
GIMSK (GIKR у сімействі Mega) - управління всіма зовнішніми перериваннями.
Маски переривань у свою чергу залежать від прапорів переривань:
TIFR та GIFR відповідно(Не плутайте з прапором глобального дозволу переривань).

Послідовність виконання переривань:
При включенні мікроконтролера всі прапори переривань скинуті в 0. Для включення переривань програма має встановити прапор I регістру SREG в 1. Після цього прописати регістри маски зі встановленими локальними перериваннями (переривання, які нам потрібні).
Коли приходить (сигнал) запит на переривання, він піднімає прапор переривання (навіть у разі якщо переривання заборонено, в організацію вкладених переривань і пріоритету між різними перериваннями). Якщо немає заборони переривань, то контролер звернеться до відповідного (Interrupt Vectors) - вектор переривань, призупиняючи поточну програму.
Вектор переривання– це фіксований рядок програмної області, куди переходить програма у разі переривання.
Весь список векторів переривання – називається таблицею векторів переривання, який розташовується на початку програмного коду.
Отже, у момент звернення до вектора переривання, прапор I регістру SREG і прапор, що викликав переривання, скидається в 0, забороняючи інші переривання. Якщо в процесі виконання переривання виникли інші запити переривань, прапори цих переривань залишаються піднятими. Після закінчення виконання поточного переривання прапор I регістру SREG піднімається, дозволяючи виконання наступного. Якщо надійшло кілька запитів, і їхні прапори виявляться піднятими, то першим буде виконано переривання, чий вектор менший за адресою в таблиці, ближче до початку пам'яті. За ним другий, і таке інше. Крім цього, програміст може організувати так зване вкладене переривання, коли в процесі виконання програми переривання виникає ще одне переривання. Тоді припиняється виконання поточного переривання та виконується нове, після завершення якого поновлюється виконання зупиненого переривання.

Як приклад наведена таблиця векторів переривання для ATtiny2313

Таблиця векторів переривання для Атмега16 виглядає так:

При порівнянні таблиці зовсім не збігаються.
У сімействі ATtiny рядок вектора переривання займає 16 біт, а в сімействі Mega займають 32 біти (зверніть увагу на адреси векторів переривання, нагадаю, що адресний рядок у програмній області представлений 16 бітним словом).

Програмний код для ATtiny2313 може виглядати так:
.cseg .org 0 rjmp Reset rjmp INT_0 rjmp INT_1 rjmp Timer1_capt1 rjmp Timer1_comp1 rjmp Timer1_OVF1 rjmp Timer0_OVF0 rjmp UART_RX rjmp UART_UDRE rjmp UART B rjmp Timer0_compA rjmp Timer0_compB rjmp USI_START rjmp USI_OVERFLOW rjmp EE_READY rjmp WDT_ OVERFLOW

Як бачимо, вектор переривання створює відносний перехід на мітки програм переривань. Нижче у таблиці показані варіанти; 1. Коли немає переривань; 2, 3. із зовнішнім перериванням по входу INT_1.
Якщо мітки «порожні» (під міткою немає програми), то нічого не відбувається, і програма послідовно «пробігшись» по мітках, що залишилися, благополучно доходить до команди RETI- Interrupt return - вихід з обробника перериванняяк показано у першому стовпці таблиці.

Щоб виконати програму переривання, наприклад на вході INT_1, потрібно мітку INT_1: винести зі списку. Це схематично показано у другому стовпці таблиці.
Але, програмісту незручно щоразу прописувати всі переривання та окремо мітки до них, особливо в останніх моделях, де таблиця досить велика, простіше в рядку вектора переривання відразу написати команду RETI, якщо переривання не використовується. Тоді програма буде виглядати, як показано у третьому стовпчику таблиці.

В AVR-контролерах залежно від моделі може бути від 1 до 8 входів зовнішніх переривань.
Розглянемо систему керування зовнішніми перериваннями. Для цього передбачені такі комбінації I/O-регістрів залежно від моделі (див. відповідний DataSheet):
- GIMSK, EIFR, PCMSK, MCUCR;
- GIKR, GIFR, MCUCR;
- EIMSK, EICR, EIFR;
GIMSK, GIKR, EIMSK - маски переривань,
EIFR, PCMSK, GIFR, EIFR – прапори переривань
Для дозволу чи заборони зовнішніх перериваньпризначені керуючі регістри: GIMSK-(General Interrupt Mask Register)(Tiny), GICR-(General Interrupt Control Register)(Mega), MCUCR - (MCU Control Register)




EIFR- External Interrupt Flag Register: 1- дозволено, 0 – заборонено. Кожен біт (прапор) дозволяє відповідному висновку працювати як джерело переривань.

Біти управління регістра GIMSK:
Біт 7 - INT1: External Interrupt Request 1 Enable – біт дозволу переривання INT1: 1 – дозволено, 0 – заборонено. Переривання буде формуватися, навіть якщо висновок INT1 налаштований як вихід. Біт INT1 налаштовуються на переривання у регістрі прапорів EIFR. Висновок INT1 синхронізований із тактовим генератором.

Біт 6 - INT0: External Interrupt Request 0 Enable - біт дозволу переривання INT0: 1 - дозволено, 0 - заборонено. Переривання буде формуватися, навіть якщо висновок INT0 налаштований як вихід. Біт INT0 налаштовуються на переривання у регістрі прапорів EIFR. Висновок INT10 синхронізований із тактовим генератором.

Біт 5 - PCIE: Pin Change Interrupt Enable - біт дозволу переривання на висновках PCINT0 ... 7: 1 - дозволено, 0 - заборонено. Будь-яка зміна на будь-якому висновку PCINT0…7 буде формувати переривання. Висновки PCINT0 ... 7 налаштовуються на переривання індивідуально, бітами в регістрі прапорів PCMSK.

PCMSK- Pin Change Mask Regiser - регістр прапорів PCMSK: 1- дозволено, 0 – заборонено. Кожен біт (прапор) дозволяє відповідному висновку працювати як джерело переривань. Висновки PCINT0…7 не синхронізовані з тактовим генератором, тобто. переривання настає за фактом зміни на будь-якому висновку.

Mega8

та відповідний йому регістр прапорів


Біт 7

Біт 6 - INT0: External Interrupt Request 0 Enable - біт дозволу переривання INT0: 1 - дозволено, 0 - заборонено. Переривання буде формуватися, навіть якщо висновок INT0 налаштований як вихід. Біт INT0 налаштовуються на переривання у регістрі прапорів GIFR



GIFR - General Interrupt Flag Register: 1- дозволено, 0 - заборонено. Кожен біт (прапор) дозволяє відповідному висновку працювати як джерело переривань.

Біти управління регістру GICR:
Біт 7– : External Interrupt Request 1 Enable – біт дозволу переривання INT1: 1 – дозволено, 0 – заборонено. Переривання буде формуватися, навіть якщо висновок INT1 налаштований як вихід. Біт INT1 налаштовуються на переривання у регістрі прапорів GIFR

Біт 6 - INT0: External Interrupt Request 0 Enable - біт дозволу переривання INT0: 1 – дозволено, 0 – заборонено. Переривання буде формуватися, навіть якщо висновок INT0 налаштований як вихід. Біт INT0 налаштовуються на переривання у регістрі прапорів GIFR

Біт 5 - INT2: External Interrupt Request 2 Enable - біт дозволу переривання INT2: 1 – дозволено, 0 – заборонено. Переривання буде формуватися, навіть якщо висновок INT2 налаштований як вихід. Біт INT2 налаштовуються на переривання у регістрі прапорів GIFR

Функціями входів INT0 та INT1 у всіх контролерах управляють молодші біти регістру MCUCR

MCUCR-MCU Control Register
Біти управління:
Біти 1, 0 – ISC01, ISC00 (Interrupt Sense Control 0 Bit 1 and Bit 0) – стан даних бітів визначає подію виведенні INT0, у якому формується переривання INT0:
ISC01 = 0, ISC00 = 0 - рівень логічного нуля;
ISC01=0, ISC00=1 – будь-яка зміна логічного стану;
ISC01 = 1, ISC00 = 0 - по спадаючому фронту;
ISC01 = 1, ISC00 = 1 - по наростаючому фронту.

Біти 3, 2 – ISC11, ISC10 (Interrupt Sense Control 1 Bit 1 and Bit 0) – стан даних бітів визначає рівень сигналу на виведенні INT1, яким формується переривання INT1:
ISC11 = 0, ISC10 = 0 - рівень логічного нуля;
ISC11=0, ISC10=1 – будь-яка зміна логічного стану;
ISC11=1, ISC10=0 – по спадаючому фронту;
ISC11 = 1, ISC10 = 1 - по наростаючому фронту.

Ну от, начебто з мінімумом про зовнішні переривання поговорили.
Зрозуміло, що для того, щоб переривання працювали, потрібно їх відповідно прописувати.
Допишемо розпочату для tiny, ініціалізацію переривання на INT1 по зростаючому фронту сигналу:

Ldi r16,0x80; запишемо в r16 число 0b10000000 ldi r17,0x0C; запишемо в r17 число 0b00001100 out MCUCR, r17; переривання сформується по наростаючому фронту ISC11 = 1, ISC10 = 1 out GIMSK, r16; виставимо маску INT0 sei
До речі на tiny2313 можна сформувати переривання на будь-яких висновках PCINT0…7, на Mega до 48 серії ці можливості відсутні.
Є такі операції, при виконанні яких переривання, що виникли, можуть викликати збій програми. У разі перед початком виконання операції пишемо CLI, а після SEI. Називаються такі операції. атомарними.
Бажано, щоб програми переривань були компактними та виконувались з максимальною швидкістю, тому що метою будь-яких переривань є фіксація події. Якщо по різних причинпрограма виконується повільно, достатньо зафіксувати подію і обробити її трохи пізніше.

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

Однією з переваг мікроконтролера ATmega8 є широкий діапазон різних переривань.

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

Переривання поділяються на внутрішні та зовнішні. До джерел внутрішніх переривань відносяться вбудовані модулі мікроконтролера (таймери, приймач USART і т.д). Зовнішні переривання виникають при надходженні зовнішніх сигналів висновки мікроконтролера (наприклад сигнали висновки RESET і INT). Характер сигналів, що призводять до виникнення переривання, задається в регістрі управління MCUCR, зокрема в розрядах - ISC00 (біт 0) та ISC01 (біт 1) для входу INT 0; ISC10 (біт2) та ISC11 (біт3) для входу INT1.

У мікроконтролері ATmega8 кожному перериванню відповідає свій вектор переривання(Адреса на початку області пам'яті програм, в якій зберігається команда для переходу до заданої підпрограми обробки переривання). У mega8 усі переривання мають однаковий пріоритет. У разі одночасного виникнення кількох переривань першим оброблятиметься переривання з меншим номером вектора.

Вектори переривань в Atmega8

Адреса Джерело переривання Опис
0x0000 RESET Сигнал скидання
0x0001 INT0 Зовнішній запит на переривання на вході INT0
0x0002 INT1 Зовнішній запит на переривання на вході INT1
0x0003 T/C1 Захоплення за таймером T/C1
0x0004 T/C1 Збіг з регістром порівняння A таймера T/C1
0x0005 T/C1 Збіг з регістром порівняння B таймера T/C1
0x0006 T/C1 Переповнення лічильника T/C1
0x0007 T/C0 Переповнення лічильника T/C0
0x0008 SPI Передача даних за інтерфейсом SPI завершена
0x0009 UART Прийом даних приймачем UART завершено
0x000A UART Реєстр даних UART порожній
0x000B UART Передача даних приймачем UART завершена
0x000C ANA_COMP Переривання від аналогового компаратора

Управління перериваннями

За управління перериваннями в ATmega8 відповідають 4 регістри:

GIMSK(він же GICR) - заборона/дозвіл переривань за сигналами на входах INT0, INT1

GIFR- керування всіма зовнішніми перериваннями

TIMSK, TIFR- керування перериваннями від таймерів/лічильників

Реєстр GIMSK(GICR)

INTFx=1: відбулося переривання на вході INTx. При вході в підпрограму обробки переривання INTFx автоматично скидається в стан лог. 0

Реєстр TIMSK

7 6 5 4 3 2 1 0
TOIE1
OCIE1A
OCIE1B
-
TICIE
-
TOIE0
-

TOIE1=1: переривання по переповненню T/C1 дозволено

OCIE1A=1: переривання при збігу регістру порівняння A із вмістом лічильника T/C1 дозволено

OCIE1B=1: переривання при збігу регістра порівняння B із вмістом лічильника T/C1 дозволено

TICIE=1: дозволено переривання при виконанні умови захоплення

TOIE0=1: переривання по переповненню T/C0 дозволено

Реєстр TIFR

7 6 5 4 3 2 1 0
TOV1
OCF1A
OCF1B
-
ICF1
-
TOV0
-

TOV1=1: відбулося переповнення T/C1

OCF1A=1: стався збіг регістру порівняння A із вмістом лічильника T/C1

OCF1B=1: стався збіг регістру порівняння B із вмістом лічильника T/C1

ICF=1: виконалися умови захоплення

TOV0=1: відбулося переповнення T/C0

При вході в підпрограму обробки переривання відповідний переривання прапор регістра TIFR автоматично скидається в стан лог. 0

Переривання працюють лише тоді, як у регістрі стану SREG дозволені загальні переривання (біт 7 = 1). У разі переривання цей біт автоматично скидається в 0, блокуючи виконання наступних переривань.

У цьому прикладі висновок INT0 включений у режимі входу з підтяжкою. При замиканні виведення на землю за допомогою кнопки на ньому встановлюється лог.0 (фронт сигналу спадає з напруги живлення до 0) і спрацьовує обробник переривання, що включає лампочку, підключену до нульового виведення порту B

void lampON()
{
PORTB.0=1;
DDRB.0 = 1;
}

interrupt void ext_int0_isr(void)
{
lampON();
}

DDRD.2 = 0;
PORTD.2 = 1;

SREG|= (1 while(1) (

На наведеному прикладі також видно, як задаються вектори переривань Code Vision AVR (interrupt void ext_int0_isr(void)). Аналогічно задаються вектори переривань і для інших випадків:

EXT_INT0 2
EXT_INT1 3
TIM2_COMP 4
TIM2_OVF 5
TIM1_CAPT 6
TIM1_COMPA 7
TIM1_COMPB 8
TIM1_OVF 9
TIM0_OVF 10
SPI_STC 11
USART_RXC 12
USART_DRE 13
USART_TXC 14
ADC_INT 15
EE_RDY 16
ANA_COMP 17
TWI 18
SPM_READY 19

В склад AVR мікроконтролеріввходить велика кількість периферійних пристроїв (ADC, Timer/Counters, EXTI, Analog Comparator, EEPROM, USART, SPI, I2C і т.д.), кожен з яких може виконувати певні дії над даними/сигналами та ін. Ці пристрої вбудовані в мікроконтролер для підвищення ефективності застосування та зниження витрат при розробці різноманітних пристроїв на базі AVR мікроконтролерів.

Процесор спілкується/керує периферійними пристроями за допомогою регістрів вводу/виводу (I/O Registers), які розміщуються у пам'яті даних (Data Memory), що дозволяє використовувати їх як звичайні змінні. Кожен пристрій має свої регістри вводу/виводу.

Усі регістри вводу/вывода (I/O Registers) можна розділити втричі групи: регістри даних, регістри управління і регістри стану.

За допомогою регістрів управління (Control Registers) реалізується налаштування пристрою для роботи в тому чи іншому режимі, з певною частотою, точністю і т.д., а за допомогою регістрів даних (Data Registers) зчитується результат роботи даного пристрою(Аналого-цифрове перетворення, прийняті дані, значення таймера/лічильника і т.д.). Здається, нічого складного тут немає (взагалі-то тут і справді нічого складного немає:)), ввімкнув пристрій, вказав бажаний режим роботи, а потім тільки залишається стригти купони читати готові дані і використовувати їх у обчисленнях. Все питання полягає в тому "коли" читати ці самі дані (завершив пристрій роботу або все ще обробляє дані), адже всі периферійні пристрої працюють паралельно з ядром мікроконтролера, та ще й на різних частотах. Постає питання реалізації спілкування та синхронізації між процесором і периферійним пристроєм.

Як ви вже напевно здогадалися, для реалізації спілкування та синхронізації між пристроєм і процесором використовуються "регістри стану" (Status Registers), в яких зберігається поточний стан роботи того чи іншого пристрою. стану” (прапор), поточне значення якого, "говорить" про поточний стан даного пристрою або його окремо взятої функції (робота завершена/не завершена, помилка при обробці даних, регістр порожній і т.д.).

Механізм спілкування між процесором і периферійним пристроєм реалізується шляхом опитування прапорів (flag polling), що відповідають за ту чи іншу функцію даного пристрою. Залежно від значення того чи іншого прапора (стан пристрою) можна змінювати хід виконання програми (розгалуження). Наприклад:

Перевірка якщо певний прапор встановлено (відбулася певна подія):

if (RegX & (1<< Flag) ) // якщо прапор у регістрі RegX встановлено
{
// роби щось
}

Очікування завершення будь-якої дії (подія):

while (! (RegX & (1<

Опитування прапорів – заняття досить ресурсомістке, як у плані обсягу програми, і у плані швидкодії програми. Оскільки загальна кількість прапорів в AVR мікроконтролерах досить велика (перевага), то реалізація спілкування між процесором і пристроєм шляхом опитування прапорів призводить до зниження ККД (швидкість коду/розмір коду) написаної вами програми, до того ж програма стає дуже заплутаною, що сприяє появі помилок, які важко виявити навіть при детальному налагодженні коду.

Для того, щоб підвищити ККД програм для AVR мікроконтролерів, а також полегшити процес створення та налагодження даних програм, розробники забезпечили всі периферійні пристрої "джерелами переривань" ( Interrupt sources), деякі пристрої можуть мати кілька джерел переривання.

За допомогою джерел переривань реалізується механізм синхронізаціїміж процесором і периферійним пристроєм, тобто процесор почне прийом даних, опитування прапорів та ін дії над периферійним пристроєм тільки тоді, коли пристрій буде до цього готовий (повідомить про завершення обробки даних, помилку при обробці даних, регістр порожній, і т.д. д.), шляхом генерації "запиту на обробку переривання" ( Interrupt request), залежно від значення деякого прапора (стан пристрою/функції/події).

У літературі, дуже часто, весь ланцюжок подій, починаючи від "запиту на обробку переривання" (IRQ) і до "процедури обробки переривання" (ISR), скорочено називають - переривання ( Interrupt).

Що таке переривання?


Переривання (Interrupt) – сигнал, що повідомляє процесору про настання будь-якої події. При цьому виконання поточної послідовності команд припиняється і управління передається процедурі обробки переривання, що відповідає даній події, після чого виконання коду триває рівно з того місця, де він був перерваний (повернення управління). (Wiki)

Процедура обробки переривання(Interrupt Service Routine) – це ні що інше як функція/підпрограма, яку слід виконати у разі виникнення певної події. Будемо використовувати саме слово "процедура", щоб підкреслити її відмінність від усіх інших функцій.

Головна відмінність процедури від простих функцій полягає в тому, що замість звичайного "повернення з функції" (ассемблерова команда RET), слід використовувати "повернення з переривання" (асемблерна команда RETI) - " RETurn from Interrupt".

Властивості AVR переривань:

  • Кожен периферійний пристрій, що входить до складу AVR мікроконтролерів, має як мінімум одне джерело переривання (Interrupt source). До всіх цих переривань слід віднести і переривання скидання – Reset Interrupt, призначення якого відрізняється від інших.
  • За кожним перериванням, суворо закріплений вектор (посилання), що вказує на процедуру обробки переривання (Interrupt service routine). Всі вектори переривань розташовуються на самому початку пам'яті програм і разом формують "таблицю векторів переривань" (Interrupt vectors table).
  • Кожному перериванню відповідає певний "біт активації переривання" (Interrupt Enable bit). Таким чином, щоб використовувати певне переривання, слід записати в його біт активації переривання - лог. одиницю. Далі, незалежно від того активували Ви чи ні певні переривання, мікроконтролер не почне обробку цих переривань, поки в "біт загального дозволу переривань" (Global Interrupt Enable bit в регістрі стану SREG) не буде записана лог. одиниця. Також, щоб заборонити всі переривання (на невизначений час), в біт загального дозволу переривань слід записати - лог нуль.

Переривання Reset, на відміну всіх інших, не можна заборонити. Такі переривання ще називають Non-maskable interrupts.

  • У кожного переривання є певний пріоритет. Пріоритет переривання залежить від його розташування в "таблиці векторів переривань". Чим менший номер вектора в таблиці, тим вище пріоритет переривання. програм.Зовнішнє переривання INT0, що йде слідом за перериванням Reset в "таблиці векторів переривань", має пріоритет менше ніж у Reset, але вище ніж у всіх інших переривань і т.д.

Таблиця векторів переривань, крім вектора Reset, може бути переміщена на початок Boot розділу Flash пам'яті, встановивши біт IVSEL у регістрі GICR. Вектор скидання також може бути переміщений на початок Boot розділу Flash пам'яті, шляхом програмування біта фьюз – BOOTRST.



Таблиця векторів переривань ATmega16

Прототип процедури обробки переривання


Щоб оголосити деяку функцію як процедуру обробки того чи іншого переривання, необхідно дотримуватися певних правил прототипування, щоб компілятор/компонувальник змогли правильно визначити і пов'язати необхідне переривання з процедурою її обробки.

По-перше, процедура обробки переривання не може нічого приймати як аргумент (void), а також не може нічого повертати (void). Це пов'язано з тим, що всі переривання в AVR асинхронні, тому не відомо де буде перервано виконання програми, у кого приймати і кому повертати значення, а також для мінімізації часу входу та виходу з переривання.

void isr (void)

По-друге, перед прототипом функції слід зазначити, що вона є процедурою обробки переривання. Як вам відомо, у мові Сі виконується лише той код, що використовується у функції main. Оскільки процедура обробки переривання функції main ніде не використовується, то для того щоб компілятор не "викинув" її за непотрібністю, перед прототипом процедури слід вказати що ця функція є процедурою обробки переривання.

Прототип процедури обробки переривання у середовищі AVR Studio

#include

ISR (XXX_vect)
{

}

В AVR Studio (AVR GCC), кожна процедура обробки переривання починається з макровизначення ISR, після чого в круглих дужках слідує конструкція:

XXX_vect

де "XXX" це ім'я вектора переривання. Всі імена векторів, для певного AVR мікроконтролера, можна знайти в "таблиці векторів переривань" даташита даного мікроконтролера або його заголовному файлі. Наприклад, "таблиця векторів переривань" для мікроконтролера ATmega16 наведена на рис.1, де в колонці Source, наведені всі імена векторів переривань. Також імена можна подивитися в заголовному файлі даного мікроконтролера (C: Program Files Atmel AVR Tools AVR Toolchain\avr\include\avr\iom16.h), див.рис.2 Все що нам треба зробити, це знайти в таблиці ім'я потрібного нам вектора і до нього додати суфікс "_vect".


Рис.2 Заголовковий файл ATmega16 для AVR Studio

Наприклад, напишемо процедуру обробки переривання прийому байта через USART (USART, Rx Complete) :

ISR (USART_RXC_vect)
{
// Тіло оброблювача переривання
}

До речі: перед тим як використовувати будь-яке переривання в AVR Studio, слід включити в проект заголовки io.h і interrupt.h:

#include
#include

Докладніше про обробників переривань в AVR Studio (AVR GCC) можна почитати у розділі Introduction to avr-libc's interrupt handling.

Прототип процедури обробки переривання у середовищі ImageCraft

#pragma interrupt_handler : iv_XXX
void< handler_name>(void)
{
// Тіло оброблювача переривання
}

У середовищі ImageCraft прототип процедури обробки переривання виглядає наступним чином:

void< handler_name>(void)

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

#pragma interrupt_handler : iv_XXX

де це ім'я тієї функції, що буде використовуватися як обробник переривання, а конструкція "iv_XXX", це ім'я вектора переривання (XXX) з префіксом "iv_". Як і у випадку з AVR Studio, всі імена векторів, для певного AVR мікроконтролера, можна знайти в "таблиці векторів переривань" даташита даного мікроконтролера або його заголовному файлі (див. рис.3).


Рис.3 Заголовковий файл ATmega16 для ImageCraft IDE

Наприклад, процедура обробки переривання по прийому байта через USART (USART, Rx Complete) в середовищі ImageCraft буде виглядати так:

#pragma interrupt_handler usat_rxc_isr: iv_USART_RXC
void usat_rxc_isr(void )
{
// Тіло оброблювача переривання
}

Докладніше про процедури обробки переривання в ImageCraft IDE можна знайти в меню Help->Programming the AVR->Interrupt Handlers середовища розробки.

Іноді, якщо кілька обробників переривання повинні робити те саме, то для економії пам'яті програм, можна направити кілька векторів переривання на ту саму процедуру обробки переривання.

У середовищі AVR Studio це виглядає так:

ISR (INT0_vect)
{
// Do something
}
ISR(INT1_vect, ISR_ALIASOF(INT0_vect) );

Спочатку йде процедура обробки переривання для певного вектора, у разі INT0. Всі інші процедури можуть посилатися на будь-який обробник переривання за допомогою конструкції:

ISR (YYY_vect, ISR_ALIASOF(XXX_vect) );

де YYY це ім'я вектора переривання, який посилається на раніше оголошений обробник переривання для вектора XXX.

У середовищі ImageCraft це виглядає так:

#pragma interrupt_handler : iv_XXX : iv_YYY
void< handler_name>(void)
{
// Тіло оброблювача переривання
}

#pragma interrupt_handler : iv_XXX
#pragma interrupt_handler : iv_YYY
void< handler_name>(void)
{
// Тіло оброблювача переривання
}

де вектори XXX і YYY посилаються на той самий обробник переривання .

Як працює переривання в мікроконтроллерах AVR?

1. Припустимо, відбувся " запит на обробку переривання” (IRQ).

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

2. Перевірка.

Якщо біт активації даного переривання встановлений (Interrupt enable bit), а також I-біт (біт загального дозволу переривань) регістру стану процесора (SREG) встановлений, то процесор починає підготовку процедури обробки переривання, при цьому біт загального дозволу переривань (I-біт регістра) SREG) скидається, забороняючи таким чином всі інші переривання. Це відбувається для того, щоб ніяка інша подія не змогла перервати обробку поточного переривання.

До речі: якщо в процедурі обробки переривання встановити I-біт стан лог. одиниці, будь-яке активоване переривання може у свою чергу перервати обробку поточного переривання. Такі переривання називаються вкладеними (Nested interrupts).

3. Підготовка.

Процесор завершує виконання поточної асемблерної команди, після чого поміщає адресу наступної команди в стек (PC-> STACK). Далі процесор перевіряє, яке джерело переривання подав "запит на обробку переривання" (IRQ), після чого скориставшись вектором даного джерела (посилання) з таблиці векторів (який залізно закріплений за кожним джерелом переривання), переходить у процедуру обробки переривання (інструкція JMP). все, про все процесор витрачає мінімум 4 такти!(залежно від моменту появи запиту та тривалість виконання поточної інструкції).Це дуже хороший час реакції на IRQ, у порівнянні з мікроконтролерами інших виробників.

До речі: якщо IRQ станеться, коли мікроконтролер перебуває у сплячому режимі (sleep mode), час реакції на IRQ збільшується ще чотири такту, плюс час закладене у ф'юз бітах SUT1 і SUT0 (Start-Up Time).

Переривання (interrupt) – подія, які потребують негайної реакції з боку процесора. Реакція у тому, що процесор перериває обробку поточної програми ( перериваної програми) і переходить до виконання деякої іншої програми ( переривання програми), спеціально призначеної для цієї події. Після завершення програми процесор повертається до виконання перерваної програми.

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

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

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

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

Як правило, управління запам'ятовуванням та поверненням покладено на обробник переривання. У цьому випадку обробник складається з трьох частин – підготовчої (пролог) та заключної (епілог), що забезпечують перемикання програм, і власне переривання програми, що виконує затребувані запитом операції. Час реакції визначається як часовий інтервал від моменту надходження запиту переривання до початку виконання програми, що перериває.


t p- Час реакції системи на переривання;
t з- Час запам'ятовування стану програми, що переривається;
t ппр- Час власне переривання програми;
t в– час відновлення стану перерваної програми

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

Якщо запит переривання виявиться не обслуженим до моменту приходу нового запиту від того самого джерела (того ж пріоритету), виникає насичення системи переривань. При цьому частину запитів переривання буде втрачено, що для нормальної роботимікроконтролера неприпустимо.

Характеристики системи перериванняє:

  • загальна кількість запитів переривання кількість джерел запитів переривання;
  • тип уявлення переривання – зазвичай, запит переривання представлений логічним рівнем сигналу;
  • пріоритет переривання – визначає черговість обробки кожного запиту переривання, що стоїть пріоритет, тим менше затримка у виконанні прерывающей програми йому;
  • час реакції - тимчасовий інтервал між появою запиту переривання і початком виконання програми, що перериває;
  • затримка переривання - визначається сумарним часом на запам'ятовування та відновлення програми;
  • глибина, зазвичай, збігається з числом рівнів пріоритетів у системі переривання;
  • насичення системи переривання;
  • допустимі моменти переривання програм (зазвичай закінчення виконання наступної команди).

Маскування перериваньвикористовується для повідомлення мікроконтролера про необхідність реагувати на кожен тип переривання або ігнорувати його. Маска переривання представляє двійковий код, розряди якого поставлені у відповідність до джерел запиту переривань. Одиничний біт у двійковому коді повідомляє мікроконтролера про необхідність обробки переривань такого типу. Нульовий біт навпаки дозволяє мікроконтролеру переходити до обробки переривань зазначеного типу.
Як правило, крім маскування переривань, існує також біт глобального дозволу переривань, нульове значення якого відключає всі обробники переривань (крім апаратного скидання і початку початку програми, що виконується).
Крім двійкового коду маски переривань існує також двійковий код прапорів переривань, який дозволяє обробнику переривань встановити джерело виникнення переривання у разі, якщо джерел із зазначеним запитом у мікроконтролері кілька.




Top