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

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

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

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

Добавлен: 16.06.2025

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

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

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

(адреса регистров LED0 ... LED7).

Сразу же после записи, в регистр W, любого из этих чисел, оно копируется, из регистра W, в

регистр FSR (movwf FSR).

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

Для того чтобы скопировать (считать) содержимое регистра с адресом, указанным в регистре FSR, в регистр W (для дальнейшего использования), нужно выполнить команду movf Indf,W.

То есть, обращение к регистру Indf соответствует обращению к содержимому того

регистра, адрес которого записан в регистре FSR.

Для удобства, можно коварно перефразировать так: команда movf Indf,W обращается не к "регистру" Indf ("чистая подстава", так как он физически не реализован. Просто "кнопка, которая включает действие"), а к содержимому того регистра, адрес которого "лежит" (на момент обращения к Indf) в регистре FSR.

Регистр специального назначения Indf, также, как и регистр специального назначения FSR, задействуется только при косвенной адресации.

Оба они находятся в 0-м банке и отображаются в 1-м банке, так что работать с ними можно, "не забивая себе голову" выборами банков.

Итак, в результате работы первых 4-х команд ПП CYCLE, на каждом "витке" малого кольца индикации, в регистр W, будет по очереди, последовательно копироваться содержимое регистров LED0 ... LED7.

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

Это мы уже проходили.

Вспомните ПП TABLE, в которой осуществляется перекодировка двоично-десятичного кода в код 7-сегментных индикаторов ("программа" addwfpc.asm).

Врегистре W, находится то, что нужно перекодировать. Останавливаться на этом я не буду (см. программу addwfpc.asm).

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

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

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

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

Посмотрите в текст программы Fsr.asm.

После команды call TABLE, Вы видите "линейный" участок из 4 последовательно исполняемых групп команд.

Детально, их состав и работа будут рассмотрены на 2-м этапе "разборок", а пока, буквально пару слов о них.

Зачем нужна группа команд установки запятой, понятно уже из ее названия.

Группа команд формирования адресного кода управления дешифратором формирует этот самый адресный код.

Ранее, я "привязал" дешифратор к м/схеме 555ИД7, имеющей 3 адресных входа и 8 выходов (да будет так).

Взависимости от адресного кода, на каком-либо одном из 8-ми выходов дешифратора устанавливается 0 (на остальных 1).

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

Возникает вопрос: "Mожно ли обойтись без внешнего дешифратора, передав его функции микроконтроллеру?

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

ВPIC16F84A, третьего порта нет и поэтому применение внешнего дешифратора необходимо. Для микроконтроллеров, с количеством портов не менее 3-х, дешифратор можно организовать программно.

231


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

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

Вывод символа на индикацию будет осуществлен в тот 7-сегментный индикатор, на общих катодах которого дешифратор установил 0.

Функция группы команд задержки, определяющей время нахождения одного 7-сегментного индикатора в активном состоянии, ясна из названия этой группы команд.

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

Для того чтобы, на этом "витке", обеспечить:

- обработку байта, хранящегося в следующем (по порядку старшинства) LEDе,

- изменение адресного кода дешифратора, приводящее к активации следующего (по порядку старшинства) знакоместа,

необходимо увеличить, на 1, содержимое "рулевого" регистра Index, которое и происходит после исполнения команды incf Index,F.

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

Или по-другому: не установилась ли, в регистре Index, восьмерка?

Для этого, организуется проверочная группа команд, с задействованием флага нулевого результата Z.

Это мы уже проходили.

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

Врегистр W, записывается константа .08.

Флаг Z сбрасывается в 0 (а можно и не сбрасывать, так как это флаг 1-й группы).

Из содержимого регистра Index, вычитается содержимое регистра W (то есть, число .08), и после этого, проверяется состояние флага нулевого результата Z.

Результат этой операции будет нулевым только в том случае, если в регистре Index будет "лежать" число .08.

Если число, "лежащее" в регистре Index, отлично от восьмерки, то после проверки состояния флага Z, произойдет безусловный переход в ПП CYCLE, то есть, на новый "виток" малого кольца индикации, после чего, описанная выше "цепочка событий" повторится, но только будет обрабатываться содержимое следующего, по старшинству, LEDа.

Если число, "лежащее" в регистре Index, будет равно 8-ми, то после проверки состояния флага Z, команда goto CYCLE будет проигнорирована (вместо нее, исполняется "виртуальный" nop), и будет отработан сценарий типа "программа исполняется далее". Если это так, то выполняется выравнивающий nop.

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

И в самом деле, переход рабочей точки программы на 1-ю команду одного сценария, происходит через 2 м.ц. (команда goto исполняется за 2 м.ц.), а ее переход на 1-ю команду другого сценария, через 1 м.ц. (команда "виртуального" NOPа исполняется за 1 м.ц.). Если речь идет о "плюс-минус двух лаптях", то выравнивающий nop не нужен, но если ПП

динамической индикации участвует в формировании калиброванных интервалов времени, то выравнивание необходимо.

Это влияет на стабильность результатов измерений.

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

А это уже серьёзно, так как речь идет о качестве измерительных устройств.

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

232


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

Только в этом случае, можно сформировать и калиброванный, и высокостабильный интервал времени.

Итак, в случае исполнения сценария "программа исполняется далее", после выравнивающего NOPа, исполняется команда clrf Index.

То есть, байт "рулевого" регистра Index сбрасывается в 0, что есть подготовка к переходу на следующий цикл большого кольца индикации.

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

Count (decfsz Count,F).

Команда ветвления decfsz, кроме декремента, еще и осуществляет проверку типа "результат декремента равен или не равен нулю?"

Если результат декремента содержимого регистра Count не равен нулю, то исполнится команда goto CYCLE, и рабочая точка программы "улетит" на начало следующего цикла. После отработки следующего цикла большого кольца индикации, произойдет следующий декремент содержимого регистра Count и т.д.

До тех пор, пока в регистре Count не "появится" 0.

После этого, команда goto CYCLE будет проигнорирована (вместо нее, "виртуальный" NOP), и далее, будет исполнена команда выравнивающего NOPа.

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

Выход на следующий цикл большого кольца индикации происходит сразу же после смены содержимого регистра Index с .07 на .08.

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

После команды инкремента содержимого регистра Index, и до команды сброса его содержимого в 0 (в том случае, если результат инкремента равен .08), отрабатывается 6 м.ц. Таким образом, смена восьмерки на 0 произойдет через 6 м.ц. (в начале 7-го), то есть, быстро.

Второй этап

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

Вашему вниманию предоставляется ASM-файл универсальной "заготовки" ПП 8-разрядной динамической индикации, с использованием внешнего дешифратора.

Файл программы называется Dinam.asm (находится в папке "Тексты программ").

Она выглядит так:

;********************************************************************************

;ГРУППА ПОДПРОГРАММ 8-РАЗРЯДНОЙ ДИНАМИЧЕСКОЙ ИНДИКАЦИИ С

;

ИСПОЛЬЗОВАНИЕМ ВНЕШНЕГО ДЕШИФРАТОРА.

;********************************************************************************

;

"ШАПКА ПРОГРАММЫ"

;******************************************************************************** ; Dinam.asm Универсальная группа подпрограмм 8-разрядной динамической индикации

;.............................................................

;================================================================================

; Определение положения регистров специального назначения.

233


;================================================================================

Indf

equ

00h

; Регистр INDF.

PC

equ

02h

; Регистр счетчика команд.

Status

equ

03h

; Регистр Status.

FSR

equ

04h

; Регистр FSR.

PortA

equ

05h

; Регистр PortA.

PortB

equ

06h

; Регистр PortB.

;.............................................................

;.............................................................

;================================================================================

; Определение названия и положения регистров общего назначения.

;================================================================================

LED0

equ

10h

; Регистр 1-го 7-сегментного индикатора.

LED1

equ

11h

; -------

2-го -------------------------

LED2

equ

12h

; -------

3-го -------------------------

LED3

equ

13h

; -------

4-го -------------------------

LED4

equ

14h

; -------

5-го -------------------------

LED5

equ

15h

; -------

6-го -------------------------

LED6

equ

16h

; -------

7-го -------------------------

LED7

equ

17h

; -------

8-го -------------------------

Index

equ

0Ch

; Регистр счетчика количества

; малых колец индикации.

Count

equ

0Dh

; Регистр счетчика количества

; больших колец индикации.

Temp

equ

0Fh

; Регистр временного хранения данных.

;.............................................................

;.............................................................

;================================================================================

; Определение места размещения результатов операций.

;================================================================================

W

equ

0

;

Результат

направить

в

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

F

equ

1

;

Результат

направить

в

регистр.

;================================================================================

; Присваивание битам названий.

;================================================================================

Z equ 2 ; Флаг нулевого результата.

;.............................................................

;.............................................................

;================================================================================

; Присваивание константам названий.

;================================================================================

Const1

equ

Y1

; Y1

-

значение

времязадающей

константы

; "грубо"

(до

.255). Задается

программистом.

Const2

equ

Y2

;

Y2

-

значение

времязадающей

константы

;

"точно"

(до

.255). Задается

программистом.

;================================================================================

org

0

;

Начать выполнение программы

goto

START

;

с подпрограммы START.

;********************************************************************************

;********************************************************************************

; РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ

;********************************************************************************

; Подготовительные операции.

;--------------------------------------------------------------------------------

;START ......................................

; ......................................

;--------------------------------------------------------------------------------

; Группа подпрограмм преобразования двоичных чисел в двоично-десятичные.

;--------------------------------------------------------------------------------

;Bin2_10 ......................................

; ......................................

;....... ......................................

; ......................................

;....... ......................................

; ......................................

234