Прерывания в atmega8

Документация

Одним из преимуществ микроконтроллера ATmega8 является широкий диапазон различных прерываний.

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

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

ISC00 ISC01 Значение
0 0 Прерывание вызывается по уровню лог.0 на входе INT0
0 1 Прерывание вызывается по ниспадающему фронту сигнала на входе INT0
1 1 Прерывание вызывается по возрастающему фронту сигнала на входе INT0

 

ISC10 ISC11 Значение
0 0 Прерывание вызывается по уровню лог.0 на входе INT1
0 1 Прерывание вызывается по возрастающему фронту сигнала на входе INT1
1 1 Прерывание вызывается по ниспадающему фронту сигнала на входе 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)

7 6 5 4 3 2 1 0
INT1
INT0
 -
 - 
 - 
  - 
 -
 - 

INTx=1: прерывания по сигналу на входы INTx разрешены

Регистр GIFR

7 6 5 4 3 2 1 0
INTF1
INTF0
 -
 - 
 - 
  - 
 -
 - 

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 [EXT_INT0] void ext_int0_isr(void)
{
lampON();
}        

void main() {
                            
   DDRD.2=0;
   PORTD.2=1;
          
   SREG|= (1<<7); //разрешаем общие прерывания
   GICR|=(1<<6);   //разрешаем прерывание по INT0    
   MCUCR|=(1<<1); //прерывание по ниспадающему фронту сигнала на INT0
 
  while(1) {

  }
 
}

Прерывания в atmega8

На приведённом примере также видно, как задаются векторы прерываний в Code Vision AVR (interrupt [EXT_INT0] 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


Если у вас есть какие-то замечания по этому документу или что-то осталось непонятно, то вы можете оставить свой отзыв или вопрос

Комментарии (5)

avatar

Пётр

  • 06 Март 2011, 19:28

ответить

Наконец-то нашёл инфу по прерываниям в atmega8! Спасибо!!!
avatar

megamaster

  • 14 Март 2011, 23:50

ответить

Да, весьма полезно!
avatar

PhOleg

  • 09 Май 2011, 16:25

ответить

Очень хорошо расписано
avatar

Gor_13

  • 03 Октябрь 2011, 19:49

ответить

ОТЛИЧНО! Недумал что в гугле так сложно найти такую простую статью как прерывание в Меге8!!! Всё разжёвано почти детально. Есть замечание по поводу упомянутого, имеющего отношения к делу, регистра SREG. Нет его описания. К примеру - не то ли это самое как Sei и Cli, и есть ли возможность вручную изменить состояние бит 7, допустим если вошли в функцию обработки прерывания, но важно не упустить другое, более важное прерывание.
Второе - не полностью расписан регистр MCUCR. Что с младшими битами? Если они отсутствуют, просьба дополнить как на примере с GIFR. Это конечно можно прогуглить, но было бы прекрасным дополнением к этой статье! Привет автору =)
avatar

Gor_13

  • 03 Октябрь 2011, 19:57

ответить

Ага! Приношу извинения. Увидил SREG|= (1

Анонимная отправка сообщений запрещена! Пожалуйста зарегистрируйтесь