- •1) Комбинационная логика, основные элементы (и, или, не), их схемы на кмоп транзисторах.
- •Временная диаграмма работы сдвигового регистра.
- •6) Общая структура микроконтроллерного устройства, алу, программный счётчик.
- •Общая структура микроконтроллерного устройства (из интернета)
- •Программный счётчик.
- •7. Виды памяти микроконтроллеров (на примере семейства avr). Стек и его инициализация.
- •8. Прерывания, вектор прерываний.
- •9) Основы языка Assembler для микроконтроллеров семейства avr. Синтаксис, классификация команд.
- •Команды логических операций.
- •Команды операций с битами.
- •Команды пересылки данных.
- •Команды передачи управления.
- •Команды управления системой.
- •10. Регистры ввода-вывода. Схема устройства вывода микроконтроллера, управляющие регистры, режимы работы.
8. Прерывания, вектор прерываний.
Прерывания – это аппаратные события, которые прекращают нормальный ход программы для выполнения какой-либо приоритетной задачи. При этом событие может быть как внутренним (от встроенной периферии самого микроконтроллера – таймеров, портов ввода-вывода, АЦП и других), так и внешним – например, появление на входе импульса от нажатой кнопки. Возникает вопрос, можно ли обрабатывать эти события без использования прерываний?
В наиболее простых случаях так и происходит: основная программа представляет собой бесконечный цикл, внутри которого тем или иным способом отслеживаются возникновения событий, при наступлении которых устанавливается определённое значение переменной, называемой обычно флагом (бит в специализированном регистре или ячейке памяти). Основная программа проверяет в цикле значения используемых флагов, и при их изменении переходит к обработке соответствующего события. Чем неудобен подобный подход? Во-первых, подобный цикл ожидания полностью загружает микроконтроллер, который в это время мог бы делать что-нибудь полезное. Во-вторых, некоторые события в принципе не могут долго ждать, например, обработка приёма данных по USART – если пропустить хоть один байт, логика работы программы будет нарушена, а повторная пересылка данных может быть не предусмотрена. Именно поэтому для организации более эффективного использования ресурсов микроконтроллера и используют прерывания.
Как работают прерывания. При возникновении прерывания микроконтроллер завершает текущую команду, сохраняет в стеке содержимое счетчика команд и совершает переход на адрес соответствующего вектора прерывания. По этому адресу, как правило, находится команда безусловного (JMP или RJMP) перехода к подпрограмме обработки прерывания. За каждым аппаратным прерыванием микроконтроллера закреплен свой адрес, и все вместе они образуют таблицу векторов прерываний, которая расположена в самом начале памяти программ. Поскольку у каждого микроконтроллера набор периферии разный, вектор прерываний также будет отличаться. Ниже приведена таблица векторов прерываний микроконтроллера ATTiny2313, который мы будем использовать вынуждены использовать в новых условиях при выполнении практических работ.
Таблица векторов прерываний микроконтроллера ATTiny2313
№ |
Адрес |
Источник прерывания |
Описание |
|
1 |
.ORG 0x0000 |
RESET |
External Pin, Power-on Reset |
|
2 |
.ORG 0x0001 |
INT0 |
External Interrupt Request 0 |
|
3 |
.ORG 0x0002 |
INT1 |
External Interrupt Request 1 |
|
4 |
.ORG 0x0003 |
TIMER1 CAPT |
Timer/Counter1 Capture Event |
|
5 |
.ORG 0x0004 |
TIMER1 COMPA |
Timer/Counter1 Compare Match A |
|
6 |
.ORG 0x0005 |
TIMER1 OVF |
Timer/Counter1 Overflow |
|
7 |
.ORG 0x0006 |
TIMER0 OVF |
Timer/Counter0 Overflow |
|
8 |
.ORG 0x0007 |
USART0, RX |
USART0, Rx Complete |
|
9 |
.ORG 0x0008 |
USART0, UDRE |
USART0 Data Register Empty |
|
10 |
.ORG 0x0009 |
USART0, TX |
USART0, Tx Complete |
|
11 |
.ORG 0x000A |
ANALOG COMP |
Analog Comparator |
|
12 |
.ORG 0x000B |
PCINT |
Pin Change Interrupt |
|
13 |
.ORG 0x000C |
TIMER1 COMPB |
Timer/Counter1 Compare Match B |
|
14 |
.ORG 0x000D |
TIMER0 COMPA |
Timer/Counter0 Compare Match A |
|
15 |
.ORG 0x000E |
TIMER0 COMPB |
Timer/Counter0 Compare Match B |
|
16 |
.ORG 0x000F |
USI START |
USI Start Condition |
|
17 |
.ORG 0x0010 |
USI OVERFLOW |
USI Overflow |
|
18 |
.ORG 0x0011 |
EE READY |
EEPROM Ready |
|
19 |
.ORG 0x0012 |
WDT OVERFLOW |
Watchdog Timer Overflow |
|
.ORG INT_VECTORS_SIZE |
Конец таблицы прерываний |
Контроллер стартует с адреса 0x00 (нулевого адреса памяти программ). Далее мы делаем безусловный переход на метку RESET. Если этого не сделать, то контроллер начнёт выполнять команды из таблицы векторов прерываний, что нам совершенно не нужно. После перехода по метке первым делом необходимо проинициализировать стек. Потом, используя команду SEI, разрешаем глобальные прерывания. За разрешение конкретных прерываний для каждого вида периферии отвечают соответствующие регистры управления локальными прерываниями.
Когда возникает прерывание, выполнение текущих операций приостанавливается и микроконтроллер переходит по соответствующей метке на подпрограмму обработки прерывания. Последней командой подпрограммы обработки прерывания должна быть команда RETI, которая обеспечивает возврат в основную программу и восстановление предварительно сохраненного счетчика команд и данных, заблаговременно перенесённых в стек.
Что происходит в том случае, если одновременно возникает не одно прерывание, а несколько? Тогда в регистре состояния устанавливаются соответствующие флаги, и прерывания обрабатываются одно за другим в порядке очерёдности. Положение вектора в таблице определяет приоритет соответствующего прерывания, при этом чем меньше адрес, тем выше приоритет прерывания. Если прерывания в работе микроконтроллера не используются, то на месте таблицы векторов прерываний может быть размещена часть основной программы.
Для глобального разрешения или запрещения прерываний предназначен флаг I регистра состояния SREG. Для разрешения работы прерываний он должен быть установлен в единицу (это делается с помощью ассемблерной команды SEI), а для запрещения сброшен (командой CLI). По умолчанию (после сброса микроконтроллера) этот флаг сброшен, и все прерывания микроконтроллера запрещены. Также возможно индивидуальное разрешение или запрещение (маскирование) прерываний, которое производится установкой или сбросом соответствующих разрядов регистров масок прерываний. Для каждого блока периферии существует собственный регистр для разрешения локальных прерываний. При возникновении прерывания флаг I регистра SREG сбрасывается на аппаратном уровне, запрещая тем самым обработку следующих прерываний. При возврате из подпрограммы обработки прерывания (при выполнении команды RETI) флаг I устанавливается обратно.
Все доступные для работы прерывания можно разделить на два типа. Прерывания первого типа генерируются при наступлении некоторого события, в результате которого устанавливается флаг прерывания. Затем, если прерывание разрешено, в счетчик команд загружается адрес вектора соответствующего прерывания. При этом флаг прерывания сбрасывается на аппаратном уровне. Он также может быть сброшен программным образом, путем записи единицы в разряд регистра, соответствующий флагу.
Прерывания второго типа не имеют флагов прерываний и генерируются в течение всего времени, пока присутствуют условия, необходимые для генерации прерывания. Соответственно, если условия, вызывающие прерывание, исчезнут до разрешения прерывания, генерации прерывания не произойдет.
Наименьшее время отклика для любого прерывания составляет 4 машинных цикла, в течение которых происходит сохранение счетчика команд в стеке. В течение последующих двух или трех циклов выполняется команда перехода к подпрограмме обработки прерывания. Если прерывание произойдет во время выполнения команды, длящейся несколько циклов, то генерация прерывания произойдет только после выполнения этой команды. Если же прерывание произойдет во время нахождения микроконтроллера в «спящем» режиме, время отклика увеличивается еще на 4 машинных цикла. Возврат в основную программу занимает 4 машинных цикла, в течение которых происходит восстановление счетчика команд из стека. После выхода из прерывания процессор всегда выполняет одну команду основной программы, прежде чем обслужить любое отложенное прерывание.
Поскольку прерывание нарушает стандартный ход выполнения программы и может возникнуть в любой момент времени, необходимо сохранить текущие данные. Для этого необходимо использовать стек, туда нужно переместить все регистры, используемые в обработчике прерывания, чтобы не потерять хранящиеся там данные. Также необходимо сохранять регистр флагов SREG, в котором хранится результат логических операций:
TIM0_OVF:
PUSH R16 // Сохраняем регистр R16
IN R16, SREG // Перемещаем содержимое SREG в R16
PUSH R16 // Сохраняем всё в стек
PUSH R17 // R17 сохраняем туда же
…………… // Выполнение кода обработчика прерывания
POP R17 // Перед выходом из прерывания извлекаем
POP R16 // сохранённые данные
OUT SREG, R16 // Действуем при этом в обратном порядке
POP R16
RETI // Выходим из прерывания
Также существует ряд операций, которые должны выполняться неразрывно, например, чтение 16-разрядного счетного регистра таймера. Поскольку ядро микроконтроллеров семейства Tiny 8-разрядное, то 16-разрядный регистр таймера считывается (или записывается) в два приема – причём сначала считывается младший байт, а потом старший (это подробно рассматривалось в главе, посвящённой таймерам). Между двумя этими операциями не должно возникать никаких прерываний, поэтому перед чтением такого регистра необходимо их запретить, а после окончания операции чтения разрешить обратно.