Внешние прерывания
Прерывание – это событие, при котором происходит приостановка основной программы и переход на выполнение подпрограммы прерывания. Чтобы узнать какие же есть прерывания в МК, нужно открыть даташит микроконтроллера и найти раздел Interrupts. В самом начале можно увидеть таблицу векторов прерываний.
Таблица 3 – Таблица векторов прерываний для МК Atmega16
В каждом векторе прерывания находится команда перехода с адресом начала подпрограммы прерывания. Любая программа начинается с Reset, в котором находится команда перехода к блоку инициализации. А дальше, каждое прерывание настроено на какое-то событие и при срабатывании этого события программа переходит к обработчику этого прерывания. Видно, что каждому прерыванию соответствует свой вектор прерывания. Чем выше адрес прерывания, тем ниже приоритет прерывания. Т.е. в очереди прерываний, прерывания с большим приоритетом будут выполняться раньше. Если началась обработка какого-нибудь прерывания, никакое другое не может быть вызвано, даже с большим приоритетом. Иначе получался бы рекурсивный вызов обработчиков прерываний и сложнее было бы отследить работу программы. При вызове обработчика любого прерывания бит глобального разрешения прерываний I регистра SREG (status register - регистр состояния) сбрасывается в "0"и только по завершении обработки прерывания снова устанавливается в "1" и разрешает начать обработку следующего прерывания в очереди. Чтобы установить ручками этот бит существует функция sei(), а чтобы сбросить - cli(). При запуске программы этот бит всегда сброшен и чтобы прерывания срабатывали его нужно установить (вызвать sei()).
Итак, в этой статье нас будут интересовать только внешние прерывания, т.е. те прерывания, которые возникают при изменении состояния определенных входом МК. Из таблицы векторов прерываний видно, что у МК ATmega8 таких прерываний 2 - INT0 и INT1 и их приоритет выше других прерываний. Жмем в даташите External Interrupts и обнаруживаем интересную вещь. Для настройки этих прерываний нужно воспользоваться регистрами MCUCR (MCU Control Register - регистр управления) и GICR (General Interrupt Control Register - общий регистр управления прерываниями). Рассмотрим их подробней.
MCUCR
Рис. 1.10 – Регистр MCUCR
Бит 1, 0 - ISC01, ISC00: Настройка условия срабатывания прерывания INT0 (таблица 4).
Таблица 4 – Настройка условия срабатывания прерывания INT0
Бит 3, 2 - ISC11, ISC10: Настройка условия срабатывания прерывания INT1 (таблица 5)
Таблица 5 – Настройка условия срабатывания прерывания INT0
Биты 4-7 относятся к управлению питанием и здесь рассматривать их не будем. Регистр GICR
Рис. 1.11 – Регистр GICR
Бит 7 - INT1: Разрешает внешнее прерывание 1 ("1" - разрешено, "0" - запрещено)
Бит 6 - INT0: Разрешает внешнее прерывание 0 ("1" - разрешено, "0" - запрещено)
Также любое прерывание имеет свой флаг прерывания. Этот флаг устанавливается в "1" в момент, когда должно произойти прерывание, даже если прерывания глобально запрещены и соответствующая программа обработки прерывания не вызывается. Можно, например, внутри какого-нибудь обработчика прерывания по этому флагу проверять было ли какое-либо прерывание или нет. Флаги внешних прерываний являются 7-м и 6-м битом регистра GIFR. Флаги прерываний сбрасываются записью в них "1". Регистр GIFR
Рис. 1.12 – Регистр GIFR
Бит 7 - INTF1: Флаг внешнего прерывания 1.
Бит 6 - INTF0: Флаг внешнего прерывания 0.
|