Файл: Самоучитель по программированию 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