Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Использование аппаратных прерываний позволяет избежать подобных ситуаций (или, по крайней мере, сгладить последствия в случае, когда нагрузка на МК превышает его возможности). По сути аппаратные прерывания организуются так же, как и "ручное" обнаружение в цикле: при возникновении условий для прерывания автоматически устанавливаются некие биты-флаги, сигнализирующие о наступлении определенного события. Но если в первом случае отслеживание значений этих флагов и реагирование на событие возлагается на программиста, то при возникновении аппаратного прерывания переход к его обработке осуществляется автоматически — программисту остается лишь написать правильную процедуру обработки. В ряде случаев основная программа может состоять только из единственной процедуры бесконечного пустого цикла: cykle: rjmp cycle. Все остальное (в том числе начальная инициализация по сбросу) будет осуществляться через прерывания.

Для надлежащего управления этим процессом флаги прерываний образуют иерархию. Во главе этой структуры стоит бит i регистра флагов SREG, который разрешает (если установлен в логическую единицу) или запрещает (если установлен в логический ноль) аппаратные прерывания вообще. Как правило, непосредственно с этим битом (как и вообще с регистром SREG) программисту дело можно не иметь: для общего разрешения (запрещения) прерываний предусмотрены специальные команды sei (разрешить) и cli (запретить), устанавливающие этот бит в нужное состояние. Отметим, что по умолчанию бит i регистра флагов SREG сброшен, т. е. прерывания при запуске МК запрещены. Для того чтобы их разрешить, необходимо в процедуре начальной инициализации, выполняющейся по сбросу МК, разместить команду sei.

Кроме общего флага прерываний, для каждого конкретного прерывания имеется свой разрешающий/запрещающий бит, расположенный в соответствующем регистре (например, для таймеров это регистры TIMSK или ETIMSK, ДЛЯ внешних прерываний— GIMSK, в последних моделях получивший название GIGR, и т. п.). При использовании прерываний эти биты необходимо устанавливать в состояние логической единицы, в противном случае автоматического вызова прерываний не произойдет.

Общая схема обработки аппаратных прерываний следующая. При возникновении любого прерывания флаг i регистра SREG аппаратно сбрасывается, тем самым запрещая обработку других прерываний. При нормальном течении событий он автоматически устанавливается опять, когда обработка прерывания заканчивается (по команде reti). Отметим, что при необходимости этот флаг можно "вручную" установить в подпрограмме-обработчике (напрямую или командой sei), разрешив вложенные прерывания. После сброса флага i контроллер определяет, запрос на обработку какого именно прерывания произошел, — это делается по флагу конкретного прерывания, который также автоматически устанавливается при возникновении прерывания (например, для таймеров эти флаги находятся в регистре TIFR или ETIFR, для внешних прерываний — в регистре GIFR или EIFR и т. п.). Отметим, что эти регистры при инициализации МК рекомендуется очищать, что делается записью единиц: ldi temp,$FF out GIFR,temp ;сбросить флаги внешних прерываний out TIFR,temp';сбросить флаги прерываний таймеров

После определения типа прерывания контроллер автоматически вычисляет адрес соответствующего вектора прерывания (векторы обычно располагаются по начальным адресам памяти программ, см. главу 2). На этом месте должна располагаться команда гjmp (для контроллеров с памятью 16 кбайт и более— команда jmp), которая содержит адрес (вектор) процедуры-обработчика.

Перед тем как перейти по вектору прерывания, МК сбрасывает флаг прерывания и автоматически сохраняет содержимое рчетчика команд в стеке. Отметим, что аппаратный стек имеется лишь в некоторых младших моделях Tiny, во всех остальных моделях для успешного вызова прерываний в процедуру инициализации контроллера необходимо включать следующие строки (обычно их ставят сразу после метки, на которую осуществляется переход по вектору сброса RESET):
ldi temp,low(RAMEND) /загрузка указателя стека out SPL,terap
ldi temp,high(RAMEND) ;загрузка указателя стека out SPH,temp
;другие установки sei ;разрешаем прерывания

Для тех моделей, у которых объем SRAM не превышает 256 байтов (модель 2313 во всех ее инкарнациях, как Tiny, так и Classic, ATtiny26 и др.), запись сокращается:
ldi temp,RAMEND ;загрузка указателя стека out SPL,temp
/другие установки
sei ;разрешаем прерывания



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru