Главная » Статьи » Программирование AVR |
4. Прерывания в микроконтроллере
Что такое прерывание? Прерывание - это событие, при котором происходит приостановка основной программы и переход на выполнение подпрограммы прерывания. Чтобы узнать какие же есть прерывания в МК, откроем даташит микроконтроллера и нажмем на вкладку Interrupts и там в самом начале увидим таблицу векторов прерываний. Для МК mega8 она выглядит вот так.
В каждом векторе прерывания находится команда перехода с адресом начала подпрограммы прерывания. Любая программа начинается с 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
Биты 4-7 относятся к управлению питанием и здесь рассматривать их не будем.
GICR
GIFR
Настроим внешние прерывания в WinAVR. Чтобы вызвать обработчик конкретного прерывания в WinAVR нужно воспользоваться макросом ISR и указать ему в качестве параметра вектор нужного прерывания. Откроем файл микроконтроллера mega8 - в папке с WinAVR по адресу \avr\include\avr\iom8.h и в нем найдем определения векторов прерывания. Внешнему прерыванию INT1 соответствует вектор INT1_vect. В блоке инициализации устанавливаем регистры MCUCR и GICR, после этого вызываем функцию sei(). Да, еще нужно подключить файл interrupt.h. В примере добавил переменную, которую будем инкрементировать при срабатывании внешнего прерывания - такой себе счетчик. Все это будет выглядеть вот так:
#include <iom8.h>
#include <avr/io.h>
#include <avr/interrupt.h>
//определяем биты регистров
#define ISC10 2
#define ISC11 3
#define INT1 7
unsigned char int1 = 0;
ISR(INT1_vect)
{
//обработка прерывания
int1++;
}
//функция инициализация внешнего прерывания
void INTinit()
{
MCUCR = (1<<ISC10) | (1<<ISC11);//0b00001100
GICR = (1<<INT1);//0b10000000
}
int main()
{
INTinit();//вызываем функцию инициализации прерывания
sei();//устанавливаем бит глобального разрешения прерываний
while(1);
}
| |
Просмотров: 1675 | | |
Всего комментариев: 0 | |