Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МПС (Влада).docx
Скачиваний:
104
Добавлен:
05.05.2021
Размер:
4.89 Mб
Скачать

8. Прерывания, вектор прерываний.

Прерывания – это аппаратные события, которые прекращают нормальный ход программы для выполнения какой-либо приоритетной задачи. При этом событие может быть, как внутренним (от встроенной периферии самого микроконтроллера – таймеров, портов ввода-вывода, АЦП и других), так и внешним – например, появление на входе импульса от нажатой кнопки.

[Можно ли обрабатывать эти события без использования прерываний?

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

Чем неудобен подобный подход?

1) Подобный цикл ожидания полностью загружает микроконтроллер, который в это время мог бы делать что-нибудь полезное.

2) Некоторые события в принципе не могут долго ждать, например, обработка приёма данных по USART – если пропустить хоть один байт, логика работы программы будет нарушена, а повторная пересылка данных может быть не предусмотрена.

Именно поэтому для организации более эффективного использования ресурсов микроконтроллера и используют прерывания.]

Как работают прерывания?

 При возникновении прерывания микроконтроллер завершает текущую команду, сохраняет в стеке содержимое счетчика команд и совершает переход на адрес соответствующего вектора прерывания. По этому адресу, как правило, находится команда безусловного (JMP или RJMP) перехода к подпрограмме обработки прерывания.

За каждым аппаратным прерыванием микроконтроллера закреплен свой адрес, и все вместе они образуют таблицу векторов прерываний, которая расположена в самом начале памяти программ.

Контроллер стартует с адреса 0x00 (нулевого адреса памяти программ). Далее мы делаем безусловный переход на метку RESET. Если этого не сделать, то контроллер начнёт выполнять команды из таблицы векторов прерываний, что нам совершенно не нужно.

После перехода по метке первым делом необходимо проинициализировать стек. Потом, используя команду SEI, разрешаем глобальные прерывания. За разрешение конкретных прерываний для каждого вида периферии отвечают соответствующие регистры управления локальными прерываниями.

Когда возникает прерывание, выполнение текущих операций приостанавливается и микроконтроллер переходит по соответствующей метке на подпрограмму обработки прерывания. Последней командой подпрограммы обработки прерывания должна быть команда RETI (выход из прерывания), которая обеспечивает возврат в основную программу и восстановление предварительно сохраненного счетчика команд и данных, заблаговременно перенесённых в стек.

RESET

// инициализация стека и инициализация периферии

SEI

ОБРАБОТЧИК ПРЕРЫВАНИЯ

RETI

Что происходит в том случае, если одновременно возникает не одно прерывание, а несколько?

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

Обработка прерываний

[ВОПРОС ИЗ КОНТРОЛЬНОЙ – краткое описание того, что ниже.

В билете можно писать это, а потом читать остальное для пояснения]

Выберите правильную последовательность действий при обработке прерывания:

1) Для включения прерывания программа должна установить флаг I регистра SREG в единицу и записать в регистры маски такой код, который разрешит лишь нужные в данный момент прерывания

2) При поступлении запроса на прерывание устанавливается флаг соответствующего прерывания

3) Флаг I автоматически сбрасывается, запрещая обработку других прерываний. Флаг, соответствующий вызванному прерыванию, также сбрасывается, сигнализируя о том, что МК уже приступил к его обработке.

4) После окончания обработки очередного прерывания происходит проверка остальных флагов, и если имеется хоть одно не обработанное прерывание, МК переходит к его обработке.

Для глобального разрешения или запрещения прерываний предназначен флаг I регистра состояния SREG. Для разрешения работы прерываний он должен быть установлен в единицу (это делается с помощью ассемблерной команды SEI), а для запрещения сброшен (командой CLI). По умолчанию (после сброса микроконтроллера) этот флаг сброшен, и все прерывания микроконтроллера запрещены.

Для каждого блока периферии существует собственный регистр для разрешения локальных прерываний (E/TIMSK). При возникновении прерывания флаг I регистра SREG сбрасывается на аппаратном уровне, запрещая тем самым обработку следующих прерываний. При возврате из подпрограммы обработки прерывания (при выполнении команды RETI) флаг I устанавливается обратно.

Все доступные для работы прерывания можно разделить на два типа.

I тип) возникают при наступлении некоторого события, в результате которого устанавливается флаг прерывания.

Если прерывание разрешено, в счетчик команд загружается адрес вектора соответствующего прерывания. При этом флаг прерывания сбрасывается на аппаратном уровне. Он также может быть сброшен программным образом, путем записи единицы в разряд регистра, соответствующий флагу.

II тип) Не имеют флагов прерываний и возникают в течение всего времени, пока присутствуют условия, необходимые для их возникновения.

Если условия, вызывающие прерывание, исчезнут до разрешения прерывания, генерации прерывания не произойдет.

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

ОБРАБОЧИК ПРЕРЫВАНИЯ:

PUSH         R16            // Сохраняем регистр R16

IN R16, SREG     // Перемещаем содержимое SREG в R16

PUSH         R16            // Сохраняем всё в стек

PUSH         R17            // R17 сохраняем туда же

……………           // Выполнение кода обработчика прерывания

POP  R17            // Перед выходом из прерывания извлекаем

POP  R16            // сохранённые данные

OUT SREG, R16 // Действуем при этом в обратном порядке

POP  R16

RETI                   // Выходим из прерывания

Также существует ряд операций, которые должны выполняться неразрывно, например, чтение 16-разрядного счетного регистра таймера.

16-разрядный регистр считывается в два приема: сначала считывается младший байт, а потом старший. (ЗАПИСЬ ПРОИСХОДИТ В ОБРАТНОМ ПОРЯДКЕ)

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

Соседние файлы в предмете Микропроцессорные системы