Файл: Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 16.06.2025

Просмотров: 3624

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Вопрос: "Почему в тексте Самоучителя..., первой описывается отладка, а только затем, отслеживание"?

Ответ: на мой взгляд, такой порядок "въезда в проблему" наиболее рационален (в смысле доходчивости).

Итак, вернемся к процессу отслеживания работы программы cus. Мы отследили только один сценарий ее работы. Переходим к другим.

Cценарии "порождаются" командами ветвления.

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

По ходу отслеживания "основного" (такая классификация субъективна) сценария программы, в текст программы были "вставлены уловочные" NOPы.

Совместим приятное с полезным: и оставшиеся сценарии отследим, и последовательно "избавимся" от "инородных" NOPов (последовательно вернем текст программы в "исходное состояние").

Начнем с конца текста программы (так удобнее. Подумайте, почему?).

-Снимаем "блокировку" с команд второй проверки (убираем точки с запятыми).

-Убираем nop (после команды btfss PortB,0).

-Возвращаем на свое "штатное" место команду goto PRD.

Это означает то, что созданы условия для "закольцовки" рабочей точки программы в ПП PRD.

Проверяем это.

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

Сбрасываем программу на начало.

Назначаем точкой остановки команду btfss PortB,0. "Запускаем автомат" и ждем окончания его отработки.

Рабочая точка программы "встала" на назначенную точку остановки. Выполняем команду btfss PortB,0.

Всоответствии с логикой команды btfss, рабочая точка программы переместится на команду goto PRD.

Выполняем команду goto PRD.

Произойдет безусловный переход на первую команду ПП PRD ("врезку" clrwdt). А теперь понажимайте клавишу F7 "от души".

Произошла "закольцовка" ("уход в вечное кольцо") рабочей точки программы в ПП PRD, и пока 0-й бит регистра PortB будет равен 0, она так и будет там "крутиться", в чем и требовалось убедиться.

Проверяем следующий сценарий.

Убираем nop (после команды decfsz SecH,F) и возвращаем на свое "штатное" место команду goto CYCLE.

Ассемблируем, устанавливаем программу на начало, назначаем точку остановки на команде decfsz SecH,F.

"Запускаем автомат" и ждем окончания его отработки. Рабочая точка программы "встала" на команду decfsz SecH,F. Выполняем и ее, и следующую за ней команду goto CYCLE.

Рабочая точка программы переместилась на первую команду ПП CYCLE (btfsc PortB,0), и она будет "крутиться по кольцу" до тех пор, пока регистр SecH не очистится, в чем и требовалось убедиться.

Проверяем следующий сценарий.

Убираем nop (после команды btfss PortB,6) и возвращаем на свое "штатное" место команду goto PRD.

Ассемблируем, устанавливаем программу на начало, назначаем точку остановки на команде btfss PortB,6.

"Запускаем автомат" и ждем окончания его отработки. Рабочая точка "встала" на команду btfss PortB,6. Выполняем и ее, и следующую за ней команду goto PRD.

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

Итак, остался последний сценарий.

Заменяем команду btfsc PortB,0 на команду btfss PortB,0 (еще одна "уловка" - берите на

132


заметку).

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

Ассемблируем, устанавливаем программу на начало, назначаем точку остановки на команде btfss PortB,0.

Запускаем "автомат" и ждем окончания его отработки. Рабочая точка "встала" на команду btfss PortB,0. Выполняем и ее, и следующую за ней команду goto START.

Рабочая точка программы переместилась на первую команду ПП START (clrf IntCon) и далее, "закольцовывается" в ней, в чем и требовалось убедиться.

Заменяем "подставу" btfss PortB,0 на "штатную" команду btfsc PortB,0. Ассемблируем текст программы.

Итог: все сценарии работы программы cus отслежены, и текст программы

"приведен в исходное состояние".

Примечание: при отслеживании последних сценариев работы программы cus, точки остановки, конечно же, можно назначать и непосредственно на командах переходов.

Аесли говорить в общем, то для точки остановки, в пределах рабочей части программы, нет никаких ограничений.

В том смысле, что точкой остановки можно назначить любую команду. Итак, я "протащил по программе" не только ее рабочую точку, но и Вас. Почувствовали "почем фунт лиха"?

Каковы ощущения?

Предполагаю, что не типа "райское наслаждение", а несколько иные. Спешу успокоить: "первый бой, он трудный самый".

По мере набора опыта, "дышать будет легче".

Это как с непривычки в парилку зайти: поначалу плоховато, затем начинает нравится, а потом "и за уши не оттащишь".

Аесли серьезно, то программирование в "чистом" ассемблере, это "епархия" упертых, въедливых и вовсе не пугливых людей.

О "манне небесной" тут и речи быть не может.

Прежде чем добраться до "конфетки", "попахать" придется как следует.

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

Пояснение

В этом разделе, применяются словосочетания "отрицательный полупериод" и "положительный полупериод".

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

Если разделительного конденсатора нет, то эти словосочетания некорректны и нужно использовать словосочетания "интервал времени формирования нулевого уровня" и "интервал времени формирования единичного уровня".

"Самоучитель по программированию PIC контроллеров для начинающих" http://ikarab.narod.ru E-mail: karabea@lipetsk.ru

133


11. Прерывания. Стек. Пример разработки программы с уходом в прерывания.

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

И далее будут придуманы и применены слова или короткие фразы, имеющие "привязки" к тем или иным понятиям.

Все это делается, как говорится, "не от хорошей жизни".

А что еще остается делать, если стандартная терминология либо "туманна", либо настолько неудобна и длинна, что если ей пользоваться, то к концу, можно забыть про начало. Можете придумать свою терминологию. Это дело второе.

Главное понимать суть происходящего, а терминология, это всего-лишь "обслуга" сути. Разбираем "технологию" конструирования следующего устройства и программы под него. Рассмотрим такую жизненную ситуацию (из практики моей работы): за большие деньги, закуплены дорогостоящие ретрансляторы Vertex-7000VXR.

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

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

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

Нужно было "спасать положение", а заодно и "прикрыть попу" начальству. Следовательно, возникла задача: перевести однонаправленный ретранслятор Vertex7000VXR в двунаправленный режим работы, с минимальными материальными затратами (себестоимость устройства - не более 250 руб.) и без потери качества ретрансляций. Начинаем "борьбу с неопределенностями".

Сначала нужно "привязаться" к аппаратуре.

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

Таким образом, задача сводится только к изменению "раскладки" частот: при ретрансляции в одну сторону, "раскладка" частот должна быть ПРМ - X, ПРД - Y, а при ретрансляции в другую сторону - наоборот, то есть, ПРМ - Y, ПРД - X.

Следовательно, речь идет о так называемом сканировании частот, то есть, о периодической смене раскладки частот, с остановкой их смены (остановкой сканирования), в интервале времени наличия несущей.

Это должно выглядеть так: при отсутствии несущей, сканирующее устройство должно поочередно переключать направления ретрансляции, то есть, указанные выше "раскладки" частот.

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

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

Если несущая появляется в приемном тракте, настроенном на частоту X, то ретрансляция происходит в одном направлении, а если она появляется в приемном тракте, настроенном на частоту Y, то ретрансляция происходит в другом направлении.

Сам процесс ретрансляции нас "не волнует", так как этим "занимается" ретранслятор. Ретранслятор Vertex-7000VXR, на задней стенке, имеет разъем, с выводов которого можно переключать раскладки частот (конкретные раскладки частот нужно заранее программировать), вывод сигнала управления шумоподавителем (несущая есть/нет = 0/1 соответственно), вывод +13,8v и корпус.

Выход, с которого снимается управляющий сигнал "несущая есть/нет" с открытым коллектором.

134


Входы переключения частот рассчитаны на стандартные 5-вольтовые уровни (преобразователей уровней не нужно).

Таким образом, для подключения сканера к ретранслятору, имеются все необходимые цепи, компактно выведенные на разъем.

Теперь можно перейти к составлению блок-схемы программы.

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

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

"Учебно-тренировочная" необходимость в этом, диктуется тем, что "разборки" с прерываниями архинеобходимы (прерывания очень востребованы).

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

Итак, чтобы двигаться дальше, нужно понять: что такое прерывания? Для начала, отсылаю Вас во 2-й раздел (см. регистр INTCON).

К информации, имеющейся там, можно добавить следующее.

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

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

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

Определимся с терминологией.

Для удобства объяснения и восприятия, целесообразно разделить рабочую часть программы на две части.

Условимся называть группу команд, которая отрабатывается после ухода в прерывание, как подпрограмму прерывания, а все остальное "основным телом" программы.

"Технология" ухода в ПП прерывания следующая: например, мы решили "прерываться" по входу RB0/INT PIC16F84A, есть и другие источники прерываний см. распечатку регистра

INTCON).

Ввожу понятие "зона" разрешения прерываний.

Это "зона" представляет собой группу команд "основного тела" программы, ограниченная сверху, командой разрешения прерываний, а снизу, их запрета.

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

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

Это конечно не "высший сорт", но он сейчас и не нужен.

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

ПП START должна начаться с команды запрета всех прерываний clrf IntCon. Уходы в прерывания должны происходить позднее.

Далее, программа отрабатывается (исполняется) до начала "зоны" разрешения прерываний.

Вначале этой "зоны", прерывания по входу RB0/INT разрешаются, после чего программа исполняется далее, если так можно выразиться, "в режиме ожидания прерываний".

135


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

В"зоне" разрешения прерываний, могут наступить 2 события:

-если прерывания нет, то программа исполняется в пределах "основного тела" программы,

-если прерывание есть (на выводе RB0/INT сформировался активный перепад), то

происходит переход рабочей точки программы на начало исполнения ПП прерываний. Такой переход происходит по стеку.

То есть, в стек записывается адрес следующей, после команды, во время исполнения которой произошло прерывание, команды.

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

Таким образом, рабочая точка программы, на некоторое время, как бы "отлучается" из "основного тела" программы.

На время этой "отлучки", отработка "основного тела" программы приостанавливается, а после возврата, снова возобновляется.

Например, представьте себе, что "зона" разрешения прерываний содержит 3 команды: A, B и С (по тексту программы, сверху вниз).

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

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

Она используется только для возврата из ПП прерывания. По этой команде, осуществляется возврат по стеку.

Это означает то, что из него автоматически извлекается адрес команды В и возврат рабочей точки программы произойдет именно на эту команду, после чего, в "основном теле" программы, программа будет исполняться далее.

Если активный перепад управляющего сигнала сформировался во время исполнения команды В, то в стек запишется адрес команды С.

Ну и так далее.

Учтите, что программист не может напрямую управлять стеком. Он может только косвенно воздействовать на него.

По этой причине, он является как бы "темной лошадкой".

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

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

А раз это так, то где же команда call ?

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

формируется не программно, а аппаратно.

"Отмашкой" на формирование такой "неявной" команды является факт возникновения прерывания.

Более подробно, эта тема будет "провентилирована" позднее.

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

Внашем случае, используется прерывание по входу RB0/INT.

Вэтом случае, команда сброса флага должна выглядеть так: bcf IntCon,1.

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

136