Ранее рассмотренные подпрограммы можно назвать «предсказуемыми» событиями, поскольку они вызываются в соответствии с логикой программы. Ситуации реального времени далеко не так просты. Очень часто вне ядра ЦП происходят события, требующие немедленной реакции процессора.
Контроллеры способны реагировать на самые разнообразные события такого рода, нарушающие их нормальное функционирование. Они могут исходить как от встроенных периферийных устройств, так и от источника, совершенно не связанного с микроконтроллером. В качестве реакции микроконтроллер должен перейти к специальной подпрограмме, называемой подпрограммой обработки прерываний или обработчиком прерываний.
Микроконтроллер PIC 1684 поддерживает 4 типа различных прерываний от периферийных устройств, в том числе и внешнее прерывание. Несмотря на различные набор периферийных устройств (ЦАП, АЦП, таймеры, последовательный порт), все они реагируют на прерывания одинаково. Этими основными источниками являются:
· Внешний сигнал, подаваемый на вход INT. Это внешнее прерывание может генерироваться либо по нарастающему , либо по спадающему фронту входного сигнала, что определяется состоянием бита INTEDG регистра OPTION_REG (соответственно бит 1 и бит 0).
· Изменением состояния любого из старших четырех разрядов порта В.
· Переполнение счетного регистра таймера/счетчика TMR0 с H’FF’ → H’00’
Программист может запретить или разрешить прерывания от этих источников, а также полностью запретить работу всей системы в целом. Pеакция на прерывание в микроконтроллерах среднего уровня (PIC 1684) показана на Рис. 10.1
Рис. 10.1. Отклик на запрос прерывания
Отклик процессора на запрос прерывания будет выглядит следующим образом:
1. Завершить выполнение текущей команды.
2. Автоматически сохранить состояние программного счетчика РС (для возврата из подпрограммы прерываний) и содержимое регистра STATUS.
3. Перейти к соответствующей процедуре обработки прерываний.
4. Выполнить требуемые действия.
5. Восстановить состояние процессора и вернуться к тому месту основной программы, в котором произошло прерывание.
Вход внешнего прерывания использует ту же ножку микроконтроллера, к которой подключена 0-я линия порта В - вывод RB0. Поскольку процесс реакции на прерывание не зависит от его источника, начнем рассматривать внешнее прерывание.
Рис. 10.2. Формат регистра прерываний INTCON
Разрешение/запрещение и распознавание прерываний в PIC16F84A производится через регистр INTCON (Рис. 10.2.). С каждым из четырех источников прерываний связан соответствующий бит флага прерывания.
Чтобы разрешить прерывания по входу INT, придется установить биты 7 и 4 регистра INTCON, т.е. выполнить команды
BSF INTCON,GIE ; разрешение всех прерываний
BSF INTCON,INTE; и по входуRB0/INT
При наличии разрешения
а) запрещается вся система прерываний (чтобы обработать текущее). Это осуществляется сбросом 7-го бита регистра INTCON (GIE);
б) состояние 13-битного программного счетчика РС заносится в стек;
в) первая команда обработчика прерываний всегда начинается по адресу Н’04’, называемому вектором прерывания;
г) процедура обработки прерывания должна завершиться командой возврата. Однако при завершении прерывания необходимо не только извлечь из стека сохраненное значение РС, но и установить бит GIE регистра INTCON для разрешения последующих прерываний. Для этого используется команда RETFIE;
д) при обработке прерывания жизненно важно сбросить флаг прерывания в процедуре обработки прерывания перед выходом из обработчика, т.е. выполнить команду BCF INTCON,INTF.
Каждый флаг прерывания имеет соответствующий бит разрешения прерывания. Так, флагу INTF соответствует бит INTЕ.
Пример1:Программа подсчета числа посетителей
При пересечении луча лазера покупателем на вход микроконтроллера поступает сигнал запроса в виде прямоугольного импульса. В этот момент микроконтроллер занят выполнение своей основной задачи, например, организацией обмена данными между торговым терминалом и основным компьютером склада.
Рис. 10.3. Контроль числа посетителей магазина
При каждом проходе посетителей инкрементируется регистр COUNT. Проход разделим на два, чтобы получить реальное количество посетителей. Максимальное число посетителей, регистрируемое нашей системой, составит 255. Указанное ограничение можно преодолеть, задействовав дополнительные регистры.
В начале программы размещена команда GOTO START. По адресу 04Н, называемому вектором прерывания. Размещена подпрограмма обработчика прерывания.
В основной программе просто устанавливают биты INTE и GIE для разрешения внешних прерываний, а также обнуляется счетчик COUNT. Расположенный далее бесконечный цикл представляет собой фоновые задачи процессора.
С точки зрения программы прерывания могут возникать произвольно при выполнении любого участка основной программы.
;****************************************
; COUNT - Подсчет числа посетителей
;****************************************
; регистры хранения состояния W и STATUS
_WORK EQU H‘4F’;ячейка для сохранения регистра w
_STATUS EQU H‘4E’;ячейка для сохранения регистра STATUS
Обработчик прерываний в своей программе может использовать регистры и , если перед исполнением подпрограммы обработки прерываний их содержимое не сохранить, то это может привести к непредсказуемым последствиям. Для работы в качестве временного хранилища используют регистры данных, которые больше ни для чего не используются.
Любую процедуру обработки данных условно можно разделить на три части:
1. Сохранение контекста
Сначала копия рабочего регистра сохраняется в регистре_work. Затем регистр STATUS сохраняется в регистре данных _STATUS (4Fh).Команда SWAPF не изменяет значение флагов, однако меняет местами тетрады байта. Их нормальное положение восстанавливается при восстановлении регистра.
2. Основной код
Сбрасывается флаг прерывания INTF, чтобы избежать повторного перехода к обработке прерыванияпосле возврата в основную программу. В рабочей секции основного кода просто инкрементируется содержимое регистра COUNT. Это основная задача процедуры обработки прерывания.
3. Восстановление контекста.
При завершении обработки в рабочий регистр с помощью команды SWAPF заносится содержимое регистра STATUS, которое затем копируется оттуда в STATUS.
Исходное значение W восстанавливается из временной переменной _WORK с использованием двух последовательных команд SWAPF. При этом значение регистра STATUS не изменяется.
Программа реализует электронный аналог игральной кости с шестью светодиодами, подключенными с старшим разрядам порта В, как показано на Рис. 10.4.Основная программа будет инкрементировать переменную с максимально возможной скоростью и сбрасывает ее в ноль, когда она становится больше пяти. При нажатии на кнопку, подключенной ко входу , программа будет переходить к обработчику прерывания. Процедура обработки прерывания отобразит одну из шести комбинаций светодиодов.
Рис. 10.4. Коды управления светодиодами электронной игральной кости
Основная программа инкрементирует переменную THROW сбрасывает ее в ноль, когда она становится больше пяти. Таким образом, реализуется программный счетчик по модулю шесть, т.е. 0, 1, 2, 3, 4, 5, 0,..
Компилятор PIC Simulator IDE генерирует основную программу. Состоящую из десяти команд, включая команду безусловного перехода и сброса переменной. В результате при тактовой частоте 4 МГц инкрементирование переменной происходит 10 000 раз в секунду. Такая частота обеспечит практически случайный выбор одного из шести значений по нажатию кнопки, подключенной к выводу RB0/INT.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
- Прерывание - это своеобразный переход, в большинстве случаев, по внешнему воздействию, из основной программы, на выполнение подпрограммы прерывания, с последующим из нее возвратом в основную программу.
- По наступлению события прерывания нормальное выполнение программы будет остановлено и программа перейдет на адрес ПЗУ 0x004, который называется вектором прерывания. По этому адресу и должна находиться подпрограмма отработки прерывания. При этом адрес возврата сохраняется в стеке.
У PIC – контроллеров вектор прерывания один для всех источников, поэтому данная подпрограмма должна сама различать события, вызвавшие прерывание, если разрешено более одного прерывания. Определение источника прерывания производится путем опроса соответствующих флагов прерывания, которые устанавливаются по наступлению прерывания. По прерыванию по входу RB0 – флаг INTF (INTCON,1), а по входу RB4 - RB7 – RBIF (INTCON,0).
Главное преимущество работы со всеми типами прерываний - малая инерционность отклика устройства на внешний управляющий сигнал прерывания (активный перепад), что может быть очень полезным в тех конструкторских разработках, к которым предъявляются жесткие требования по инерционности (скорости) срабатывания исполнительных устройств.
- Метки для команд условного перехода и DECFSZ должны лежать в границах 0 до 256 байт.
- При использовании команды DECFSZ, инициализируйте регистр CNT положительным числом. Команда DECFSZ контролирует только нулевое значение, при отрицательном программа будет продолжать циклиться.
- Если некоторая команда устанавливает флаг, то данный флаг сохраняет это значение, пока другая команда его не изменит. Например, если за арифметической командой, которая устанавливает флаги, следуют команды MOV, то они не изменят флаги. Однако, для минимизации числа возможных ошибок, следует кодировать команды условного перехода непосредственно после команд, устанавливающих проверяемые флаги.
- Команда вызова процедуры CALL работает совместно с командой RETURN. При этом при исполнении команды CАLL В10 МК выполняет два действия:
· в программный счетчик РС заносится адрес процедуры В10 и исполнение программы продолжается по указанному адресу;
· в стек STACK заносится адрес возврата в основную программу – адрес следующей за CАLL В10 команды.
· вызываемая процедура может, в свою очередь, вызвать другую процедуру, и если следовать существующим соглашениям, то команда RETURN всегда будет выбирать из стека правильный адрес возврата
По команде RETURN содержимое стека загружается в программный счетчик РС и работа основной программы продолжается.
- Используйте команды сдвига для удваивания значений и для деления пополам.
ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
1.Каким образом может программа начать выполнение процедуры?
2.В программе процедура A10 вызывает B10, B10 вызывает C10, а C10 вызывает D10. Сколько адресов возврата содержит стек?
3.Напишите программу формирования 10-ти периодов звукового сигнала частотой 1 кГц.
4.Напишите программу формирования двухтонального звукового сигнала: импульсы частотой 5кГц и скважностью два заполнены частотой 500 Гц.
INT_RB4_7: Прерывания от изменения уровня на ножках порта RB<7:4>.
Прерывания от изменения уровня на ножках порта RB4...RB7 являются одной из разновидностей прерываний. В отличие от прерываний по выводу INT, где нужно предварительно определить активные фронты прерываний (бит INTEDG регистра Option), для прерываний по изменению уровней сигналов на выводах RB4...RB7, этого делать не требуется, так как уход в эти прерывания происходит и при смене 0 на 1, и при смене 1 на 0 на любом из выводов RB4...RB7.
Если сравнить прерывания по выводу INT и прерывания от изменения сигналов на любом из выводов RB4...RB7, то, за исключением указанного выше и того, что перед выходом из прерывания нужно сбросить другой флаг (RBIF), их механизм одинаков. Так что, если речь идет только об одном внешнем устройстве, которое является источником прерываний, и нужно уйти в прерывания не по какому-то конкретному перепаду, а по любому перепаду внешнего управления, то это внешнее устройство можно подключить к любому из 4-х выводов RB4...RB7.
Естественно, при задействовании под прерывания выводов RB4...RB7, они должны быть предварительно настроены на вход. Вопрос о подключении или отключении подтягивающих резисторов решается в каждом конкретном случае (зависит от схемотехники внешнего источника прерываний).
К четырем выводам RB4...RB7 можно подключить четыре источника прерываний и получить 16 комбинаций (24) подпрограмм прерываний, причем, как бы "нейтральной" комбинацией является только 0000, а переход от нее к любой из оставшихся 15 комбинаций связан со срабатыванием одного или нескольких источников прерываний.
К этим 15-ти сценариям можно "привязать" до 15-ти отдельных внешних исполнительных устройств (если выводов портов для этого достаточно) или меньшее количество внешних исполнительных устройств, но работающих в комплексе и обеспечивающих до 15 комбинаций их срабатываний.
Для "слабосильных" PICов типа PIC16F84A, последний вариант наиболее приемлем (просто деваться некуда, так как выводов его портов для 1-го варианта не достаточно).
После ухода в прерывание, "привязка" к конкретным сценариям осуществляется в подпрограмме прерывания. Для этого организуется многосценарный вычисляемый табличный переход с тем количеством сценариев, которое нужно. Естественно, перед его осуществлением, необходимо составить соответствующее количество исполнительных подпрограмм и адресно привязать все сценарии к соответствующим комбинациям 4-х источников прерывания.
CLRF TRISA ; Все выводы порта А работают на выход.
BCF STATUS,RP0 ; Установка 0-го банка.
GOTO START ; Переход на начало START.
; Конец текста программы----------------------------------
END
Рис. 11.4.Прерывания от изменения уровня на ножках порта RB<7:4>
Программа INTRB4_7 отображает номер комбинации источников прерывания в двоичном коде с помощью светодиодов, подключенных к выводам порта В (RB0...RB3). Всего комбинаций 15. "Нейтральная" комбинация 0000 соответствует "пустышке" (все светодиоды погашены и ничего не происходит).
Формирование исходных данных для работы процедуры вычисляемого перехода происходит при считатывании состояния выводов RB4...RB7 порта В и его копирования в регистр W. Перед копированием блокируется младший полубайт (ANDLW B'11110000') и полубайты меняются местами SWAPF. Теперь младший полубайт несет информацию о номере комбинации источников прерывания, что и используется для организации вычисляемого перехода, а в старший будет выводиться двоичный код любой из 15-ти комбинаций.
Для того чтобы его сменить, нужно установить новую комбинацию источников прерывания ит.д.
Можно ввел в программу "ограничитель высвечивания": в простейшем случае, это подпрограмма задержки, посложнее – программа звукового генератора с ограниченным временем работы.
Звуковой сигнал будет указывать о нахождении программы в подпрограмме прерывания.. при любой комбинации источников прерывания он будет оповещать о времени исполнения текущего сценария, а после его окончания вывод на индикацию прекращается и все светодиоды будут находиться в погашенном состоянии вплоть до следующей комбинации источников прерывания.
В состав P16C84А входят периферийные модули: сторожевой таймер WDT и счетчик/таймер TMR0. Для инициализации последнего используется регистр OPTION.
Сторожевой таймер WDT
В случае зависания программы по какой-либо причине, WDT может вывести ее из этого состояния, переведя программу в положение START. Он представляет ждущий RC-мультивибратор с перезапуском, формирующий импульс длительностью примерно 18мс. Если работа WDT разрешена (а она может быть и запрещена), то после старта программы, он запускается, и, если его в течение 18мс не перезапустить, то он окончит формирование импульса и по его заднему фронту сформируется сигнал сброса программы на начало.
OPTION_REG
PS2 PS1 PS0
CLRWDT
PSA
&
7 0 7 0
Counter
RC oscillator
PRESCALER
МК
WDTE
Рис.11.6
Именно поэтому таймер WDT и назван сторожевым. Для обеспечения этого сторожевого режима, необходимо в ходе выполнения программы, периодически (через время не более 18мс) сбрасывать WDT (CLRWDT). Если после WDT поставить предделитель (PRESCALER), то период сброса WDT можно увеличить.
Счетчик/таймер TMR0
Счетчик/таймер - восьми разрядный счетчик с Ксч = 256, но с возможностью предустановки и синхронизации. Предустановка -это запись числа, начиная с которого происходит его счет. Обычно, такого рода загрузку производят для задания некой начальной точки отсчета. Если счетчик/таймер TMR0 работает без предустановки, его коэффициент счета всегда равен 256 и не меняется.
В большинстве же случаев, перед TMR0 включается предделитель с заданным Ксч и, обычно, этого бывает вполне достаточным для решения поставленных задач.
OPTION_REG
PSA PS2 PS1 PS0
TOCS TOSE
RA4/TOCKI
&
&
&
7 0 7 0
PRESCALER
TMR0
O
CLKOUT
Рис.11.7
Основная функция счетчика/таймера TMR0 - подсчет количества импульсов за определенное программой время.
Через каждые 256 импульсов (при переходе из FFН в 00Н) происходит так называемое переполнение таймера, количество которых (при необходимости подсчета количества импульсов большего чем 256) подсчитывается. Например: за 1сек. произошло 10 переполнений, значит TMR0 посчитал 2560 импульсов. Если приплюсовать к этому количеству содержимое TMR0 на момент окончания счета, то мы получим точное количество импульсов, поступивших на вход TMR0 за 1сек.
Если перед TMR0 включен предделитель, то в итог подсчета вносятся соответствующие коррективы, определяемые заданным коэффициентом счета предделителя и числом, "лежащим" в предделителе на момент окончания счета. На такого рода подсчете и основывается принцип работы устройств, производящих подсчет импульсов за заданный интервал времени.
Каждая разновидность прерываний имеет свою специфику. Для прерывания от переполнения TMR0, она заключается в том, что уход в прерывание происходит не по каждому активному управляющему перепаду на входе RA4/TOCKI, а только по тому из них, который приводит к смене .255 на .0.
Если производить отсчет от состояния .0, то уход в прерывание произойдет на 256-м активном перепаде (импульсе), но можно производить отсчет и не от .0, предварительно выполнив предустановку в TMR0 того числа, которое требуется. В этом случае, уход в прерывание будет происходить на (256 – N) импульсе, где N - число предустановки TMR0. В случае использования предделителя и предустановки TMR0, уход в прерывание будет происходить на (256 - N) х Ксч. предделителя импульсе. В простейшем случае, имеет место быть нулевая предустановка TMR0 (CLRF TMR0).
Примечание: когда ко входу TMR0 подключен предделитель, любая операция с содержимым TMR0 (например, CLRF TMR0 или запись в TMR0 константы предустановки) приводит к сбросу содержимого предделителя (специальной команды сброса содержимого предделителя нет) аппаратными средствами PICа.
Вот Вам и исходные данные для ответа на вопрос: "На каком, начиная с момента предустановки TMR0 и с учетом Ксчпредделителя, импульсе произойдет уход в прерывание"?
Например, предустановка - .0, Ксч.предделителя = 8. Уход в прерывание по переполнению TMR0 произойдет на 256 х 8 = 2048 импульсе. Если предустановка, например, .100, Ксч.предделителя = 8, то уход в прерывание по переполнению TMR0 произойдет на (256 - 100) х 8 = 1248 импульсе. Если предустановка, например, .250, а предделитель к TMR0 не подключен, то уход в прерывание по переполнению TMR0 произойдет на 256 - 250 = 6 импульсе и т.д.
В связи с этим, прерывания по переполнению TMR0 используются в том случае, когда нужно задать некую "границу дозволенного", при превышении которой устройство очень быстро (с малой инерционностью) реагирует на ее превышение.
Пример: из каждых 10000 операций допускается 10 операций, результат которых выходит за рамки нормы (пределов дозволенного). Допустим, что этих "ненормальных" операций стало 11. На 11-й операции устройство быстренько срабатывает, и либо вообще блокирует весь процесс, либо вносит поправку, уменьшающую количество этих "ненормальных" операций (либо еще какое-то "полезное" действие). Это "полезное" действие (действия) производится в подпрограмме прерываний. Если питание устройства не выключается, то возможны 2 варианта:
- после совершения "полезного" действия и выхода из прерывания, исполнение программы продолжается с того места основной программы, на котором был обнаружен "дефект".
- программа уходит в подпрогррамму прерываний в "вечное кольцо" и продолжение работы в основной программе не возможно (блокировка).
В качестве внутреннего тактового сигнала используется сигнал с частотой опорного генератора PICа, деленной на 4, т.е. TMR0 будет считать каждый машинный цикл (1мкс при применении кварца на 4мГц). Это - для случая работы TMR0 без предделителя. При применении предделителя, TMR0 будет, естественно, считать медленнее.