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

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

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

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

Добавлен: 16.06.2025

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

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

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

Память программ многих типов м/контроллеров меньше 8192 слов, но есть и м/контроллеры с объемом памяти программ по максимуму (8 килослов).

С регистром PCL никаких проблем нет. Проблемы есть с регистром PCH.

В частности, они связаны с вычисляемым переходом.

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

Проще говоря, если перед выполнением команды вычисляемого перехода, в PC имела место быть команда, например, с адресом 5 , а в регистре W "лежит" число 2, то, в результате исполнения команды вычисляемого перехода, произойдет переход ("прыжок") на команду с адресом 5+2=7.

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

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

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

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

Вэтом случае, при переполнении PCL, инкремента PCH не происходит.

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

Поэтому можно только предположить, что это ограничение объясняется какими-то специфическими особенностями организации взаимодействия PCL и PCH, детали которого разработчики ПИКов не посчитали нужным разъяснить (просто поставили перед фактом). И это не пустые слова.

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

Пример: начало исполнения вычисляемого перехода приходится на команду с номером, в памяти программ, равным 508.

508 - 256 = 252.

Число 252 вплотную, слева, "подступает к границе" 256-байтного блока (этой "границей" является переход от 255 к 0, и, в этом случае, нужно "держать ушки на макушке" в смысле: "а как бы ее не пересечь".

Если максимальное приращение счетчика команд PC будет менее числа 3 включительно, то "произойдет переход на планируемую программистом команду (509, 510, 511), а если оно будет более трех, например, 4, то, в результате сложения, содержимое регистра PCL окажется нулевым (252+4=256: 0 и 256 - одно и то же, но общепринято указывать 0), плюс инкремент содержимого регистра PCH.

Но, в случае вычисляемого перехода, инкремента содержимого регистра PCH не происходит.

Вконечном итоге, переход на 512-ю команду не осуществляется, а вместо этого осуществляется возврат назад, на 256-ю команду (в PCH "лежало" число 00000001, и оно, в случае вычисляемого перехода, не изменилось, а в регистре PCL будет "лежать" 00000000), что есть сбой.

Пояснения к этому примеру:

Двоичное представление числа 508: 00000001 (PCH) 11111100 (PCL).

Для вычисляемого перехода с приращением 3, результат: 00000001 11111111 - все в норме: переход будет осуществлен на 508+3=511-ю команду.

Для вычисляемого перехода с приращением 4, должен быть результат 00000010 00000000, но на самом деле, будет результат 000000001 00000000 (приращения PCH нет), то есть, 256. Переход будет осуществлен на 256-ю команду, а должен быть на 512-ю команду (сбой). Для того чтобы предотвратить подобного рода сбои, операцию вычисляемого перехода не нужно организовывать в непосредственной близости от "границ" 256-командных блоков памяти программ.

21


Практический вывод: в части касающейся PIC16F84A PC 1024 слова), если вычисляемого перехода нет, то о регистре PCH можно вообще "забыть", то есть, не обращать на него внимания, так как содержимое этого регистра будет изменяться "в автомате" и вмешательства программиста в этот процесс просто не требуется.

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

Регистры INDF и FSR - регистры косвенной адресации. Здесь необходимо кое-что пояснить.

Существует 2 вида адресации: прямая и косвенная.

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

При этом, адрес этого регистра в области оперативной памяти, определяется в "автомате" (по его названию).

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

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

Для начинающих это звучит достаточно непонятно. Пока примите это к сведению.

Это нужно уяснять на конкретных примерах.

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

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

Ито, и другое предстоит сделать.

Инаконец, самый часто используемый регистр - регистр W или его еще называют

аккумулятором.

Это тот же регистр общего назначения, только с определенным названием (в том смысле, что оно заранее определено так же, как и названия регистров специального назначения).

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

Стоит только обратиться к регистру W, как адрес автоматически поставится ему в соответствие.

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

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

Флаги

Определение флагов дано выше.

Основная часть флагов находится в регистре STATUS.

Самый часто применяемый из них - флаг нулевого результата (2-й бит с названием Z). Он показывает, является ли результатом проведенной операции нулевой результат (флаг поднят, что соответствует установке 2-го бита регистра STATUS в 1) или этот результат не нулевой (флаг опущен: во 2-м бите - 0).

Кроме информирования программиста о результате операции, содержимое бита Z может являться критерием выбора того или иного сценария работы программы, для чего он чаще всего и применяется.

Например, программист поставил условие: если результат операции не равен 0, то программа исполняется далее, а если равен нулю, то происходит переход на выполнение подпрограммы (или на метку) ABCD.

После выполнения операции, флаг или останется опущенным (0) или поднимется (1). Далее следует команда ветвления типа: если 2-й бит регистра STATUS не равен 0, то программа исполняется дальше, а если равен 0, то происходит переход на выполнение

22


подпрограммы (или на метку) ABCD. Дешево и сердито.

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

Не трудно заметить, что анализ содержимого бита Z (а также и некоторых других флагов), происходит при выполнении так называемых команд ветвления, суть которых: если X, то так, а если Y, то по другому, применяющихся при выборе так называемых "сценариев работы программы".

Это словосочетание также, как и словосочетание "рабочая точка программы" - моя "самодеятельность", и я "ввожу его в эксплуатацию" с целью наиболее комфортного восприятия информации.

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

Необходимо также отметить то, что при использовании одной команды ветвления, возможных сценариев может быть только 2, а при применении нескольких - количество возможных сценариев будет кратным двум.

Флаги переноса - заёма С (0-й бит регистра STATUS) и десятичного переноса - заёма DC (1-й бит) показывают, было ли переполнение байта или младшего полубайта байта (извиняюсь за тавтологию) соответственно.

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

Например, наибольшее число в пределах байта (8 разрядов) 255.

Если, например, складываются числа 200 и 100, то происходит переполнение, и флаг C устанавливается в 1 (поднимается).

Кроме того, при выполнении команд сдвига, флаг C загружается старшим или младшим битом байта сдвигаемого регистра (в зависимости от направления сдвига).

На флаги переполнения сторожевого таймера и включения питания пока можете не обращать внимания.

Они используются достаточно редко.

То же самое относится и к флагам EEIF и WRERR регистра EECON1 (см. распечатку). Флаги TOIF, INTF, RBIF регистра INTCON работают по единому принципу.

Отличия только в источниках прерываний.

Перед работой с ними, их необходимо сбросить программно. "Разборки" с этим сбросом будут позднее.

С содержимым регистров специального назначения, в основном, разобрались. Пошли дальше.

Метки

Само название уже отражает смысл этого понятия.

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

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

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

Название подпрограммы указывает на первую команду подпрограммы, а метка помечает команду, отличную от первой команды подпрограммы.

Вот и все различие.

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

Аппаратный стек

Является всё тем же оперативным запоминающим устройством "объемом" в 8 ячеек по 13 битов каждая.

Он поддерживает команды переходов/возвратов по условию (условные переходы), а также и переходы/возвраты, связанные с прерываниями.

23


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

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

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

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

Вывод: главная функция стека - хранение адреса возврата в течение всего времени исполнения программной процедуры.

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

ВMPLAB, это выглядит так:

Если, по ходу исполнения программы, был осуществлен условный переход, то в верхнюю строку (так называемая вершина стека), из счетчика команд PC, копируется 13-ти разрядное слово (8 бит PCL и 5 бит PCH) адреса следующей, после команды условного перехода, команды (для дальнейшего возврата программы по этому адресу).

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

Таким образом, стек можно заполнить 8-ю адресами возвратов, после чего наступает его переполнение, чего допускать нельзя (указателя переполнения стека нет), так как будет "Гитлер капут".

То есть, в стек может быть заложено не более 8-ми адресов возврата, и программист должен за этим следить при составлении программы.

Даже в достаточно сложных программах, работа стека на грани переполнения - редкое явление и его "емкости" хватает с избытком.

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

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

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

Спешу успокоить начинающих: на первых порах достаточно только одной вершины стека, то есть, первой (верхней) его строки.

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

24


Если Вы это освоите, то со временем, Вы естественным образом перейдете к более сложным манипуляциям с условными переходами.

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

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

Подробнее о работе со стеком - в следующих разделах.

Итак: микроконтроллер это набор многофункциональных устройств.

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

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

И в том, и в другом случае именно программа (программист) определяет все то, что будет происходить с этими элементами ПИК-конструктора, и поэтому далее речь пойдет о "начинке" программы, то есть о командах.

Примечание: то, что Вы прочитали, есть основа, с еще не достаточно четко "прорисованными" деталями.

Одноразово выдавать Вам весь "массив", связанной с этим "ПИК-конструктором", информации, было бы абсолютно неправильным и опрометчивым решением.

"Въезжать" в этот "массив" нужно постепенно, с соблюдением "техники безопасности" и не делая "резких движений".

Это и есть дальнейшая стратегия "въезда".

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

25

3. Система команд PIC16F84A

Вашему вниманию предлагается описание команд ассемблера для PIC контроллеров.

Таблица команд ассемблера для ПИКов находится в "Приложении №10".

Команды разделены на 3 группы:

-байт-ориентированные команды, то есть команды, производящие действия с байтами,

-бит-ориентированные команды, то есть команды, производящие действия с битами,

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

Из списка команд управления можно смело вычеркнуть последние 2 команды, так как они могут быть использованы только для поддержки совместимости PIC16F84A с более "древним" семейством микроконтроллеров PIC16C5x, а для совместимости PIC16F84A с последующими, выпускаемыми микроконтроллерами, эти команды разработчики вообще не рекомендуют использовать.

Итого: осталось 35 команд. Разве это много?

По сравнению, например, с изучением иностранного языка, это вообще мизер. Давайте с ними разбираться.

Сначала - информация по таблице команд.

В первой колонке располагается название команды, а в рамке под этим названием - краткое содержание команды.

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

Латинские буквы в конце команды обозначают:

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

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

d - указатель места сохранения результата при операциях с байтами. Если d = 0, то результат исполнения команды сохраняется в регистре W (в аккумуляторе).

Если d = 1, то результат исполнения команды сохраняется в регистре f, то есть, в том же самом регистре, с содержимым которого производится действие.

b - номер бита в регистре, с которым производится действие (для бит-ориентированных команд).

k - константа, то есть некое число в пределах байта, которое задается программистом.

Во второй колонке, находится более подробное описание действия, которое производит команда.

Втретьей колонке, даны примеры выполнения команд.

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

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

Комбинация числа 1 и двойки в скобках, означает, что по одному сценарию выполнения команды, она выполняется за один машинный цикл, а по другому - за два.

Напоминаю, что подобного рода команды (команды ветвления) имеют только 2 сценария исполнения команды.

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

Сразу обратите внимание на следующую особенность, знание которой поможет Вам при запоминании команд: значительная часть команд состоит из 5-ти букв, причем корень слова

26