Оглавление
Общие положения
Регистр спецназначения FSR
Регистр спецназначения INDF
Особенности применения косвенной адресации в приложении к
“клоноподобным” процедурам
Особенности применения косвенной адресации в приложении к предустановке,
в ячейках заданного “сектора” оперпамяти, заданных числовых значений
Примеры числовых предустановок массивов оперпамяти 2-банковых ПИКов
Примеры числовых предустановок массивов оперпамяти 4-банковых ПИКов
Выбор банков при прямой адресации
Выбор банков при косвенной адресации
Работа в “связке”
Применение косвенной адресации при работе с таблицами данных
Общие положения
Копирование массива данных, из одного “сектора” оперпамяти, в другой
(“чтение-модификация-запись”), с использованием косвенной адресации
Копирование массива данных, из заданного “сектора” EEPROM-памяти данных,
в заданный “сектор” оперпамяти (“чтение-модификация-запись”), с
использованием косвенной адресации
Копирование массива данных, из заданного “сектора” оперпамяти, в заданный
“сектор” EEPROM-памяти данных (“чтение-модификация-запись”),
с использованием косвенной адресации
Общие положения
2
Иными словами, обращение к регистру INDF “запускает в работу” относительно
несложный, аппаратный модуль косвенной адресации, который, если так можно
выразиться, “всё сделает в лучшем виде”.
Голос из-за кулис: “Ты что пропагандируешь, тудыть твою растудыть! Коню понятно,
что одна команда симпатичнее трёх (см. выше)”.
Ответ: в приложении к “вышележащему” сравнению, вне сомнений, симпатичнее, но как
быть с цитатой из “Справочника по среднему семейству…”: Режим косвенной
адресации может быть полезен при обращении к таблицам данных (а я бы ещё
сказал, что и в других случаях)?
“Это жу-жу не спроста” (сказал Винни-Пух). Где-то “прячется приятность типа мёд”.
Так оно и есть: в некоторых, специфических случаях, суть перехода, от прямой
адресации, к косвенной, сводится к оптимизации типа обмен уменьшения количества
команд исходной процедуры, на увеличение времени её отработки.
Вопрос: “По какой причине возникает относительная, временнАя затяжка”?
Ответ: команды, которые обеспечивают осуществление такой разновидности
оптимизации, исполняются не за ноль секунд, что, с учётом цикличности исполнения
“заоптимизированной”, программной процедуры (имеются в виду её внутренние циклы), приводит к
увеличению времени её отработки (по сравнению со временем отработки исходной, “незаоптимизированной”
процедуры) на величину суммарного времени отработки этих команд.
;....................................
LOOP16
;....................................
;---------------------------------------
; Основные операции 2/10 преобразования.
;---------------------------------------
; Работа с LED0.
;----------------
adjDEC movlw 3 ;
addwf LED0,W ;
movwf Mem ;
btfsc Mem,3 ; Эта группа команд идентична (“клоноподобна”)
movwf LED0 ; остальным 3-м группам команд, но не полностью
movlw 30 ; -> работа с регистром LED0.
addwf LED0,W ;
movwf Mem ;
btfsc Mem,7 ;
movwf LED0 ;
;----------------
; Работа с LED1.
;----------------
movlw 3 ;
addwf LED1,W ;
movwf Mem ;
btfsc Mem,3 ; Эта группа команд идентична (“клоноподобна”)
movwf LED1 ; остальным 3-м группам команд, но не полностью
movlw 30 ; -> работа с регистром LED1.
addwf LED1,W ;
movwf Mem ;
btfsc Mem,7 ;
movwf LED1 ;
;----------------
; Работа с LED2.
;----------------
movlw 3 ;
addwf LED2,W ;
movwf Mem ;
btfsc Mem,3 ; Эта группа команд идентична (“клоноподобна”)
movwf LED2 ; остальным 3-м группам команд, но не полностью
movlw 30 ; -> работа с регистром LED2.
addwf LED2,W ;
3
movwf Mem ;
btfsc Mem,7 ;
movwf LED2 ;
;----------------
; Работа с LED3.
;----------------
movlw 3 ;
addwf LED3,W ;
movwf Mem ;
btfsc Mem,3 ; Эта группа команд идентична (“клоноподобна”)
movwf LED3 ; остальным 3-м группам команд, но не полностью
movlw 30 ; -> работа с регистром LED3.
addwf LED3,W ;
movwf Mem ;
btfsc Mem,7 ;
movwf LED3 ;
;....................................
LOOP16
;....................................
;----------------------------------------------------
; Подготовка к косвенной адресации и вызов ПП adjBCD.
;----------------------------------------------------
adjDEC movlw LED0 ; Запись в регистр FSR, через регистр W, операдреса
movwf FSR ; регистра LED0, с дальнейшим переходом в ПП adjBCD.
call adjBCD ; После возврата по стеку, далее.
movlw LED1 ;
movwf FSR ; То же самое для регистра LED1.
call adjBCD ;
movlw LED2 ;
movwf FSR ; То же самое для регистра LED2.
call adjBCD ;
movlw LED3 ;
movwf FSR ; То же самое для регистра LED3.
call adjBCD ;
4
Выигрыш (по количеству команд) очевиден, но эта процедура будет отрабатываться немного
помедленнее (относительно исходной), так как записи операдресов, в регистр FSR, а также и
переходы/возвраты требуют дополнительного времени.
В подобного рода командной оптимизации, ничего выдающегося нет (несколько “клонов”
сводятся к одной вызываемой ПП. Обычная методика. В частности, см. подраздел 2 статьи “Обмена…” 4_72, и в моих
книгах/статьях об этом неоднократно упомянуто), за исключением того, что в вызываемой ПП
происходит обращение (обращения) к регистру INDF.
Обратите внимание на группу команд с названием Подготовка к косвенной
адресации и вызов ПП adjBCD.
Аналогичные группы команд, лично я, называю “администраторскими группами команд”.
И в самом деле, некое “администрирование” налицо:
Это есть основа того, что некоторые люди называют “суперлупом”, но лично мне, это
слово не нравится (возникает такая ассоциация à глаза на выкате, вплоть до вываливания из глазниц).
“Администраторская группа команд” может состоять:
1. Из последовательности команд условных переходов, не “укомплектованных”
командами подготовительных операций.
2. Из последовательности команд условных переходов, “укомплектованных”
командами подготовительных операций.
3. Из “гибрида” пункта 1 и пункта 2.
В рассматриваемом случае, речь идёт о пункте 2, который хорош тем, что порядок
“прописки” (в “шапке” программы) LED3 … LED0 может быть произвольным (можно “тасовать как
колоду карт”), но в обмен на “небольшую клоноподобность”, которая присутствует в
“администраторской группе команд”.
Соответствующие ПП 2/10 преобразований, “лежащие” в статье Подпрограммы 2_10
преобразований, составлены так, что порядок “прописки” (в “шапке” программы) LEDов,
которые задействованы в “администраторской группе команд”, может быть
произвольным.
Это гарантирует отсутствие оргнедоразумений, связанных с порядком “прописки” LEDов.
Поэтому я и составил программы именно так, но, тем не менее, “прописал” LEDы не
в произвольном порядке, а в порядке последовательного возрастания их номеров.
Почему? Сейчас поймёте.
Предлагаю Вашему вниманию вариант реализации “вышележащего” фрагмента
программы №10:
;***************************************************************************************************
; “Шапка” программы.
;***************************************************************************************************
;....................................
;----------------------------------------
; "Прописка" регистров общего назначения.
;----------------------------------------
cblock 20h ; Назначение адреса первого регистра блока
; (можно назначить и другой начальный адрес).
LED0 ;Регистр хранения результатов преобразований 1-го 2_10-го разряда
LED1 ; ------- 2-го -------
LED2 ; ------- 3-го -------
LED3 ; ------- 4-го -------
;....................................
endc ; Конец блока.
;------------------------------------
org <то, с чего нужно начать исполнение программы> ;
;***************************************************************************************************
5
;===================================================================================================
;....................................
LOOP16
;....................................
;----------------------------------------------------
; Подготовка к косвенной адресации и вызов ПП adjBCD.
;----------------------------------------------------
adjDEC movlw LED0 ; Запись в регистр FSR, через регистр W, операдреса
movwf FSR ; регистра LED0, с дальнейшим переходом в ПП adjBCD.
call adjBCD ; После возврата по стеку, далее.
;------------------------------------
;;; movlw LED1 ;
;;; movwf FSR ;
incf FSR,F ; То же самое для
call adjBCD ; регистра LED1.
;------------------------------------
;;; movlw LED2 ;
;;; movwf FSR ;
incf FSR,F ; То же самое для
call adjBCD ; регистра LED2.
;------------------------------------
;;; movlw LED3 ;
;;; movwf FSR ;
incf FSR,F ; То же самое для
call adjBCD ; регистра LED3.
;------------------------------------
goto LOOP16 ; Переход на следующий цикл.
;---------------------------------------
; Основные операции 2/10 преобразования.
;---------------------------------------
adjBCD movlw 3 ;
addwf INDF,W ;
movwf Mem ;
btfsc Mem,3 ;
movwf INDF ; Вызываемая ПП с элементами
movlw 30 ; косвенной адресации.
addwf INDF,W ;
movwf Mem ;
btfsc Mem,7 ;
movwf INDF ;
Примечание: если LEDы “шапкопрописаны” в порядке последовательного убывания их номеров, то нужно использовать
не инкременты, а декременты (в начале “админа” à обращение к адресу “нижней” оперячейки).
Примечание: если количество проходов = 32 и “админ ужался” на 3 команды (как в рассматриваемом случае), то
скоростной выигрыш составляет 2427 – 2334 = 93 м.ц. (судя по результатам замеров)
То есть, в общем виде, скоростной выигрыш (в машинных циклах) = (Nпроходов – 1) х N”убитых” команд.
В данном случае, скоростной выигрыш = (32 – 1) х 3 = 93 м.ц.
6
Особенности применения косвенной адресации в приложении к предустановке, в
ячейках заданного “сектора” оперпамяти, заданных числовых значений
8
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 0-го банка с адресом 4Fh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 4Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
9
В том смысле, что в ней можно “симуляторно подобрать” (это не сложно) нужные (условно)
числовые значения констант, которые используются в “нижележащей”, программной
процедуре очистки вожделеемого “сектора” оперпамяти (выделено чёрным цветом).
Физически нереализованную область оперпамяти (на картинках, она обозначена пунктирами)
предустанавливать не имеет смысла, так как это достаточно бестолковое занятие.
А это то же самое (по смыслу. В данном случае, для PIC12F629), только в приложении к другим
типам 2-банковых ПИКов (у них область оперпамяти “сконструирована” несколько иначе, чем в PIC16F84 / 84A.
См. соответствующие карты оперпамяти):
10
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 0-го банка с адресом 5Fh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 5Fh,F ; - 1 из счётчика проходов.
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
Для PIC12F683
Работа с массивом регистров общего назначения 0-го банка.
В 1-м банке отображается только группа регистров общего назначения 0-го
банка с адресами 70h … 7Fh.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданного “сектора” оперпамяти, заданных числовых значений.
; Сначала, в декрементном порядке, производится предустановка чисел от 5Fh (в ячейке с адресом 20h),
; до 00h (в ячейке с адресом 7Fh) а затем производится очистка этих предустановок.
;***************************************************************************************************
LIST p=12f683 ; Используется PIC12F683.
#include <p12f683.inc>; Подключение INC-файла PIC12F683.
__CONFIG 0FE1H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения 0-го банка, от ячейки с адресом 20h и до ячейки с
; адресом 7Fh, чисел, которые отличны от 0 (за исключением оперячейки с адресом 7Fh. В ней 0
; выставляется по факту окончания потоковой предустановки).
; Так как, в данном случае, содержимое группы регистров общего назначения, с адресами 70h...7Fh,
; отображается в 1-м банке, то в соответствующей группе регистров общего назначения 1-го банка
; (адреса 0Fh...FFh) будет такая же предустановка.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START movlw 20h ; Потоковая запись чисел начинается от оперячейки
11
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 7Fh) записывается
movwf 7Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 7Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №1
; процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 0-го банка с адресом 7Fh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
12
В данном случае, в 1-м банке отображается только часть массива регистров общего
назначения 0-го банка (см. “подмассив” с адресами 70h … 7Fh и его “зеркальное отображение” в оперячейках с
адресами F0h … FFh).
Если нужно предустановить только эти отображаемые “подмассивы” (2 штуки), то
необходимо:
начальный адрес (заменить 20h на 70h),
количество проходов (заменить .95 на .15),
конечный адрес заменять не нужно (7Fh).
В этом случае, “картина” такая:
Для PIC12F683
Предустановка всех регистров общего назначения.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений, причём,
; в приложении к обоим банкам.
;***************************************************************************************************
LIST p=12f683 ; Используется PIC12F683.
#include <p12f683.inc>; Подключение INC-файла PIC12F683.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 0FE1H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 20h и до ячейки с адресом 7Fh,
; чисел, которые отличны от 0 (включая и отображаемую область оперпамяти).
; Так как, в данном случае, области оперпамяти с адресами 70h...7Fh (0-й банк) и 0Fh...FFh (1-й банк)
; являются отображаемыми, то они предустанавливаются одинаково (в оперячееках с адресами 7Fh и FFh,
; ноли выставляется по факту окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
movlw 20h ; Потоковая запись чисел начинается от оперячейки
13
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 7Fh) записывается
movwf 7Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 7Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом A0h и до ячейки с адресом BFh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом BFh. В ней 0 выставляется по факту
; окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое этой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 0A0h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом A0h (см. соответствующую карту оперпамяти).
movlw .31 ; (.31=1Fh) В счётчик проходов (адрес ячейки BFh) записывается
movwf 0BFh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 movf 0BFh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_1 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0BFh,F ; - 1 из счётчика проходов.
goto SNOVA_1 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом A0h и до ячейки с адресом BFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_1 movlw 0A0h ; Потоковая запись чисел начинается <- ТОЧКА ОСТАНОВКИ №1
; от оперячейки с адресом A0h
movwf FSR ; (см. соответствующую карту оперпамяти).
movlw .31 ; В счётчик проходов записывается количество оперячеек,
movwf 0BFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 1-го банка с адресом BFh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_2 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_2 ; Если все, то переход на начало
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
14
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0BFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_2 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_2 movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;-----------------------------------------------------------------------------------------------
; Примечание: в данном случае, счётчик проходов “дислоцируется” в 1-м банке, но он отображается
; и в 0-м банке. По окончании процедуры потоковой предустановки нолей, в ней, по причине обнуления
; счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC-----------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_3 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду goto <туда, куда
; нужно>, и в том случае, если в дальнейшем предполагается работа в 0-м банке, то 1-й командой
; процедуры типа “туда, куда нужно”, должна быть команда перехода в 0-й банк.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_3 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
Для того чтобы понять, “что творится в этой программе”, нужно кое-что объяснить.
За выбор 0-го или 1-го банка “отвечает” бит №7 байта адреса, “лежащего” в регистре
FSR (если бит №7 = 0, то это 0-й банк, а если он = 1, то это 1-й банк).
Из этого следует то, что посредством записи нужного (условно) операдреса, в регистр
FSR, “в границах” 0-го и 1-го банков (о 2-м и 3-м банках расскажу позднее), можно адресно
выбрать любую из их оперячеек (банки выбирать не нужно).
15
Просто, в той или иной форме (в данном случае, не в виде обращения к названию регистра, а в виде
обращения к числовому значению его адреса), задаётся адрес оперячейки, и все дела (в этом случае,
всё просто как звук “му” и никакой “банковской, головной боли”).
А вот в приложении к счётчику проходов, немного “погеморройнее”.
Постараюсь объяснить.
“Цитата” из программы:
movlw .31 ; (.31=1Fh) В счётчик проходов (адрес ячейки BFh) записывается
movwf 0BFh ; количество оперячеек, содержимое которых подлежит предустановке
В данном случае, это прямой намёк на оперячейку счётчика проходов с адресом BFh,
“лежащую” в 1-м банке, а также и на конфуз, связанный с обращением к ней из 0-го
банка.
Как видите, в этом случае, регистр FSR не задействуется (прямая адресация).
Если “до того” был установлен 0-й банк, то “после того”, счётчик проходов будет
“дислоцироваться” не в оперячейке с адресом BFh (это нужно. 1-й банк), а в оперячейке с
адресом 3Fh (“бяка”. 0-й банк).
То есть, число .31 отобразится не там, где нужно (со всеми вытекающими).
Это так называемое (мной) “зеркальное отображение” (в данном случае, “с паразитной
сущностью”), которое в упор не соответствует задумке и является “бяковым” (неприятности
гарантированы).
Выход из этого положения довольно-таки прост: ПП START нужно начать так (что и
сделано):
START bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
Применение команды bsf STATUS,RP0 приводит к тому, что счётчик проходов,
предназначенный для предустановок оперячеек 0-го банка, если так можно выразиться,
“зеркально передислоцируется” в отображаемую область 1-го банка (адрес FFh).
По этой “отображаемой” причине (оперячейки с адресами 7Fh и FFh - “клоны”), ему, образно
выражаясь, “по фигу, где лежать”, то ли в 0-м банке, то ли в 1-м банке.
То есть, в приложении к работе в 0-м банке, эта “клоноподобность” не содержит в
себе никакой “бякосоставляющей”, и одновременно, в приложении к работе с 1-м
банком, команда bsf STATUS,RP0 “загоняет” счётчик проходов, предназначенный для
предустановки оперячеек 1-го банка, в его “штатное, банковоадресное стойло”
(1-й банк, оперячейка с адресом BFh. Это неотображаемая область оперпамяти).
Вот и вся “премудрость” (если желаете “въехать” в суть сказанного, то заблокируйте команду
bsf STATUS,RP0 , “погоняйте” программу в симуляторе, обратив внимание на оперячейки с адресами 3Fh и BFh).
Вывод №1
Если речь идёт о косвенной адресации, то в “границах” 0-го и
1-го банков (а также и в “границах” 2-го и 3-го банков. О специфике переключений между этими группами
банков расскажу ниже), она является абсолютной. В том смысле, что банки
(те, которые работают “в паре/связке”) программно “переключать” не обязательно.
Вывод №2
Содержимое отображаемых областей оперпамяти “клоноподобно”.
То есть, c этим содержимым можно работать в любом из тех банков,
в которых эта “клоноподобность” существует (без программного “переключения” банков).
Вывод №3
Перед обращением к регистрам общего назначения, которые “лежат” в
неотображаемых областях оперпамяти, нужно озаботиться программным
выбором соответствующих банков.
Примечание: см. описание процесса конструирования модуля для блоков питания (“Практикум…”). В ходе этой
поэтапной работы, суть сказанного “расписана” (в приложении к PIC16F873A. В нём, 0-й банк отображается на 2-й
банк, а 1-й банк отображается на 3-й банк) достаточно подробно.
16
Примеры числовых предустановок массивов оперпамяти 4-банковых ПИКов
Так как 4 банка это не 2 банка (у 4-банковых ПИКов есть специфика), то настало время более
детально разобраться с “4-банковскими делами”:
Наличие двух битов выбора банка (биты RP1, RP0 регистра STATUS) обусловлено тем, что
работа с 4-мя банками (128 х 4 = 512) требует наличия 9-ти битов, а в коде команды,
которая обращается к содержимому оперячейки, имеется только 7 битов (можно работать
только в “границах” одного 128-“ячеечного банка”. См. “вышележащую” картинку) , что недостаточно для того,
чтобы работать в “границах” 4-х банков.
Вот разработчики и придумали/добавили биты RP1 и RP0 (2 бита à 4 комбинации), поместив
их в регистр STATUS.
То есть,
с помощью битов RP1 и RP0 (работа “в связке”) выбирается один из 4-х банков,
а адресный выбор одной из оперячеек (работа внутри выбранного банка) определяется
кодом команды, которая обращается к её содержимому.
В части касающейся первого, можно сказать и так: состояние бита RP1 определяет
пару банков, а состояние бита RP0 определяет конкретный банк.
17
Выбор банков при косвенной адресации
Работа в “связке”
“Влёт” в этот фрагмент происходит из пары банков 2/3 (bsf STATUS,IRP), а далее применяется
косвенная адресация (наряду с прямой) и необходимо работать в паре банков 0/1.
Значит нужно исполнить команду:
bcf STATUS,IRP ; Переход на работу в 0-м и 1-м банках.
“Косвенную адресацию банково ублажили”.
Теперь “банково ублажаем прямую адресацию”.
“Влёт” в этот фрагмент происходит из 2-го банка (bcf STATUS,RP0 и bsf STATUS,RP1), а далее
применяется прямая адресация (наряду с косвенной) и необходимо работать в 1-м банке. Значит
нужно исполнить команды:
bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
bcf STATUS,RP1 ; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
Если заблокировать любую из этих команд то программа будет работать не так, как
задумано (можете проверить в симуляторе). Вот и весь сказ. Дружески советую понять его суть
(это выгодно во всех отношениях. В частности, во избежание “вождения носом по батарее”) .
Ну а теперь поближе к другой конкретике.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 0-го банка с адресом 7Fh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
19
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду goto <туда, куда
; нужно>.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
20
В данном случае, в 1, 2 и 3 банках отображается только часть массива регистров
общего назначения 0-го банка (см. “подмассив” с адресами 70h … 7Fh и его “зеркальные отображения” в
оперячейках с адресами F0h … FFh, 170h … 17Fh, 1F0h … 1FFh).
Если нужно предустановить только эти отображаемые “подмассивы” (4 штуки), то
необходимо:
начальный адрес (заменить 20h на 70h),
количество проходов (заменить .95 на .15),
конечный адрес заменять не нужно (7Fh).
В этом случае, “картина” такая:
21
Для PIC16F628 / 628A
Предустановка всех регистров общего назначения.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений, причём,
; в приложении ко всем банкам.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 20h и до ячейки с адресом 7Fh,
; чисел, которые отличны от 0 (включая и отображаемую область оперпамяти).
; Так как, в данном случае, области оперпамяти с адресами 70h...7Fh (0-й банк), F0h...FFh, (1-й
; банк), 170h...17Fh (2-й банк), 1F0h...1FFh (3-й банк) являются отображаемыми, то они
; предустанавливаются одинаково (в оперячееках с адресами 7Fh, FFh, 17Fh, 1FFh ноли выставляется
; по факту окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START bcf STATUS,IRP ; Переход на работу в 0-м и 1-м банках.
; Если этого не сделать, то после осуществления перехода
; goto START (см. ниже), дальнейшая работа будет происходить
; не в “связке” 0-го и 1-го банков, а в “связке” 2-го и 3-го
; банков (“бяка”).
bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
bcf STATUS,RP1 ; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 7Fh) записывается
movwf 7Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 7Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом A0h и до ячейки с адресом EFh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом EFh. В ней 0 выставляется по факту
; окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое отображаемой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 0A0h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом A0h (см. соответствующую карту оперпамяти).
movlw .79 ; (.79=4Fh) В счётчик проходов (адрес ячейки EFh) записывается
movwf 0EFh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 movf 0EFh,W ; Так как в случае ненулевого результата декремента счётчика
22
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_1 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0EFh,F ; - 1 из счётчика проходов.
goto SNOVA_1 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 120h и до ячейки с адресом 14Fh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом 14Fh. В ней 0 выставляется по
; факту окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое отображаемой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_1 bsf STATUS,IRP ; Так как далее предустанавливается содержимое регистров общего
; назначения 2-го банка, то переход на работу во 2-м и 3-м банках
bcf STATUS,RP0 ; После этого, выбор конкретного банка этой “связки”,
bsf STATUS,RP1 ; в данном случае, 2-го банка.
23
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 1-го банка с адресом EFh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_3 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_3 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0EFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_3 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_3 movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;-----------------------------------------------------------------------------------------------
; Примечание: в данном случае, счётчик проходов “дислоцируется” в 1-м банке, но он отображается
; и в 0-м банке. По окончании процедуры потоковой предустановки нолей, в ней, по причине обнуления
; счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_4 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_4 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_4 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 120h и до ячейки с адресом 14Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_4 bsf STATUS,IRP ; Так как далее предустанавливается содержимое регистров общего
; назначения 2-го банка, то переход на работу во 2-м и 3-м банках
bcf STATUS,RP0 ; После этого, выбор конкретного банка этой “связки”,
bsf STATUS,RP1 ; в данном случае, 2-го банка.
24
; С учётом этого, а также того, что любой из банков расчитан на “дислокацию” 128-ми регистров,
; возникает некая (можно назвать и по-другому) “парная клоноподобность” адресации. В данном случае,
; в приложении к 0-му и 2-му банкам (что-то типа “адресной зеркалки”).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_5 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду goto <туда, куда
; нужно>, и в том случае, если в дальнейшем предполагается работа в 0-м банке, процедура типа “туда,
; куда нужно”, должна начаться с команды перехода в 0-й банк.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 4Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_5 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
25
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 20h и до ячейки с адресом 7Fh,
; чисел, которые отличны от 0 (включая и отображаемую область оперпамяти).
; Так как, в данном случае, области оперпамяти с адресами 70h...7Fh (0-й банк), F0h...FFh, (1-й
; банк), 170h...17Fh (2-й банк), 1F0h...1FFh (3-й банк) являются отображаемыми, то они
; предустанавливаются одинаково (в оперячееках с адресами 7Fh, FFh, 17Fh, 1FFh ноли выставляется
; по факту окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START bcf STATUS,IRP ; Переход на работу в 0-м и 1-м банках.
; Если этого не сделать, то после осуществления перехода
; goto START (см. ниже), дальнейшая работа будет происходить
; не в “связке” 0-го и 1-го банков, а в “связке” 2-го и 3-го
; банков (“бяка”).
bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
bcf STATUS,RP1 ; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
;----------------------------------------------------------------------------------------------------
; Примечание: команда bcf STATUS,IRP нужна в тех случаях, когда отрабатываются циклы от 2-го и далее
; (“влёт” в ПП START осуществляется из 3-го банка), а в 1-м цикле, эта команда подтверждает ранее
; установленное состояние.
; Команда bsf STATUS,RP0 нужна только при отработке 1-го цикла, так как в этом случае
; осуществляется переход, из 0-го банка (он установлен по умолчанию), в 1-й, а в следующих циклах
; (“влёт” в ПП START осуществляется из 3-го банка), эта команда подтверждает ранее установленное
; состояние.
;----------------------------------------------------------------------------------------------------
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 7Fh) записывается
movwf 7Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 7Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом A0h и до ячейки с адресом EFh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом EFh. В ней 0 выставляется по факту
; окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое отображаемой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 0A0h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом A0h (см. соответствующую карту оперпамяти).
movlw .79 ; (.79=4Fh) В счётчик проходов (адрес ячейки EFh) записывается
movwf 0EFh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 movf 0EFh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_1 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
26
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0EFh,F ; - 1 из счётчика проходов.
goto SNOVA_1 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 110h и до ячейки с адресом 16Fh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом 16Fh. В ней 0 выставляется по
; факту окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое отображаемой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_1 bsf STATUS,IRP ; Так как далее предустанавливается содержимое регистров общего
; назначения 2-го и 3-го банков, то переход на работу во 2-м
; и 3-м банках.
bcf STATUS,RP0 ; После этого, выбор конкретного банка этой “связки”,
bsf STATUS,RP1 ; в данном случае, 2-го банка.
27
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0EFh,F ; - 1 из счётчика проходов.
goto SNOVA_3 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@---
; Предустановка, в оперячейках (от ячейки с адресом A0h и до ячейки с адресом EFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_3 bcf STATUS,IRP ; Так как далее предустанавливается <- ТОЧКА ОСТАНОВКИ №1
; содержимое регистров общего назначения 1-го банка,
; то переход на работу в 0-м и 1-м банках.
bcf STATUS,RP1 ; Выбор 1-го банка.
;(“влёт” в процедуру осуществляется из 3-го банка).
movlw 0A0h ; Потоковая запись чисел начинается
; от оперячейки с адресом A0h
movwf FSR ; (см. соответствующую карту оперпамяти).
movlw .79 ; В счётчик проходов записывается количество оперячеек,
movwf 0EFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;---------------------------------------------------------------------------------------------
; Примечание: в данном случае, под счётчик проходов назначена последняя активная оперячейка
; 1-го банка с адресом EFh. По окончании процедуры потоковой предустановки нолей, в ней,
; по причине обнуления счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_4 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_4 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0EFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_4 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_4 movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;-----------------------------------------------------------------------------------------------
; Примечание: в данном случае, счётчик проходов “дислоцируется” в 1-м банке, но он отображается
; и в 0-м банке. По окончании процедуры потоковой предустановки нолей, в ней, по причине обнуления
; счётчика проходов, устанавливается 0 (т.е. сбрасывать её не нужно).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_5 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_5 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_5 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
28
; Предустановка, в оперячейках (от ячейки с адресом 110h и до ячейки с адресом 16Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_5 bsf STATUS,IRP ; Так как далее предустанавливается содержимое регистров общего
; назначения 2-го банка, то переход на работу во 2-м и 3-м банках
bcf STATUS,RP0 ; Выбор 2-го банка.
bsf STATUS,RP1 ; (“влёт” в процедуру осуществляется из 1-го банка).
29
decf 0EFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_7 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
30
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом A0h и до ячейки с адресом FFh,
; чисел, которые отличны от 0.
; Так как, в данном случае, содержимое 1-го банка отображается на 3-й банк, то предустановки обоих
; этих банков будут одинаковы (в оперячееках с адресами FFh, 1FFh, ноли выставляется по факту
; окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD bsf STATUS,RP0 ; Выбор 1-го банка.
;(“влёт” в процедуру осуществляется из 0-го банка).
movlw 0A0h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом A0h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки FFh) записывается
movwf 0FFh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 movf 0FFh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_1 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0FFh,F ; - 1 из счётчика проходов.
goto SNOVA_1 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@---
; Предустановка, в оперячейках (от ячейки с адресом A0h и до ячейки с адресом FFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_1 movlw 0A0h ; Потоковая запись чисел начинается <- ТОЧКА ОСТАНОВКИ №1
; от оперячейки с адресом A0h
movwf FSR ; (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 0FFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_2 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_2 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0FFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_2 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
31
VIHOD_2 bcf STATUS,RP0 ; Выбор 0-го банка.
;(“влёт” в процедуру осуществляется из 1-го банка).
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_3 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду
; goto <туда, куда нужно>.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_3 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
32
; Выключено: защита, WDT, сброс BOR, LVP, DEBUG.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 20h и до ячейки с адресом 7Fh,
; чисел, которые отличны от 0.
; Так как, в данном случае, содержимое 0-го банка отображается на 2-й банк, то предустановки обоих
; этих банков будут одинаковы (в оперячееках с адресами 7Fh, 17Fh, ноли выставляется по факту
; окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 7Fh) записывается
movwf 7Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 7Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковая запись чисел начинается <- ТОЧКА ОСТАНОВКИ №1
movwf FSR ; от оперячейки с адресом 20h
; (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 7Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду
; goto <туда, куда нужно>. Выход с 0-м банком.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
33
Для PIC16F873 / 873A / 874 / 874A
Предустановка регистров общего назначения 1-го и 3-го банков.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений.
;***************************************************************************************************
LIST p=16f873A ; Используется PIC16F873A.
#include <p16f873a.inc>; Подключение INC-файла PIC16F873A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 3F31H ; Включено: XT-генератор, PWRT,
; Выключено: защита, WDT, сброс BOR, LVP, DEBUG.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом A0h и до ячейки с адресом FFh,
; чисел, которые отличны от 0.
; Так как, в данном случае, содержимое 1-го банка отображается на 3-й банк, то предустановки обоих
; этих банков будут одинаковы (в оперячееках с адресами FFh, 1FFh, ноли выставляется по факту
; окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START bsf STATUS,RP0 ; Переход в 1-й банк.
movlw 0A0h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом A0h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки FFh) записывается
movwf 0FFh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 0FFh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
34
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0FFh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом A0h и до ячейки с адресом FFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 0A0h ; Потоковая запись чисел начинается <- ТОЧКА ОСТАНОВКИ №1
movwf FSR ; от оперячейки с адресом A0h
; (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 0FFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду
; goto <туда, куда нужно>. Выход с 1-м банком.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 0FFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.
Ещё раз обращаю Ваше внимание на то, что “вышележащие” программные процедуры
предустановок являются универсальными à в них, по желанию конструктора, можно
35
задать произвольный массив (массивы), подлежащий предустановке (естественно, в границах
дозволенного).
Если же речь идёт не об очистке части “банкомассива” (а также и во множественном числе)
регистров общего назначения, а об очистке его всего, то процедуру очистки можно
упростить так, как указано стр. 6-14 “Справочника по среднему семейству …” (с учётом
“нижележащего” примечания).
Смысл этого “действа” относительно прост: если речь идёт о 0-м и 2-м банках, то
процедура очистки ориентирована на факт обнаружения единицы в бите №7 указателя
оперАдреса (то есть, числа .128), а если речь идёт о 1-м и 3-м банках, то процедура
очистки ориентирована на факт обнаружения “кольцевого” перехода указателя
оперАдреса, из состояния FFh, в состояние 00h.
Примечание: на стр. 6-14 “Справочника по среднему семейству …” допущена ошибка à указан не флаг Z, а флаг С.
Мотивация: во внутреннем цикле очистки нет команд, воздействующих на флаг С, что приводит к “глюку”. Вместо
флага С, должен “фигурировать” флаг Z, так как команда incf на него воздействует. Вы можете убедиться в наличии
такого “глюка”, если, в “нижележащей” программе (в цикле SNOVA_2), замените Z на С.
37
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, то команду
; goto START нужно заменить на команду goto <туда, куда нужно>, либо без этой команды
; (будет исполняться то, что “лежит” ниже).
;----------------------------------------------------------------------------------------------------
;....................................
;....................................
;****************************************************************************************************
end ; Конец программы.
Общие положения
Таблица данных это массив данных (несколько позиций/строк. В форме нескольких байтов),
который, с целью осуществления задуманного конструктором действия,
подлежит дальнейшему, последовательному считыванию (в том числе и с последующим
осуществлением модификации считанного, а также и прочих действий. Это зависит от конкретной задумки) .
То есть, “проведена аналогия” с тем, что всем привычно (с некой таблицей “того-сего”).
Естественно, что в приложении к нашему делу, имеется “табличная специфика”.
Оптимальная (с точки зрения простоты “эксплуатации” и т.д.) таблица данных является, если так
можно выразиться, “адреснолинейной” (а не “адресно-кусочно-рваной”).
В том смысле, что в “адреснолинейной” таблице, числовые значения адресов любой
пары соседних строк таблицы отличаются на единицу.
Если массив данных представляет собой “набор” N-количества “адреснолинейных”
таблиц, разделённых “адресно-кусочно-рваностью”, то целесообразно программно
разделить этот массив на N “адреснолинейных” таблиц и отрабатывать их
последовательно (естественно, при условии осуществления соответствующих, “влётных”, адресных коррекций).
Мотивация: в “адреснолинейном” случае, можно применить такую “компактную
красатульку”, как косвенная адресация (вплоть до иных, табличных “спецприбамбасов”. Это о ПИКах 18-й
серии и выше).
Прежде чем считать массив данных, нужно обеспечить его наличие, а иначе нечего
будет считывать/модифицировать/записывать.
То, о чём ранее шла речь, это один из способов создания массивов данных (таблиц),
подлежащих дальнейшей обработке.
А именно, в “вышележащих” случаях, речь шла только о записях, причём, только в
область оперпамяти, но ведь кроме неё есть ещё и EEPROM-память данных,
и Flash-память программ.
Туда тоже можно записать массив/массивы данных (а затем считать и т.д.).
Нет проблем, но при одном обязательном условии: нужно знать, как именно это
осуществить.
А пока продолжаю работать по последовательному, плановому, “удавному” принципу,
а заодно и ещё раз напоминаю о том, что массив/массивы данных (то есть, содержимое
таблицы/таблиц) можно записать (а соответственно и считать):
39
в область оперпамяти,
в EEPROM-память данных,
во Flash-память программ.
Проще говоря, таблицу/таблицы можно создать как в любом из этих “мест”, так и в
комплексе.
Работаем дальше. Пока, с “привязкой” к оперпамяти.
Сразу обращаю Ваше внимание на то, что массив данных копируется, из одного
“сектора” оперпамяти, в другой, не “оптом”, а строго последовательно, начиная от 1-й
строки таблицы (1-го байта), и заканчивая последней (в итоге à тот же самый “опт”).
Один из вариантов подобного рода “свистопляски” выглядит так (“мал золотник, да дорог”!):
40
; ТАБЛИЦА СОЗДАНА (теперь есть с чем работать). ПОСЛЕДОВАТЕЛЬНО СЧИТЫВАЕМ ЕЁ
; ДАННЫЕ (в регистр Reg), МОДИФИЦИРУЕМ ИХ (инкремент) И ЗАПИСЫВАЕМ РЕЗУЛЬТАТЫ
; МОДИФИКАЦИЙ В ЗАДАННЫЙ “СЕКТОР” ОПЕРПАМЯТИ 1-го БАНКА.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Последовательное чтение данных из массива оперячеек с адресами 20h..2Fh, модификация считанного
; (инкремент), после чего осуществляется последовательное копирование (запись) модифицированных
; данных в массив оперячеек с адресами A0h..AFh.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковое чтение ранее записанного начинается
movwf FSR ; от оперячейки с адресом 20h.
movlw .16 ; В счётчик проходов записывается количество оперячеек,
movwf Count ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;####################################################################################################
; Циклическая ПП чтения-модификации-записи.
;####################################################################################################
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, чтение закончено или нет ?)
goto $ ; “Мертвяк”. <- ТОЧКА ОСТАНОВКИ №2
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, по причине применения “мертвяка”, отрабатывается один полный цикл
; программы, но если нужно выйти, из этой процедуры, по сценарию “программа исполняется далее”,
; то команду goto $ нужно заменить на команду goto <туда, куда нужно>.
;----------------------------------------------------------------------------------------------------
; Cчитывание содержимого текущей оперячейки (т.е. ранее записаных данных) в регистр Reg
; (суть: оперсохранение считанных данных, с целью осуществления их дальнейшей модификации).
;------------------------------------------------------------------------------------------
movf INDF,W ; Содержимое текущей оперячейки копируется в W
movwf Reg ; W -> Reg
;--------------------------------------------------------------------------
; Модификация (в данном случае, очень простая. Она может быть и посложнее).
;--------------------------------------------------------------------------
incf Reg,F ; Reg + 1 = ... (результат -> Reg)
;----------------------------------------------------------------------------------------------------
; Так как текущий результат модификации нужно скопировать/записать в соответствующую оперячейку 1-го
; банка (“влёт в нижележащее” происходит из 0-го банка), то адресный выбор “зеркальной” оперячейки
; 1-го банка.
;----------------------------------------------------------------------------------------------------
bsf FSR,7 ; Содержимое FSR увеличивается на 80h
; (“адресозеркальный” переход в 1-й банк).
;---------------------------------------------------------------------------------------------------
; Если нужно не “зеркальное” задание “сектора” копирования, а произвольное (с заданным адресным
; смещением относительно “зеркалки”), то содержимое FSR необходимо скорректировать так (в паре с
; “нижележащим”. См. выделенное зелёным цветом):
;---------------------------------------------------------------------------------------------------
;;; movlw 80h ; Содержимое FSR увеличивается на 80h
;;; addwf FSR,F ; (работа в 1-м банке. Для косвенной адресации).
;---------------------------------------------------------------------------------------------------
; Пояснение: для того чтобы изменить адресное положение считанного массива данных, нужно
; заблокировать обе команды, обращающиеся к биту №7 регистра FSR (выделены красным цветом) и
; разблокировать те команды, которые выделены зелёным цветом. В данном случае (выставлена
; корректирующая поправка 80h), имеет место быть “зеркалка” (эквивалентно обращению к биту №7
; регистра FSR), но если одинаково увеличить числовые значения обеих адресных поправок (см. то, что
; выше и ниже выделено зелёным цветом), то “месторасположение” считанного массива данных изменится
; (его можно адресно сместить туда, куда нужно. В пределах дозволенного). Величина адресного смещения
; считанного массива данных зависит от величины адресной поправки.
;---------------------------------------------------------------------------------------------------
; Запись ранее считанного (из оперячейки 0-го банка) байта, в соответствующую оперячейку 1-го банка.
;---------------------------------------------------------------------------------------------------
movf Reg,W ; Ранее оперсохранённое -> W
movwf INDF ; В текущую оперячейку 1-го банка записывается то, что ранее
; было считано из текущей оперячейки 0-го банка.
;---------------------------------------------------------------------------------------------------
; Для того чтобы продолжить считывание байтов таблицы, “лежащей” в 0-м банке, нужно в него перейти.
;---------------------------------------------------------------------------------------------------
bcf FSR,7 ; Содержимое FSR уменьшается на 80h
; (“адресозеркальный” переход в 0-й банк).
;---------------------------------------------------------------------------------------------------
;;; movlw 80h ; Содержимое FSR уменьшается на 80h
;;; subwf FSR,F ; (работа в 0-м банке. Для косвенной адресации).
;---------------------------------------------------------------------------------------------------
; Подготовка к чтению следующего байта.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf Count,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
41
;****************************************************************************************************
end ; Конец программы.
42
далее, результаты модификации, с применением косвенной адресации,
записываются в адресно-заданный “сектор” оперпамяти 1-го банка
(“чтение-модификация-запись”).
Так как этих циклов 16 штук, то в конечном итоге, массив оперданных скопируется, из
заранее известного “сектора” оперпамяти 0-го банка, в заданный “сектор” оперпамяти
1-го банка (а можно и во 2-й банк. А можно и в другой “сектор” 0-го банка. Если адресно подсуетиться), и все
дела.
Далее à “мертвяк”, но можно придумать и что-то более
симпатичное/жизнеутверждающее/... .
Вопрос: “А почему переход, в 1-й банк, осуществляется не с помощью штатной
команды bsf STATUS,RP0, а с помощью команды bsf FSR,7”?
Ответ: в приложении к “банковским делам”, прямая и косвенная адресация
относятся к разным “епархиям”.
Для косвенной адресации, команда bsf STATUS,RP0 “по-барабану”.
Она её (а также и в приложении к биту RP1) в упор не “слушается”, так как не та “епархия”.
“Слушается” (в приложении к “банковским делам”, осуществляемым в “границах” заданной пары банков) только
“приказов” бита №7 указателя операдреса (если бит IRP = 0, что, в данном случае, имеет место быть
по умолчанию, то в бите №7 можно задать 0-й или 1-й банк).
Примечание: для прямой адресации, в “неотображаемых” случаях, это вовсе не “по-барабану”, но в данном случае,
“по-барабану”, так как регистры Reg и Count “прописаны” в отображаемой (на все банки) области оперпамяти.
43
А именно, в “шапкопрописанные” регистры общего назначения с названиями Reg_1,
Reg_2 и Reg_3.
Их количество можно нарастить, но во-первых, отображаемая область оперпамяти
PIC16F628/628A (в частности) не резиновая и она очень ценна (обычно в ней “прописывают
важняковые/ширпотребные” регистры), а во-вторых, если массив данных внушителен, то
“замучаешься прописывать” (условно. “Шапка” будет “массивной”).
На мой взгляд, целесообразно “состряпать” то, что имеет бОльшие возможности и
одновременно, компактность.
Особый интерес представляет копирование массива данных в неотображаемую область
оперпамяти того банка, который “нравится” (условно).
Если уж я ранее “привязался” к 1-му банку, то скопирую в него (из “сектора” EEPROM-памяти)
массив, состоящий из 16-ти байтов (можно и больше/меньше, но пусть будет такое количество).
Программная реализация этого “техзадания” выглядит так:
45
Копирование массива данных, из заданного “сектора” оперпамяти, в заданный
“сектор” EEPROM-памяти данных (“чтение-модификация-запись”),
с использованием косвенной адресации
46
; "лежат" в 1-м банке, то выбор 1-го банка.
movlw 0 ; Задание адреса первой ячейки EEPROM-массива
movwf EEADR ; (в данном случае, это EEPROM-ячейка с адресом 00h).
47