Сброс и обработка прерываний AVR

Микроконтроллеры / Для начинающих / Архитектура /

Микроконтроллеры для начинающих Что нужно для того, чтобы стать профессиональным разработчиком программ для микроконтроллеров и выйти на такой уровень мастерства, который позволит с лёгкостью найти и устроиться на работу с высокой зарплатой (средняя зарплата программиста микроконтроллеров по России на начало 2017 года составляет 80 000 рублей). Подробнее...

Прерывание - это событие, при возникновении которого программа прерывается и переходит к выполнению заранее написанного программного кода, который называется обработчиком прерывания.

Прерывания бывают внешними (например, появление сигнала на входе) и внутренними (например, переполнение таймера/счётчика).

Обработчик прерывания (начало кода обработчика прерывания) находится по определённому адресу в памяти. Адреса обработчиков прерываний находятся в самом начале памяти программ. Список адресов обработчиков прерываний называется таблицей векторов прерываний. А адрес одного прерывания называется, соответственно, вектором прерывания.

AVR предоставляет несколько различных источников прерываний. Эти прерывания и отдельный Вектор Сброса (Reset Vector) имеют отдельный Вектор Программы (Program Vector) в области памяти программы (Program memory space). Все прерывания связаны с обпределёнными битами в регистрах разрешения прерываний. Чтобы разрешить соответствующее прерывание, надо установить нужный бит. Кроме того, должен быть установлен бит Глобального Разрешения Прерываний (Global Interrupt Enable) в регистре состояния.

Самые низкие адреса в области памяти программы по умолчанию определяются как векторы Сброса (Reset) и Прерывания (Interrupt). Полный список векторов приведен в документации (мы ещё об этом будем говорить). Этот список также определяет уровни приоритета различных прерываний. Чем меньше адрес, тем выше приоритет. Прерывание RESET (сброс) имеет наивысший приоритет, а следующий приоритет у прерывания INT0 (запрос на внешнее прерывание 0).

При возникновении прерывания бит глобального разрешения прерывания (флаг I) сбрасывается, и все прерывания отключаются. Это предотвращает возможность выполнения других прерываний до того, как закончит работу текущее прерывание. В вашей программе вы можете установить флаг I для того, чтобы включить все прерывания. При этом все прерывания, работа которых разрешена индивидуальными флагами, могут после этого прервать работу текущего прерывания. Флаг I автоматически устанавливается при выполнении команды RETI (возврат из прерывания).

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

Каждое прерывание имеет свой флаг прерывания. Этот флаг устанавливается в 1 в тот момент, когда прерывание должно произойти. Даже если флаг глобального разрешения прерываний сброшен, флаг прерывания всё-равно устанавливается при возникновении события (но при этом переход к обработчику прерывания не выполняется). Если прерывания глобально запрещены, то можно программно проверить состояние флага прерывания, чтобы узнать, было ли прерывание. Флаг прерывания после возникновения события прерывания остаётся установленным до тех пор, пока его не сбросить. Подпрограмма обработки прерывания будет вызвана если:

  1. Флаг прерывания установлен
  2. Прерывания глобально разрешены

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

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

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

Второй тип прерываний будет срабатывать до тех пор, пока присутствует условие прерывания. Эти прерывания могут не иметь флагов прерываний. Если условие прерывания исчезает до включения прерывания, прерывание не будет вызвано.

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

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

При использовании инструкции CLI для отключения прерываний, прерывания будут немедленно отключены. Никакое прерывание не будет выполнено после инструкции CLI, даже если это произойдет одновременно с инструкцией CLI. Следующий пример показывает, как это может использоваться, чтобы избежать прерываний во время синхронизированной последовательности записи в EEPROM.

Пример на ассемблере:

in  r16,  SREG   ; Сохранить значения SREG 
cli              ; Отключить прерывания на время синхронизации
sbi EECR, EEMPE  ; Начать запись в EEPROM 
sbi EECR, EEPE
out SREG, r16    ; Восстановить значения SREG (I-bit)

Пример на Си:

char cSREG;
cSREG = SREG;       /* Сохранить значения SREG  */
/* Отключить прерывания на время синхронизации */
__disable_interrupt(); 
EECR |= (1<<EEMPE); /* Начать запись в EEPROM */
EECR |= (1<<EEPE);
SREG = cSREG;       /* Восстановить значения SREG (I-bit) */

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

Пример на ассемблере:

sei     ; Установить флаг глобального разрешения прерываний
sleep   ; Спящий режим в ожидании прерывания
; Примечание: переход в спящий режим 
; перед ожиданием какого-либо прерывания

Пример на Си:

/* Установить флаг глобального разрешения прерываний */
__enable_interrupt();
/* Спящий режим в ожидании прерывания */
__sleep();

Время ответа прерывания

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

Возврат из подпрограммы обработки прерываний занимает четыре такта. Во время этих четырех тактов счетчик команд (два байта) извлекается из стека, указатель стека увеличивается на два, а флаг I в регистре состояния устанавливается.


Вступить в группу "Основы программирования"

Подписаться на RUTUBE-канал

Подписаться на Дзен-канал

Подписаться на рассылки по программированию

Микроконтроллеры для ЧАЙНИКОВ Микроконтроллеры для ЧАЙНИКОВ

Бесплатная рассылка о микроконтроллерах. Рассылка содержит как бесплатную информацию для начинающих, так и ссылки на платные продукты (книги, видеокурсы и др.) для тех, кто захочет вникнуть в тему более глубоко. Подробнее...

Инфо-МАСТЕР ®
Все права защищены ©
e-mail: mail@info-master.su