Внешние прерывания

Внешние прерывания (англ. external interrupt) являются одними из самых простых функций периферии. У микроконтроллеров AVR обычно от 1 до 8 специальных выводов, при изменении логического значения или в определённом состоянии которых, создаётся прерывание в программе. Так как в основном эта функция используется для отслеживания логических сигналов вне контроллера, соответствующие выводы называются выводами внешнего прерывания.

Для использования внешнего прерывания следует настроить вывод на обычный режим входа IO (можно использовать и в режиме выхода, но в таком случае прерывание может быть создано только самим контроллером). В регистре конфигурации следует разрешить создание прерывания и указать условие, при котором оно будет выполнено. Имеется четыре возможных условия:

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

Исходя из принципов работы, существуют два вида внешних прерываний: синхронизированный с тактом контроллера и асинхронный. Синхронизированные прерывания работают, запоминая значение выводов, что означает, что логические изменения находятся путём сравнения значений, полученных от двух разных тактов. Если логические изменения внешнего сигнала происходят быстрее, чем идёт рабочий такт, то прерывания либо создаются неверно, либо вовсе пропускаются. Асинхронные прерывания не зависят от такта контроллера и позволяют определить быстро меняющийся внешний сигнал – логический нуль должен удерживаться сигналом как минимум в 50 ns. У ATmega128 4 синхронизированных и 4 асинхронных внешних прерывания.

 

Пример

Требуется заставить вывод ATmega128 номер 9 (вывод 7 шины Е) создать прерывание, если его значение изменится. Этому выводу соответствует внешнее прерывание INT7, которое синхронно.

#include <avr/interrupt.h>
 
// Программа внешнего прерывания
ISR(INT7_vect)
{
	// Сделай что-нибудь
}
 
int main()
{
	// Изменение вывода 7 шины Е входом путём обнуления бита 7
	DDRE &= ~(1 << PIN7);
 
	// Установление pull-up резистора в вывод 7 шины Е от плавания
	PORTE |= (1 << PIN7);
 
	// Установление прерывания 7 в логическое изменение
	// в регистре конфигурации внешних прерываний
	EICRB = (1 << ISC70);
 
	// Разрешение внешнего прерывания 7
	EIMSK |= (1 << INT7);
 
	// Разрешение глобального прерывания
	sei();
 
	// Бесконечный цикл программы
	while (1) continue;
}

В дополнение к прерываниям, созданным одиночными выводами, в крупных AVR можно использовать прерывания изменений логических значений целых групп выводов. Такие прерывания называют просто прерыванием изменения вывода (англ. pin change interrupt). Они запускаются тогда, когда изменяется значение хотя бы одного вывода в группе.