Что такое прерывание в микроконтроллере
Перейти к содержимому

Что такое прерывание в микроконтроллере

  • автор:

Что такое прерывание в микроконтроллере

Прерывания в микроконтроллерах представляет собой механизм, который позволяет микроконтроллеру реагировать на внешние события. Этот механизм работает таким образом, что при наступлении некоторого события в процессоре возникает сигнал, заставляющий процессор прервать выполнение текущей программы, т.е. говорят, что возникло прерывание. После того как выполнение текущей программы прервано, процессор должен перейти к выполнению программной процедуры, связанной с этим событием (прерыванием) – процедуры обработки прерывания. Однако , прежде чем перейти непосредственно к процедуре обработки прерывания, процессор должен выполнить ряд предварительных действий. Прежде всего, для того чтобы в будущем он смог корректно продолжить прерванную программу, необходимо сохранить состояние процессора ( счетик команд, слово состояния процессора, внутренние регистры и т.д.) на момент, предшествующий прерыванию. Т.е. другими словами, требуется сохранить состояния всех тех ресурсов, которые так или иначе могут быть изменены в процессе обработки прерывания. Далее, если в системе имеется несколько возможных источников прерываний (а обычно так и бывает), процессор должен определить источник запроса прерываний. И, наконец, затем перейти к самой процедуре прерываний, конкретной для данного прерывания. По завершению обработки прерывания процессор должен восстановить состояние ресурсов, соответствующее прерванной программе, после чего она может быть продолжена. Следует отметить, что для сохранения всех требуемых ресурсов, поиска источника прерывания и перехода к процедуре обработки прерывания процессор должен затратить вполне определенное время. Это время называется скрытым временем прерывания. Чем меньше скрытое время прерывания, тем выше скорость реакции системы на внешние события и тем выше производительность системы. Во многом это определяется системой прерывания процессора и она является одной из основных особенностей архитектуры контроллера.

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

Одноуровневые прерывания

Данная система прерываний реализована таким образом, что при возникновении прерывания процессор аппаратно переходит к подпрограмме обработки прерываний, расположенной по некоторому фиксированному адресу. Чтобы упростить аппаратную часть системы прерываний, этот адрес обычно располагается либо в начале, либо в конце адресного пространства программной памяти. Поскольку для обработки ВСЕХ прерываний используется только ОДНА точка входа, то такая система прерываний получила название одноуровневой. В такой системе выявление источника прерываний путем опроса состояния флажков признаков прерываний в начале программы обработки прерываний. При обнаружении установленного флажка происходит переход к соответствующему участку процедуры. Чем больше возможных источников прерываний, тем больше времени необходимо для обнаружения источника прерывания. Такой метод обнаружения источника прерывания называется программным опросом или поллингом ( polling ). Его недостатком является довольно большое время, затрачиваемое на поиск источника прерывания и, как следствие, замедленная реакция системы на внешние события. Его достоинство – простота реализации системы прерываний.

Векторные прерывания

Чтобы значительно уменьшить время реакции на внешние события, используются многоуровневые или, что то же самое, векторные прерывания. В векторных прерываниях КАЖДОМУ источнику прерывания соответствует СВОЙ, вполне определенный, адрес процедуры обработки прерывания, который принято называть вектором прерывания.

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

PIC vs . AVR vs. MSP vs mcs51. В контроллерах PIC 16 реализована одноуровневая система прерывания. При возникновении прерывания, процессор переходит по адресу 0x0004 (точка входа по прерыванию). Далее, после контекстного сохранения регистров, выполняется программный опрос признаков прерываний ( поллинг ). Нужно также отметить, что при обнаружении источника прерывания требуется сбросить соответствующий установленный флажок запроса на прерывания.

В семействе PIC 18 используется как одноуровневая (в режиме совместимости с PIC 16), так и двухуровневая система прерываний. В режиме совместимости при возникновении прерывания процессор переходит к процедуре обработки прерывания по адресу 0 x 000008 и далее все происходит аналогично PIC 16. При двухуровневой системе прерывания имеются два вектора перехода 0 x 000008 и 0 x 000018. Присвоение уровня каждому из имеющихся источников прерывания задается программным путем, с помощью соответствующих признаков. Способ организации системы прерывания (одно- или двухуровневая ) также определяется значением соответствующего разряда в регистре управления прерываниями.

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

В контроллерах семейства MSP 430 система прерываний также является векторной, т.е. каждому периферийному модулю соответствует свой вектор прерывания. Однако , это не исключает необходимости программного контроля ( поллинга ), т.к. некоторые периферийные модули имеют множественные источники прерываний. Пример – прерывания от порта ввода/вывода. В данном случае имеется возможность программно разрешать прерывания от индивидуальных выводов порта. Даже в том случае, если разрешены прерывания от более , чем одного входа, они все будут иметь одинаковый вектор прерываний. Определить какой конкретно вход являлся источником прерывания можно только программно. Эта особенность также влияет и на сброс флагов прерываний – флаги прерывания с множественными источниками не сбрасываются автоматически в отличие от флагов прерывания с одним источником. Адрес и количество векторов прерывания зависят от конкретного типа контроллера. Вектора прерываний находятся в конце программной памяти (адресного пространства) и представляют из себя адрес обработчика прерывания.

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

Приоритетные прерывания

Обычно, значимость тех или иных событий в системе неодинакова. Одни события более важны и требуют немедленной реакции, другие менее важны, и с ответом на них можно подождать. Естественно, что и соответствующие этим событиям прерывания должны иметь разный приоритет. При одновременном возникновении нескольких прерываний, процессор должен перейти к обработке прерывания, имеющего более высокий приоритет. Этот процесс происходит на аппаратном уровне ядра процессора и называется последовательностью опроса прерываний ( interrupt polling sequence ).

PIC vs . AVR vs MSP vs. mcs51. В семействе PIC 16 приоритет опроса того или иного прерывания определяется очередностью опроса соответствующего флажка прерывания. Приоритет опроса прерывания будет выше у тех прерываний, у которых флажки запросов на прерывания будут опрашиваться в первую очередь. Порядок опроса флажков признаков прерывания целиком определяется программой обработки прерывания и может быть изменен при ее изменении.

В контроллерах PIC 18 при двухуровневой системе прерывания более высокий уровень приоритета имеют прерывания с вектором 0 x 000008. В пределах одного уровня приоритетность прерывания определяется программно, так же как и у PIC 16.

В семействе AVR приоритета опроса жестко фиксирован и не может быть изменен. Чем меньше адрес вектора прерывания, тем выше уровень опроса прерывания ему соответствующего.

В семействе MSP 430 приоритет опроса также жестко фиксирован и неизменяем, но зависимость приоритета опроса прерывания обратная – чем выше адрес вектора прерывания, тем выше приоритет опроса данного прерывания.

В семействе mcs 51 приоритет опроса полностью анологичен контроллерам семейства AVR .

Вложенные прерывания

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

PIC vs . AVR . В семействе PIC16 процедура обработки любого прерывания начинается с одного и того же адреса и реализовать вложенные прерывания крайне затруднительно, если это вообще возможно.

В контроллерах PIC 18 при двухуровневой системе прерывания возможно прерывание процедур прерывания с низким уровнем приоритета прерываниями, имеющими более высокий уровень.

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

Аналогично организована обработка прерываний в семействе MSP . Следует, однако, отметить, что организация программы с вложенными прерываниями требует от программиста особого внимания. Более того, обработка прерывания внутри другого прерывания вообще является нежелательной и должна применяться только в крайних случаях. Ввиду того, что флаги прерываний устанавливаются аппаратно вне зависимости от того, разрешены ли прерывания глобально битом GIE , в большинстве случаев не представляет сложности обработка прерываний без использования вложенности.

В семействе mcs 51 аппаратно предусмотрена возможность вложенных прерываний. Для этого каждому типу прерывания может быть задан уровень приоритета high и прерывание с данным уровнем может прервать обработку другого прерывания с уровнем приоритета low . Приоритеты внутри одного уровня приоритета располагаются согласно последовательности опроса прерываний ( interrupt polling sequence ).

Прерывания

Частенько бывает, что микросхемка должна работать-работать себе спокойненько, а на какое-то событие бросать все дела и выполнять что-то иное. А потом — снова возвращаться к первоначальному делу. Это как в часах, например, — они показывают время до тех пор, пока не настанет время будильника. И вроде как никаких внешних воздействий — нажатия там кнопки, ресета — а микросхема сама переключается.

Это и можно реализовать с помощью прерываний — сигналов, сообщающих процессору о наступлении какого-либо события.

Вот пример из бытовой жизни — сидите Вы на кухне, пьете чай с малиновым вареньем и вкусняшками неприменно, и ждете гостей. А как узнать, что кто-то пришел? Тут два варианта: либо мы каждые пять минут будем отвлекаться от варенья, в смысле, чая и бегать проверять, а не стоит ли кто за дверью, либо купить дверной звонок и спокойненько ждать на нагретом месте, пока кто-нибудь в него не позвонит.

Так вот, когда гость звонит — это событие. Соответственно, мы прерываемся и кидаемся к двери.

Итак, у микросхемы есть прерывания. И не одно. Прерывания делятся на внешние — такие срабатывают при определённом напряжении на некоторых выводах микросхемы (INT0, INT1 и также иногда целый порт PCINT ) — и внутренние — при переполнении счётчика, срабатывании сторжевого таймера, при использовании USART, при прерывании аналогового компаратора, АЦП и прочей периферии.

Соответственно, возникает проблема приоритета. Это как мы все также сидим и пьем чай, но звонят нам уже не только в дверь, но и по телефону. И ведь не разорвешься, что-то нужно сделать первым. Поэтому в даташите есть таблица векторов прерываний. Чем меньше номер прерывания, тем более оно приоритетно.

Здесь получается несколько тонкостей.

Вот произошло событие — пошел запрос на прерывание, то есть выставляется так называемый «флаг запроса на прерывание». Если все хорошо, прерывание разрешено, то жизнь прекрасна и происходит его обработка.

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

НО! Получается, что даже если прерывание обрабатывается, не факт, что событие, которое его вызвало, ещё живо. Это как позвонили в дверь и по телефону одновременно, Вы ответили по телефону, а гости уже решили, что никого дома нету и ушли. И вроде как событие — звонок в дверь — было, а за дверью никого нет.

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

Ещё одна особенность использования прерываний — да и не только прерываний: реентерабельность (или повторная входимость).

Реентерабельная программа — та, которую могут вызвать несколько пользователей (или процессов), и при этом как минимум не возникнет ошибка, а как максимум — не будет потери вычислений — например, другому пользователю не придется выполнять код снова.

Иными словами, если на кухне во то время, пока Вы встречаете гостей, никто не утащит себе вкусняшки, то значит все реентерабельно)

В общем, серезная штука — если её не учитывать, можно долго мучится с «а чего же она не работает?!». Нужно её учитывать, например, если обрабатываются несколько прерываний, и каждое изменяет какую-то глобальную переменную.

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

Рассмотрим работу с внешними прерываниями: нам нужно, во-первых, настроить, по какому событию будет происходить прерывание, а, во-вторых, разрешить микросхеме вообще обрабатывать это самое прерывание.

За первое в микросхеме ATmega8 отвечает регистр MCUCR — биты ISC11-ISC10, отвечающие за INT1, и ISC01-ISC00, отвечающие за INT0.

ISC11 ISC10 Событие, по которому генерируется прерывание
0 0 Нижний уровень на выводе INT1
0 1 Любое изменение уровня на выводе INT1
1 0 Нисходящий фронт сигнала (смена 1 на 0) на выводе INT1
1 1 Восходящий фронт сигнала (смена 0 на 1) на выводе INT1

Таблица 1. Определение событий для генерации прерывания по INT1

Соответственно, с INT0 аналогично.

А теперь остается разрешить прерывания по нужному нам выводу — в регистре GIGR есть биты INT0 и INT1; поставить на нужный «1» — и внешнее прерывание разрешено! Но ещё рано радоваться — помимо внешних прерываний надо разрешить прерывания вообще — ставим крайний левый бит I регистра SREG в «1». Это же можно сделать и ассемблерной командой: asm sei;

Рассмотрим простой примерчик: на ножку INT0 (D.2) микросхемы ATmega8 присоединена кнопка (к ножке и на ноль); нажимаем — возникает прерывание и включается светодиодик на выводе B.0. Светодиод, соответственно, подключен к ножке и на единицу:

//программа для ATmega8 при нажатии на кнопку на выводе INT0 (D.2) - присоединена к 0 - //включает по внешнему прерыванию светодиодик на выводе B.0 - присоединён к 1 //переопределяем типы typedef unsigned char byte; sbit ddrButton at ddD2_bit; //кнопка генерации sbit pinButton at pinD2_bit; sbit portButton at portD2_bit; sbit ddrLight at ddB0_bit; //вывод для светодиода, на выход с подтяжкой, включается 0 по кнопке sbit portLight at portB0_bit; byte flagButton = 0; //флаг нажатия кнопки; нажата - 1 void INT0_interrupt() org IVT_ADDR_INT0 //нужно написать как минимум пустую функцию - //потому что компилятор сам не создает. Иначе не работает < flagButton = 1; >//обработка нажатия кнопки - с учётом дребезга void buttonLight() < if(flagButton) //если нажата кнопка < portLight = 0; //включаем светодиод delay_ms(500); portLight = 1; //выключаем светодиод flagButton = 0; >> void main() < //инициализация всех используемых портов ddrB = 0; portB = 0; ddrD = 0; portD = 0; //инициализация кнопки - на вход с подтяжкой portButton = 1; ddrButton = 0; //инициализация светодиодика, которая включается по 0 и нажатию кнопки - на выход и в 1 portLight = 1; ddrLight = 1; //настраиваем внешние прерывания MCUCR.ISC00 = 0; //прерывание генерируется по логическому 0 на INT0 MCUCR.ISC01 = 0; GICR.INT0 = 1; //разрешаем внешнее прерывание INT0 asm sei;//SREG.B7 = 1; //разрешаем прерывания в принципе (бит I); команды аналогичны while(1) < buttonLight(); >>

Немного о синтаксисе. Функция прерывания написана так: void имя_функции() org IVT_ADDR_INT0.

Ключевое слово org указывает, что дальше будет идти адрес прерывания из даташита. У нас же есть название прерывания из библиотечки: набираем IVT и и дальше нажимаем Ctrl + Пробел (люблю я такие вещички ˆˆ). Ещё вместо слова org можно использовать iv, судя по справке компилятора.

Ещё маленькое замечание: во-первых, прерывание никогда не должно быть громоздким — несколько строк и все. Это связано с тем, что во время обработки прерывания микросхема не может отвлечься на что-либо иное, азначит, если у нас прерываний несколько, то можно пропустить наступление какого-нибудь события.

А ещё может оказаться так, что обработка прерывания нам вообще не нужна — например, достаточно, что схема вышла из спящего режима. Но в этом случае все равно надо писать функцию прерывания, пусть даже пустую — так называемую «заглушку». В принципе, некоторые компиляторы автоматически пишут пустые функции для каждого прерывания, но это не наш случай — приходится делать ручками.

Прерывания

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

Прерывания

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

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

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

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

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

Время реакции на прерывание

tp – время реакции системы на прерывание;
tз – время запоминания состояния прерываемой программы;
tппр – время собственно прерывающей программы;
tв – время восстановления состояния прерванной программы

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

Глубина прерываний

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

Характеристиками системы прерывания являются:

  • общее количество запросов прерывания количество источников запросов прерывания;
  • тип представления прерывания – как правило, запрос прерывания представлен логическим уровнем сигнала;
  • приоритет прерывания – определяет очередность обработки каждого запроса прерывания, чем выше приоритет, тем меньше задержка в исполнении прерывающей программы для него;
  • время реакции – временной интервал между появлением запроса прерывания и началом выполнения прерывающей программы;
  • задержка прерывания – определяется суммарным временем на запоминание и восстановление программы;
  • глубина, обычно совпадает с числом уровней приоритетов в системе прерывания;
  • насыщение системы прерывания;
  • допустимые моменты прерывания программ (как правило, окончание выполнения следующей команды).

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

Комментариев к записи: 1

Что такое прерывание в микроконтроллере

�� � ��������

Теги статьи: Добавить тег

Для чего нужны прерывания? Автор:
Опубликовано 01.01.1970

Прерывание — это остановка извне выполнения текущей программы на время выполнения некоторой подпрограммы (которая называется «обработчик прерывания»). Что это значит? Прерывание возникает по некоторому внешнему сигналу, поступающему в процессор. При этом, основная программа останавливается в совершенно произвольном месте (где ее застанет прерывание), и начинается выполнение подпрограммы-обработчика. По окончании работы обработчика, выполнение основной программы возобновляется с места останова. Это бывает очень полезно, если необходимо оперативно среагировать на какое-то внешнее событие. Например, на нажатие кнопочки, на начало передачи данных… И т.д. и т.п. В AT90s2313 существует 11 событий, по которым можно установить прерывания (прерывание — дело добровольное, хочешь — ставишь, хочешь — не ставишь). Что это за события? Открываем даташит по микросхеме на стр.19 и смотрим табличку «Reset and interrupt vectors». Для ленивых привожу ее здесь:

Таблица прерываний контроллера AT90S2313

  1. Reset — прерывание по сбросу (подача 0 на вывод микросхемы «Reset»; или включение питания; или по переполнению сторожевого таймера)
  2. INT_0 — первое внешнее прерывание (сигнал на вывод микросхемы «INT0»)
  3. INT_1 — второе внешнее прерывание (сигнал на «INT1»)
  4. Timer1_capt1 — прерывание защелки 1-го таймера
  5. Timer1_comp1 — прерывание компаратора 1-го таймера
  6. Timer1_OVF1 — по переполнению 1-го таймера
  7. Timer0_OVF0 — по переполнению 0-го таймера
  8. UART_RX — по окончанию приема пакета по протоколу UART
  9. UART_UDRE — по опустошению регистра данных UART
  10. UART_TX — по окончанию передачи пакета по UART
  11. ANA_COMP — прерывание аналогового компаратора

Если некоторые слова вам еще не знакомы — не отчаивайтесь, так и должно быть. Давайте лучше разбираться, что такое — Interrupt Vectors — Вектора Прерываний? А это ни что иное, как указатели на адрес ПЗУ, на который мы переходим в результате прерывания. Все векторы расположены в самом начале адресного пространства, и занимают первые 11 адресов ПЗУ (с $000 по $00A). Это прекрасно видно из таблицы. То есть, если мы, скажем, хотим активизировать прерывание Timer1_comp1, то мы должны по адресу $004 поставить ссылку на подпрограмму — обработчик этого прерывания. А вообще, лучше расставить в начале программы ссылки на все прерывания. Давайте так и сделаем.

.cseg .org 0 rjmp Reset rjmp INT_0 rjmp INT_1 rjmp Timer1_capt1 rjmp Timer1_comp1 rjmp Timer1_OVF1 rjmp Timer0_OVF0 rjmp UART_RX rjmp UART_UDRE rjmp UART_TX rjmp ANA_COMP

Так как эти команды стоят в самом начале программы, значит они как раз таки будут расположены в ПЗУ по первым 11-ти адресам. Таким образом, при каждом прерывании, будет вызываться соответствующий обработчик.

Например: по прерыванию компаратора таймера 1 (Timer1_comp1), мы перескакиваем на адрес $004, то есть — на 5-ю строчку программы. В пятой строчке стоит безусловный переход на метку Timer1_comp1. Где-то ниже в программе, мы пишем обработчик этого прерывания и в его начале ставим эту метку. Вот так все несложно…

Ну а что делать с остальными прерываниями, которые не используются? Надо все равно прописать на них метки (иначе компилятор страшно выругается), но по этим меткам ничего не делать, а тут же выходить.

Кстати, чуть не забыл:

reti — Interrupt return — выход из обработчика прерывания

Reset: INT_0: INT_1: Timer1_capt1: Timer1_comp1: Timer1_OVF1: Timer0_OVF0: UART_RX: UART_UDRE: UART_TX: ANA_COMP: reti

Пусть вас не смущает, что столько меток стоят на одну команду: это не страшно, так можно делать. Нельзя ставить несколько ОДИНАКОВЫХ меток…

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

Ну вот. Теперь возвращаемся к нашим баранам. То есть — бегущим огонечкам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *