Прерывания
В данном разделе описывается специфика обработки прерываний, реализованная в ATmega128. Общее описание обработки прерываний приведено в разделе “Сброс и обработка прерываний”.
Векторы прерываний в ATmega128
Таблица 23 – Векторы сброса и прерываний
№ вектора |
Адрес памяти программ(4) |
Источник |
Условие возникновения прерывания |
1 |
$0000(1) |
RESET |
Внешний сброс, сброс при подаче питания, сброс при недопустимом снижении питания, сброс сторожевым таймером и сброс через JTAG-интерфейс |
2 |
$0002 |
INT0 |
Запрос на внешнее прерывание 0 |
3 |
$0004 |
INT1 |
Запрос на внешнее прерывание 1 |
4 |
$0006 |
INT2 |
Запрос на внешнее прерывание 2 |
5 |
$0008 |
INT3 |
Запрос на внешнее прерывание 3 |
6 |
$000A |
INT4 |
Запрос на внешнее прерывание 4 |
7 |
$000C |
INT5 |
Запрос на внешнее прерывание 5 |
8 |
$000E |
INT6 |
Запрос на внешнее прерывание 6 |
9 |
$0010 |
INT7 |
Запрос на внешнее прерывание 7 |
10 |
$0012 |
TIMER2 COMP |
Срабатывание компаратора таймера-счетчика 2 |
11 |
$0014 |
TIMER2 OVF |
Переполнение таймера-счетчика 2 |
12 |
$0016 |
TIMER1 CAPT |
Захват фронта таймером-счетчиком 1 |
13 |
$0018 |
TIMER1 COMPA |
Срабатывание компаратора А таймера-счетчика 1 |
14 |
$001A |
TIMER1 COMPB |
Срабатывание компаратора В таймера-счетчика 1 |
15 |
$001C |
TIMER1 OVF |
Переполнение таймера-счетчика 1 |
16 |
$001E |
TIMER0 COMP |
Срабатывание компаратора таймера-счетчика 0 |
17 |
$0020 |
TIMER0 OVF |
Переполнение таймера-счетчика 0 |
18 |
$0022 |
SPI, STC |
Завершение последовательной передачи интерфейсом SPI |
19 |
$0024 |
USART0, RX |
Завершение приема УСАПП 0 |
20 |
$0026 |
USART0, UDRE |
Регистр данных УСАПП0 свободен |
21 |
$0028 |
USART0, TX |
Завершение передачи УСАПП 0 |
22 |
$002A |
ADC |
Завершение преобразования АЦП |
23 |
$002C |
EE READY |
Готовность ЭСППЗУ |
24 |
$002E |
ANALOG COMP |
Аналоговый компаратор |
25 |
$0030(3) |
TIMER1 COMPC |
Срабатывание компаратора С таймера-счетчика 1 |
26 |
$0032(3) |
TIMER3 CAPT |
Захват фронта таймером счетчиком 3 |
27 |
$0034(3) |
TIMER3 COMPA |
Срабатывание компаратора А таймера-счетчика 3 |
28 |
$0036(3) |
TIMER3 COMPB |
Срабатывание компаратора В таймера-счетчика 3 |
29 |
$0038(3) |
TIMER3 COMPC |
Срабатывание компаратора С таймера-счетчика 3 |
30 |
$003A(3) |
TIMER3 OVF |
Переполнение таймера счетчика 3 |
31 |
$003C(3) |
USART1, RX |
Завершение приема УСАПП 1 |
32 |
$003E(3) |
USART1, UDRE |
Регистр данных УСАПП1 свободен |
33 |
$0040(3) |
USART1, TX |
Завершение передачи УСАПП1 |
34 |
$0042(3) |
TWI |
Двухпроводной последовательный интерфейс |
35 |
$0044(3) |
SPM READY |
Готовность записи в память программ |
Прим.:
- Если конфигурационный бит BOOTRST запрограммирован, то микроконтроллер выполняет переход на адрес сброса в загрузочном секторе, см. “ Самопрограммирование из сектора начальной загрузки с поддержкой чтения во время записи ”.
- Если установлен бит IVSEL в регистре MCUCR, то векторы прерываний перемещаются в начало загрузочного сектор флэш-памяти. В этом случае к адресу каждого вектора прерывания из таблицы прибавляется стартовый адрес загрузочного сектора флэш-памяти.
- Прерывания по адресам $0030 - $0044 не существуют в режиме совместимости с ATmega103.
В таблице 24 показано расположение векторов сброса и прерываний в зависимости от различных установок BOOTRST и IVSEL. Если программа не использует прерывания, то она может быть размещена равномерно, используя ячейки с адресами векторов прерываний для хранения программного кода. Возможен также случай, когда вектор сброса располагается в секторе прикладной программы, а векторы прерываний – в загрузочном секторе или наоборот.
Таблица 24 – Размещение векторов сброса и прерываний
BOOTRST |
IVSEL |
Адрес сброса |
Начальный адрес векторов прерываний |
1 |
0 |
$0000 |
$0002 |
1 |
1 |
$0000 |
Адрес сброса в загрузочном секторе + $0002 |
0 |
0 |
Адрес сброса в загрузочном секторе |
$0002 |
0 |
1 |
Адрес сброса в загрузочном секторе |
Адрес сброса в загрузочном секторе + $0002 |
Прим. : Адрес сброса загрузочного сектора показан в таблице 113. Для конфигурационного бита BOOTRST “1” означает незапрограммированное состояние, “0” - запрограммированное.
Ниже приведено большинство типичных и общих программных установок адресов сброса и векторов прерываний у ATmega128:
Адрес Инструкция Комментарий
$0000 jmp RESET ; Переход на обработку сброса
$0002 jmp EXT_INT0 ; Переход на обработку запроса IRQ0
$0004 jmp EXT_INT1 ; Переход на обработку запроса IRQ1
$0006 jmp EXT_INT2 ; Переход на обработку запроса IRQ2
$0008 jmp EXT_INT3 ; Переход на обработку запроса IRQ3
$000A jmp EXT_INT4 ; Переход на обработку запроса IRQ4
$000C jmp EXT_INT5 ; Переход на обработку запроса IRQ5
$000E jmp EXT_INT6 ; Переход на обработку запроса IRQ6
$0010 jmp EXT_INT7 ; Переход на обработку запроса IRQ7
$0012 jmp TIM2_COMP ; Переход на обработку при выполнении условия сравнения таймера 2
$0014 jmp TIM2_OVF ; Переход на обработку при переполнении таймера 2
$0016 jmp TIM1_CAPT ; Переход на обработку при захвате фронта таймером 1
$0018 jmp TIM1_COMPA ; Переход на обработку при срабатывании компаратора А таймера 1
$001A jmp TIM1_COMPB ; Переход на обработку при срабатывании компаратора В таймера 1
$001C jmp TIM1_OVF ; Переход на обработку при переполнении таймера 1
$001E jmp TIM0_COMP ; Переход на обработку при выполнения условия сравнения таймера 0
$0020 jmp TIM0_OVF ;Переход на обработку при переполнении таймера 0
$0022 jmp SPI_STC ; Переход на обработку при завершении передачи SPI
$0024 jmp USART0_RXC ; Переход на обработку при завершении приема УСАПП0
$0026 jmp USART0_DRE ; Переход на обработку при освобождении регистра данных UDR УСАПП0
$0028 jmp USART0_TXC ; Переход на обработку при завершении передачи УСАПП0
$002A jmp ADC ; Переход на обработку при завершении преобразования АЦП
$002C jmp EE_RDY ; Переход на обработку при готовности ЭСППЗУ
$002E jmp ANA_COMP ; Переход на обработку при срабатывании аналогового компаратора
$0030 jmp TIM1_COMPC ; Переход на обработку при срабатывании компаратора С таймера 1
$0032 jmp TIM3_CAPT ; Переход на обработку при захвате фронта таймером 3
$0034 jmp TIM3_COMPA ; Переход на обработку при срабатывании компаратора А таймера 3
$0036 jmp TIM3_COMPB ; Переход на обработку при срабатывании компаратора В таймера 3
$0038 jmp TIM3_COMPC ; Переход на обработку при срабатывании компаратора С таймера 3
$003A jmp TIM3_OVF ; Переход на обработку при переполнении таймера 3
$003C jmp USART1_RXC ; Переход на обработку по завершении приема УСАПП1
$003E jmp USART1_DRE ; Переход на обработку при освобождении регистра данных UDR УСАПП1
$0040 jmp USART1_TXC ; Переход на обработку при завершении передачи УСАПП1
$0042 jmp TWI ; Переход на обработку прерывания по двухпроводному последовательному интерфейсу
$0044 jmp SPM_RDY ; Переход на обработку прерывания при готовности выполнения команды SPM
;
$0046 RESET:ldir16, high(RAMEND); Начало основной программы
$0047 out SPH,r16 ; Установка указателя стека в конце ОЗУ
$0048 ldi r16, low(RAMEND)
$0049 out SPL,r16
$004A sei ; Разрешение прерываний
$004B xxx
... ... ... ...
|
Если конфигурационный бит BOOTRST незапрограммирован, размер загрузочного сектора установлен 8 кбайт и бит IVSEL установлен в регистре MCUCR перед разрешением любого прерывания, то можно использовать следующий пример распределения программы по адресам векторов сброса и прерываний.
Адрес Инструкция Комментарий
$0000 RESET:ldi r16,high(RAMEND) ; Начало основной программы
$0001 out SPH,r16 ; Установка указателя стека в конце ОЗУ
$0002 ldi r16,low(RAMEND)
$0003 out SPL,r16
$0004 sei ; Разрешение прерываний
$0005 xxx
;
.org $F002
$F002 jmp EXT_INT0 ; Переход на обработку прерывания IRQ0
$F004 jmp EXT_INT1 ; Переход на обработку прерывания IRQ1
... ... ... ;
$F044 jmp SPM_RDY ; Переход на обработку прерывания по готовности к записи в память программ
|
Если конфигурационный бит BOOTRST запрограммирован и установлен размер загрузочного сектора 8 кбайт, то можно использовать следующий шаблон программы:
Адрес Инструкция Комментарий
.org $0002
$0002 jmp EXT_INT0 ; Переход на обработку прерывания IRQ0
$0004 jmp EXT_INT1 ; Переход на обработку прерывания IRQ1
... ... ... ;
$0044 jmp SPM_RDY ; Переход на обработку прерывания по готовности к записи в память программ
;
.org $F000
$F000 RESET: ldi r16,high(RAMEND) ; Начало основной программы
$F001 out SPH,r16 ; Установка указателя стека в конец ОЗУ
$F002 ldi r16,low(RAMEND)
$F003 out SPL,r16
$F004 sei ; Разрешение прерываний
$F005 xxx
|
Если конфигурационный бит BOOTRST запрограммирован, размер загрузочного сектора установлен 8 кбайт и бит IVSEL в регистре MCUCR установлен перед разрешение любого из прерываний, то распределение адресов в программе следующее:
Адрес Инструкция Комментарий
;
.org $F000
$F000 jmp RESET ; Переход на обработку сброса
$F002 jmp EXT_INT0 ; Переход на обработку прерывания IRQ0
$F004 jmp EXT_INT1 ; Переход на обработку прерывания IRQ1
... ... ... ;
$F044 jmp SPM_RDY ; Переход на обработку прерывания по готовности записи в память программ
$F046 RESET: ldi r16,high(RAMEND) ; Начало основной программы
$F047 out SPH,r16 ; Установка указателя стека в конец ОЗУ
$F048 ldi r16,low(RAMEND)
$F049 out SPL,r16
$F04A sei ; Разрешение прерываний
$F04B xxx
|
Перемещение между секторами загрузочной и прикладной программы
Общий регистр управления прерываниями задает размещение таблицы векторов прерываний.
Регистр управления микроконтроллером – MCUCR
Разряд |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
|
SRE |
SRW10 |
SE |
SM1 |
SM0 |
SM2 |
IVSEL |
IVCE |
MCUCR |
Чтение/запись |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
Чт./Зп. |
|
Исх. значение |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
Разряд 1 – IVSEL: Выбор вектора прерывания
Если бит IVSEL сброшен (=0), то векторы прерываний размещаются в начале флэш-памяти. Если данный бит установлен (=1), то векторы прерываний перемещаются в начало загрузочного сектора флэш-памяти. Фактический адрес начала загрузочного сектора определяется значением конфигурационных бит BOOTSZ. См. раздел “Самопрограммирование из сектора начальной загрузки с поддержкой чтения во время записи” для выяснения подробностей. Во избежание несанкционированных изменений таблицы векторов прерываний необходимо выполнить специальную последовательность записи при изменении бита IVSEL:
- Записать лог. 1 в бит разрешения изменения вектора прерывания (IVCE).
- В течение четырех машинных циклов записать желаемое значение в IVSEL, при этом записывая лог.0 в IVCE.
Прерывания будут автоматически отключены при выполнении такой последовательности. Прерывания отключаются во время установки IVCE и останутся отключенными до перехода к инструкции следующей за инструкцией записи в IVSEL. Если IVSEL не записан, то прерывания будет находиться в отключенном состоянии 4 такта синхронизации. Состояние бита I в регистре статуса не затрагивается при автоматическом отключении прерываний.
Прим. : Если векторы прерываний помещаются в загрузочный сектор и бит защиты загрузочного сектора BLB02 запрограммирован, то прерывания будут отключены при выполнения программы с секторе прикладной программы. Если векторы прерываний размещены в прикладном секторе и бит защиты BLB12 запрограммирован, то прерывания становятся отключенными при выполнении программы в загрузочном секторе. См. также “ Самопрограммирование из сектора начальной загрузки с поддержкой чтения во время записи ” для более подробного изучения бит защиты.
Разряд 0 – IVCE: Разрешение изменения вектора прерывания
В бит IVCE должна быть записана лог. 1, чтобы разрешить изменение бита IVSEL. IVCE сбрасывается аппаратно через четыре машинных цикла после записи лог. 1 в IVSEL. Установка бита IVCE приведет к отключению прерываний, что описано при рассмотрении бита IVSEL выше. Ниже приведен пример кода.
Пример кода на Ассемблере
Move_interrupts:
; Разрешение изменения векторов прерываний
ldi r16, (1<<IVCE)
out MCUCR, r16
; Перемещение векторов в загрузочный сектор флэш-памяти
ldi r16, (1<<IVSEL)
out MCUCR, r16
ret
Пример кода на Си
void Move_interrupts(void)
{
/* Разрешение изменения векторов прерываний */
MCUCR = (1<<IVCE);
/* Перемещение векторов в загрузочной сектор флэш-памяти */
MCUCR = (1<<IVSEL);
}