AVR:Прерывания

Материал из roboforum.ru Wiki
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск


Что такое прерывания и с чем его едят?

Прерывание это событие при котором процессор приостанавливает выполнение основной программы и переходит на подпрограмму обработки прерывания.

Что такое подпрограмма обработки прерывания?

Это подпрограмма которая выполняется при возникновении прерывания.

При каких событиях происходят прерывания?

События при которых происходят прерывания указаны таблице векторов прерываний в даташите.

Вот пример таблицы для мега16

Таблица прерываний для ATMega16
# Адресс Разрешение прерывания Запрос рерывания Событие
1 $0002 INT0 (GICR) INTF0 (GIFR) INT0 Внешнее прерывание 0
2 $0004 INT1 (GICR) INTF1 (GIFR) INT1 Внешнее прерывание 1
3 $0006 OCIE2 (TIMSK) OCF2 (TIFR) TIMER2 COMPARE Совпадение таймера счетчика 2
4 $0008 TOIE2 (TIMSK) TOV2 (TIFR) TIMER2 OVERFLOW Переполнение таймера счетчика 2
5 $000A TICIE1 (TIMSK) ICF1 (TIFR) TIMER1 CAPTURE Захват таймера счетчика 1
6 $000C OCIE1A (TIMSK) OCF1A (TIFR) TIMER1 COMPARE A Совпадение А таймера счетчика 1
7 $000E OCIE1B (TIMSK) OCF1B (TIFR) TIMER1 COMPARE B Совпадение В таймера счетчика 1
8 $0010 TOIE1 (TIMSK) TOV1 (TIFR) TIMER1 OVERFLOW Переполнение таймера счетчика 1
9 $0012 TOIE0 (TIMSK) TOV0 (TIFR) TIMER0 OVERFLOW Переполнение таймера счетчика 0
10 $0014 SPIE (SPCR) SPIF (SPSR) SPI STC Передача по SPI завершена
11 $0016 RXCIE (UCSRB) RXC (UCSRA) USART RXC Прием по USART завершен
12 $0018 UDRIE (UCSRB) UDRE (UCSRA) USART UDRE Готовность регистр данных USART
13 $001A TXCIE (UCSRB) TXC (UCSRA) USART TXC Передача по USART завершеа
14 $001C ADIE (ADCSRA) ADIF (ADCCSRA) ADC Преобразование ADC завершено
15 $001E EERIE (EECR) EE RDY Готовность EEPROM
16 $0020 ACIE (ACSR) ACI (ACSR) ANA COMP прерывание от аналогового компаратора
17 $0022 TWIE (TWCR) TWINT (TWCR) TWI Прерывания от TWI
18 $0024 INT2 (GICR) INTF2 (GIFR) INT2 Внешнее прерывание 2
19 $0026 OCIE0 (TIMSK) OCF0 (TIFR) TIMER0 COMPARE 0 Совпадение -

таймера счетчика 0

20 $0028 SPMIE(SPMCR) SPM RDY Готовность SPM

Для чего нужна эта таблица?

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

Для чего нужны эти флаги?

При установке флага разрешения мы разрешаем необходимое нам прерывание, флаги запроса прерывания устанавливаются аппаратно при наступлении прерывания и сбрасываются при переходе на подпрограмму обработки прерывания,эти флаги также можно сбросить программно. Следует не забывать, что при разрешении прерывания необходимо устанавливать флаг I регистра SREG для глобального разрешения прерываний.

Можно простой примерчик или как то на пальцах обьяснить?

Можно, вот простой примерчик подсчета количества прерываний INT0 и выводом результата в порт В.

<source lang="asm">

Подсчет количества прерываний INT0
Результат выводится в порт В
Подключение файла обьявления имен регистров ATmega8

.include "c:\...\m16def.inc"

.cseg .org 0

------------------ Вектора прерываний ---------------------------
         jmp PROG              ;Вектор перехода на начало программы
         jmp SUBI_INT0         ;Вектор перехода на подпрограмму прерывания INT0
-----------------------------------------------------------------

.org $30

Начало программы

PROG:  ;PROG

  ldi  R16,high(RAMEND)       ;Инициализация стека
  out  SPH,R16
  ldi  R16,low(RAMEND)
  out  SPL,R16
Инициализация INT0
                              ;INT.SenseControl=FallingEdge
  ldi  R16,(0<<ISC00)|(1<<ISC01) ;Условие прерывания - спадающий фронт сигнала
  out  MCUCR,R16
  ldi  R16,(1<<INT0)          ;INT.Enable=1 Разрешаем прерывание INT0
  out  GICR,R16
Обнуление регистра R20 и установка порта В на вывод
  ldi  R20,$00                ;R20=$00
  ldi  R16,$FF                ;DDRB=$FF
  out  DDRB,R16
  sei                         ;Разрешаем прерывания глобально I=1
Конец программы (бесконечный цикл)

END_PROG:  ;END PROG

  rjmp  END_PROG
-----------------------------------------------------------------
Начало подпрограммы обработки прерывания от INT1
                              ;SUBI INT0

SUBI_INT0:  ;Сохраняем регистры R16,SREG в стеке

  push R16
  in   R16,SREG
  push R16
  inc R20                     ;R20+$01
  out  PORTB,R20              ;PORTB=R20
  pop  R16                    ;Востанавливаем регистры
  out  SREG,R16
  pop  R16
  reti                        ;END SUBI
-----------------------------------------------------------------

</source>

А теперь на пальцах смотрим на симуляторе что происходит. Нажимаем пошаговое выполнение пока строка выполнения не будет крутиться в бесконечном цикле по команде rjmp END_PROG.

Avr interrupt 1.jpg

После чего подаем лог. 0 на вывод INT0 нажав переключатель.

Avr interrupt 2.jpg

Потом нажимаем опять пошаговое выполнение и ВИДИМ, ПРОИСХОДИТ ЧУДО. Стока выполнения перещается на адресс $0002($0004) (в таблице адресс вектора указывается в словах, а в симуляторе адрессация в байтах) в котором находиться команда перехода rjmp INT0 на начало подпрограммы INT0. После чего происходит выполнение подпрограммы INT0.

Хорошо,а что произойдет если мы разрешим допустим два прерывания, и события при которых они наступят произойдут в один и тот же момент времени?

Для этого и нужна таблица векторов прерываний, чем меньше адресс вектора тем выше приоритет этого прерывания по отношению к другим. Допустим одновременно наступили два прерывания INT0 и INT1, тогда сначала будет выполненена подпрограмма обработки INT0, а после подпрограмма обработки INT1.

А если во время выполнения подпрограммы обработки прерывания, наступит другое, более высокое по приоритету, что тогда?'

При наступлении любого прерывания флаг глобального разрешения прерываний I регистра SREG сбрасывается в 0 и до его установки любые другие прерывания не выполняются. Соответственно при выполнении подпрограммы другое прерывание не будет выполено до установки бита I в 1 или команды reti (выход из подпрограммы с установкой бита I в 1).

Значит, если во время выполнения подпрограммы обработки прерывания, наступит другое, оно не будет выполнено?

Нет, все разрешенные прерывания будут выполнены (кроме тех, у которорых не предусмотрен флаг запроса прерывания), но уже не сразу после наступления события, а в порядке их преоритетности. Для этого и служат флаги запроса прерываний (смотрите таблицу) При наступлении прерывания устанавливается флаг, который сигнализирует процессору о наступлении события и не сбрасывается, до тех пор пока процесссор не перейдет на подпрограмму обработки этого прерывания.

А если прерываний будет много и процессор не будет успевать их обрабатывать. Например дважды возникнет одно и тоже прерывание до того как он успевает обработать предыдущее?

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

А для чего значения рабочих регистров и регистра SREG заносятся в стек в начале подпрограммы прерывания и извлекаются из стека в конце?

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


Автор: bodja
E-Mail: bodja74@mail.ru
WWW: http://telepribor.narod.ru/
Профиль на электрониксе: bodja74