Вы находитесь на странице: 1из 47

Косвенная адресация и оперотображаемость.

Оглавление

Общие положения
Регистр спецназначения FSR
Регистр спецназначения INDF
Особенности применения косвенной адресации в приложении к
“клоноподобным” процедурам
Особенности применения косвенной адресации в приложении к предустановке,
в ячейках заданного “сектора” оперпамяти, заданных числовых значений
Примеры числовых предустановок массивов оперпамяти 2-банковых ПИКов
Примеры числовых предустановок массивов оперпамяти 4-банковых ПИКов
Выбор банков при прямой адресации
Выбор банков при косвенной адресации
Работа в “связке”
Применение косвенной адресации при работе с таблицами данных
Общие положения
Копирование массива данных, из одного “сектора” оперпамяти, в другой
(“чтение-модификация-запись”), с использованием косвенной адресации
Копирование массива данных, из заданного “сектора” EEPROM-памяти данных,
в заданный “сектор” оперпамяти (“чтение-модификация-запись”), с
использованием косвенной адресации
Копирование массива данных, из заданного “сектора” оперпамяти, в заданный
“сектор” EEPROM-памяти данных (“чтение-модификация-запись”),
с использованием косвенной адресации

Общие положения

В любом ПИКе имеются три функционально различные области памяти, которые


обеспечивают их (ПИКов) функционирование:

Обращения к этим видам памяти осуществляется по соответствующим внутренним,


параллельным интерфейсам (у каждого вида памяти, он “свой”), что позволяет организовать
параллельный (высокоскоростной) доступ к этим видам памяти.
По причине того, что грамотное применение косвенной адресации предполагает “въезд
в оперативную память данных”, перво-наперво необходимо разобраться именно с ней.
На рис. 1, этот вид памяти выделен светло-голубым цветом.
Соответственно, прежде чем “въезжать в нижележащее”, целесообразно усвоить
информацию статьи Карты оперпамяти различных типов ПИКов.
Предположим, что эта информация усвоена.
Теперь можно двигаться дальше.
Рассмотрим самый простой случай: необходимо произвести какую-то операцию с
содержимым одного из регистров оперпамяти, который задействован в программе.
Во-первых, к нему нужно адресоваться (выбрать оперячейку из массива оперпамяти).
Во-вторых, произвести нужную операцию (это “епархия” кода конкретной команды).
Существуют 2 вида реализации этой “штатной” задумки, которые связаны:
 с прямой адресацией,
 с косвенной адресацией.
1
Например, нужно банально скопировать содержимое регистра Reg в аккумулятор (W).
Если применить прямую адресацию, то это выглядит так:

movf Reg,W ; Reg -> W (прямая адресация).


Примечание: обращение к содержимому регистра есть адресное обращение (напоминаю о
“шапковых” директивах equ и cblock/endc) к той ячейке оперпамяти, которой, в данном случае,
присвоено название Reg, после чего содержимое этой оперячейки копируется в W.

Если применить косвенную адресацию, то программная реализация того же действия


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

movlw Reg ; В W записывается константа (см. movlw),


; числовое значение которой = числовому
; значению адреса той оперячейки, которой
; присвоено название Reg. Проще говоря,
; в W записывается операдрес регистра Reg.
movwf FSR ; Копирование операдреса регистра Reg
; в регистр FSR.
movf INDF,W ; Обращение к регистру INDF эквивалентно
; обращению к содержимому того регистра,
; операдрес которого записан в регистр FSR.
; Так как в данном случае, в регистре FSR
; “лежит” операдрес регистра Reg, то его
; содержимое копируется в W.

То есть, в случае использования косвенной адресации, задействуются 2 регистра


специального назначения, которые, образно выражаясь, “заточены под это дело”:

Регистр спецназначения FSR

Это регистр хранения адреса той оперячейки, к содержимому которой, в дальнейшем,


произойдёт обращение.
А можно назвать и указателем адреса текущей оперячейки.
В регистр FSR записывается числовое значение операдреса
- либо тем способом, который указан выше:
movlw <название регистра>
movwf FSR
- либо с помощью прямого указания числового значения операдреса:
movlw <числовое значение операдреса>
movwf FSR
Так как регистр FSR является “полноценным” регистром спецназначения (доступен для
записи/чтения), его содержимое, по ходу исполнения программы, можно программно
изменять (в зависимости от текущих “насущностей”), что позволяет адресно обращаться
(в последовательном порядке) к различным ячейкам оперпамяти.

Регистр спецназначения INDF

На мой взгляд, называть регистр INDF регистром спецназначения слегка не корректно,


так как он физически не реализован, но ведь как-то же нужно было обозначить то, к
чему (в случае использования косвенной адресации) происходит обращение.
По этому поводу, разработчики не стали “городить понятийный огород”, а просто
присвоили этой “штуковине” статус регистра спецназначения (с “выделением соответствующего
местечка” в области оперпамяти).
Пусть будет так.
Факт обращения к якобы регистру спецназначения INDF есть не что иное, как “запуск
в работу” аппаратного процесса, результатом отработки которого является воздействие
на содержимое того регистра, адрес которого “лежит” в указателе адреса (то есть, в
регистре FSR).

2
Иными словами, обращение к регистру INDF “запускает в работу” относительно
несложный, аппаратный модуль косвенной адресации, который, если так можно
выразиться, “всё сделает в лучшем виде”.
Голос из-за кулис: “Ты что пропагандируешь, тудыть твою растудыть! Коню понятно,
что одна команда симпатичнее трёх (см. выше)”.
Ответ: в приложении к “вышележащему” сравнению, вне сомнений, симпатичнее, но как
быть с цитатой из “Справочника по среднему семейству…”: Режим косвенной
адресации может быть полезен при обращении к таблицам данных (а я бы ещё
сказал, что и в других случаях)?
“Это жу-жу не спроста” (сказал Винни-Пух). Где-то “прячется приятность типа мёд”.
Так оно и есть: в некоторых, специфических случаях, суть перехода, от прямой
адресации, к косвенной, сводится к оптимизации типа обмен уменьшения количества
команд исходной процедуры, на увеличение времени её отработки.
Вопрос: “По какой причине возникает относительная, временнАя затяжка”?
Ответ: команды, которые обеспечивают осуществление такой разновидности
оптимизации, исполняются не за ноль секунд, что, с учётом цикличности исполнения
“заоптимизированной”, программной процедуры (имеются в виду её внутренние циклы), приводит к
увеличению времени её отработки (по сравнению со временем отработки исходной, “незаоптимизированной”
процедуры) на величину суммарного времени отработки этих команд.

Особенности применения косвенной адресации в приложении к


“клоноподобным” процедурам

Начну с привычной для Вас (надеюсь на это) процедуры.


Условно предположим, что конструктор не использовал косвенную адресацию и
изначально “сваял” это (см. статью Подпрограммы 2_10 преобразований, программа №25. Это её
упрощённый фрагмент):

;....................................
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 ;

goto LOOP16 ; Переход на следующий цикл.


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

“Даже невооружённым глазом” видна командная избыточность, в виде 4-х


“клоноподобных” процедур.
Различия только в номерах LEDов.
Если конструктор этого захочет (естественно, что наличие соответствующих знаний обязательно), то
группу подобного рода “клоноподобных” процедур (не только этих, но и аналогичных) можно
подвергнуть указанной выше оптимизации.
Её суть заключается в том, что “массив клоноподобных” процедур “ужимается” до
одной вызываемой подпрограммы, в которой происходит обращение (обращения) к
регистру INDF.
Соответственно, перед вызовом этой ПП, нужно записать, в регистр FSR, операдрес
текущего LEDа.
Реализация сказанного, с использованием косвенной адресации, выглядит так (см. статью
Подпрограммы 2_10 преобразований, программа №10. Это её упрощённый фрагмент):

;....................................
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 ;

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 ;

retlw 0 ; Возврат по стеку.


;----------------------------------------------------------------------------------------------
; Примечание: addwf INDF,W можно заменить на addwf 0,W и movwf INDF можно заменить на movwf 0
;----------------------------------------------------------------------------------------------
;....................................

4
Выигрыш (по количеству команд) очевиден, но эта процедура будет отрабатываться немного
помедленнее (относительно исходной), так как записи операдресов, в регистр FSR, а также и
переходы/возвраты требуют дополнительного времени.
В подобного рода командной оптимизации, ничего выдающегося нет (несколько “клонов”
сводятся к одной вызываемой ПП. Обычная методика. В частности, см. подраздел 2 статьи “Обмена…” 4_72, и в моих
книгах/статьях об этом неоднократно упомянуто), за исключением того, что в вызываемой ПП
происходит обращение (обращения) к регистру INDF.
Обратите внимание на группу команд с названием Подготовка к косвенной
адресации и вызов ПП adjBCD.
Аналогичные группы команд, лично я, называю “администраторскими группами команд”.
И в самом деле, некое “администрирование” налицо:

 после “влёта в админ”, он отдаёт 1-й программный “приказ”,


 исполнение 1-го “приказа” и возврат на начало “отдачи 2-го приказа”,
 “админ” отдаёт 2-й программный “приказ”,
 исполнение 2-го “приказа” и возврат на начало “отдачи 3-го приказа”
 и т.д. (зависит от количества последовательно исполняемых “приказов”),
 а по окончании полного цикла “администрирования, осуществляется либо выход
из него (на начало исполнения другой группы команд), либо “закольцовка” на его начало
(зависит от конкретной задумки).

Это есть основа того, что некоторые люди называют “суперлупом”, но лично мне, это
слово не нравится (возникает такая ассоциация à глаза на выкате, вплоть до вываливания из глазниц).
“Администраторская группа команд” может состоять:
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 ;

retlw 0 ; Возврат по стеку.


;----------------------------------------------------------------------------------------------
; Примечание: addwf INDF,W можно заменить на addwf 0,W и movwf INDF можно заменить на movwf 0
;----------------------------------------------------------------------------------------------
;....................................

Серым цветом выделено то, что “убито”.


Синим цветом выделены “нововведения” (взамен “убитого”).
Таким образом произведена командноскоростная оптимизация “администраторской
группы команд”, обеспечивающая выигрыш и по количеству команд (минус 3 команды), и по
скорости.
А именно, первая “загрузка” операдреса регистра LED0, в регистр FSR, происходит без
“катаклизмов” (так, как ранее. В данном случае, можно заменить команду movlw LED0 на команду movlw 20h. На
усмотрение конструктора).
Это, если так можно выразиться, “начальная точка FSR-отсчёта”.
И в самом деле, если LEDы “шапкопрописаны” в порядке последовательного
возрастания их номеров (в рассматриваемом случае, по направлению сверху вниз), то зачем, в
дальнейшем, использовать пары команд (работа через “посредника” W), если любую из этих
пар можно заменить одной командой инкремента содержимого регистра FSR
(с сохранением результата инкремента в нём же)?
Это и сделано (см. выше).

Примечание: если LEDы “шапкопрописаны” в порядке последовательного убывания их номеров, то нужно использовать
не инкременты, а декременты (в начале “админа” à обращение к адресу “нижней” оперячейки).

В результате (в данном случае), “мать ужалась” на 3 команды и процедура отрабатывается


быстрее (минус 93 м.ц.).

Примечание: если количество проходов = 32 и “админ ужался” на 3 команды (как в рассматриваемом случае), то
скоростной выигрыш составляет 2427 – 2334 = 93 м.ц. (судя по результатам замеров)
То есть, в общем виде, скоростной выигрыш (в машинных циклах) = (Nпроходов – 1) х N”убитых” команд.
В данном случае, скоростной выигрыш = (32 – 1) х 3 = 93 м.ц.

6
Особенности применения косвенной адресации в приложении к предустановке, в
ячейках заданного “сектора” оперпамяти, заданных числовых значений

Пояснение: объяснения производятся в контексте “въезда” в косвенную адресацию, а заодно и в


контексте “разборок” с отображаемыми/неотображаемыми областями оперпамяти.

Актуальность/желательность/… (вплоть до необходимости) командного “компактизирования”


процедур этих предустановок мотивированы тем, что количество оперячеек
предустанавливаемого массива может быть весьма внушительным.
В этих случаях, использование прямой адресации, если так можно выразиться,
“породИт программного монстра, внешний вид которого (имеется в виду “PC-масса”) будет
несимпатичным/растрёпанным” (вспомнил высказывание М.Задорнова: “Хватит лохматить бабушку”!).
“Въезд” в эти относительно “массивные” предустановки нужно начать с того, что
относительно проще.
Доподлинно известно, что после инициализации ПИКа (сброс POR. Речь идёт не о работе в
симуляторе, а о работе “в железе”), в оперячейках регистров общего назначения
устанавливаются случайные числа.
Во многих случаях это не имеет значения, так как по ходу исполнения программы, эти
“паразиты уничтожаются” записью, по их верху, нужных (условно) значений, но иногда
(мало ли… А вдруг что-то не учтено/упущено. В жизни всякое случается) бывает полезным “оптово убить
этих паразитов на подлёте (в ПП START, а если рассуждать в общем виде, то в начале исполнения
программы) к святая святых” (официальное название этого “действа” - инициализация регистров общего
назначения).
Это актуально при конструировании устройств, которые предназначены для массового
тиражирования, так как может возникнуть конфуз типа “некоторые устройства работают
нормально, а некоторые не хотят”.
Самый простой способ придания содержимому оперячеек заранее известных
конструктору (и гарантированно установленных) значений, от которых, в дальнейшем, “можно
плясать”, это их программный, “оптовый” сброс в ноль (иногда бывает полезным предустановить
другое число. Целесообразность этого зависит от конкретной задумки).
Вопрос: “Оптово это как”?
Ответ: по здравому разумению, достаточно предустановить только те регистры общего
назначения, которые задействованы в программе, но частенько, как говорится, “за
компанию”, предустанавливают и те регистры общего назначения, которые не
задействованы в программе, но по мере “ваяния” текста программы (например, в случае
расширения функциональности устройства), могут быть задействованы.
При этом, конструктор точно знает, что “на влёте в святая святых”, в этих оперячейках
“железобетонно” предустановлены известные ему числовые значения (а не “анархические”) и
ориентируется на это.
Далее получается интересная оргситуация.
Я могу предоставить несколько разновидностей программных процедур очистки
оперячеек, но в MPLAB, проконтролировать процесс очистки нельзя, так как MPLAB -
не ясновидящий.
По этой причине, в ячейках регистров общего назначения, он просто “тупо” выставляет
ноли и, как говорится, “будь здоров”.
Соответственно, будет происходить смена нолей на ноли, в чём, как сами понимаете,
нет никакой наглядности, а заодно и “извилинной отрады”.
Значит, прежде чем осуществлять очистку массива (массивов) оперячеек регистров общего
назначения (регистры спецназначения не в счёт!!!), нужно сымитировать (это слово пишется через “ы”) то,
что подлежит очищению (это “то” должно быть отличным от нолей и “симуляторно бросаться в глаза”).
В реале (то есть, в “железе”), это “числа-анархисты”, но для MPLAB-проверки процесса
очищения, подойдут и “предустановленные неанархисты” (“квазианархисты”).
Например, ряд/массив чисел, программно сформированный при помощи
последовательных инкрементов или декрементов.
В зависимости от типа ПИКа, банков может быть как 2 (0-й, 1-й), так и 4 (0-й, 1-й, 2-й, 3-й).
7
Примеры числовых предустановок массивов оперпамяти 2-банковых ПИКов

Вашему вниманию предлагаются (здесь и ниже) универсальные “конструкции” процедур


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

Для PIC16F84 / 84A


Работа со всем массивом регистров общего назначения 0-го и 1-го банков
(так как в этом типе ПИКа все регистры общего назначения 0-го банка
отображаются в 1-м банке).
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданного “сектора” оперпамяти, заданных числовых значений.
; Сначала, в декрементном порядке, производится предустановка чисел от 43h (в ячейке с адресом 0Ch),
; до 00h (в ячейке с адресом 4Fh) а затем производится очистка этих предустановок.
;***************************************************************************************************
LIST p=16f84A ; Используется PIC16F84A.
#include <p16f84a.inc>; Подключение INC-файла PIC16F84A.
__CONFIG 03FF1H ; Бит защиты выключен, WDT выключен, XT - генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка в регистрах общего назначения 0-го банка, от ячейки с адресом 0Ch и до ячейки с
; адресом 4Fh, чисел, которые отличны от 0 (за исключением оперячейки с адресом 4Fh. В ней 0
; выставляется по факту окончания потоковой предустановки). Так как, в данном случае, все регистры
; общего назначения 0-го банка отображаются в 1-м банке, то такая же предустановка будет и в нём.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START movlw 0Ch ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 0Ch (см. соответствующую карту оперпамяти).
movlw .67 ; (.67=43h) В счётчик проходов (адрес ячейки 4Fh) записывается
movwf 4Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 4Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №1
; процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 4Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 0Ch и до ячейки с адресом 4Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 0Ch ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 0Ch (см. соответствующую карту оперпамяти).
movlw .67 ; В счётчик проходов записывается количество оперячеек,
movwf 4Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на

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 ; Конец программы.

Обратите внимание на то, что в этой программе, по причине ненужности,


“шапкопрописка” регистров общего назначения отсутствует.
Соответственно, обращения происходят не к “шапкопрописанным” названиям регистров
общего назначения (этой “шапкопрописки” нет), а адресно. Можно и так (“мотайте на ус”. Пригодится).
Если выставить обе точки остановки (в тексте программы, они помечены), то щёлкая
по “кнопке-автомату”, Вы будете наблюдать последовательную смену этих картинок:

Здесь и ниже, отображаемые области оперпамяти (в части касающейся регистров общего


назначения) выделены синими рамками.
В данном случае, по причине отображения регистров общего назначения 0-го банка, в
1-м банке (и наоборот. См. карту оперпамяти PIC16F84 / 84A), по ходу отработки программы (если
выставить точки остановок на командах goto SNOVA и goto SNOVA_1, то можно проконтролировать), происходят
“синхронные” (“клоноподобные”) предустановки регистров общего назначения обоих банков.
Вопрос: “А если необходимо предустановить только часть регистров общего
назначения, то как быть”?
Ответ: нужно просто изменить адресацию, то есть, назначить адрес той оперячейки, от
которой необходимо начать предустановку, и адрес той оперячейки, в которой её
нужно закончить (она же - оперячейка счётчика проходов), а также уменьшить “материнское”,
числовое значение .67 так, чтобы концовка результата предустановки была
… 02 01 00 (для левой картинки. См. выше). В этой статье, такие примеры есть.
Тем и хороша косвенная адресация: небольшая коррекция, без изменения “массы”
процедуры, и её “командная компактность”.
То есть, в данном случае (“основной упор” на очистку), верхняя (по тексту программы) программная
процедура предустановки является как бы вспомогательной/выяснятельной (здесь и
далее выделено тёмно-красным цветом).

9
В том смысле, что в ней можно “симуляторно подобрать” (это не сложно) нужные (условно)
числовые значения констант, которые используются в “нижележащей”, программной
процедуре очистки вожделеемого “сектора” оперпамяти (выделено чёрным цветом).
Физически нереализованную область оперпамяти (на картинках, она обозначена пунктирами)
предустанавливать не имеет смысла, так как это достаточно бестолковое занятие.
А это то же самое (по смыслу. В данном случае, для PIC12F629), только в приложении к другим
типам 2-банковых ПИКов (у них область оперпамяти “сконструирована” несколько иначе, чем в PIC16F84 / 84A.
См. соответствующие карты оперпамяти):

Для PIC12F629, PIC12F675, PIC16F630, PIC16F676


Работа со всем массивом регистров общего назначения 0-го и 1-го банков
(так как в этом типе ПИКа все регистры общего назначения 0-го банка
отображаются в 1-м банке).
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданного “сектора” оперпамяти, заданных числовых значений.
; Сначала, в декрементном порядке, производится предустановка чисел от 3Fh (в ячейке с адресом 20h),
; до 00h (в ячейке с адресом 5Fh) а затем производится очистка этих предустановок.
;***************************************************************************************************
LIST p=12f629 ; Используется PIC12F629.
#include <p12f629.inc>; Подключение INC-файла PIC12F629A.
__CONFIG 01A1h ; XT-генератор, PWRT включен, защита и WDT выключены.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения 0-го банка, от ячейки с адресом 20h и до ячейки с
; адресом 5Fh, чисел, которые отличны от 0 (за исключением оперячейки с адресом 5Fh. В ней 0
; выставляется по факту окончания потоковой предустановки). Так как, в данном случае, все регистры
; общего назначения 0-го банка отображаются в 1-м банке, то такая же предустановка будет и в нём.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .63 ; (.63=3Fh) В счётчик проходов (адрес ячейки 5Fh) записывается
movwf 5Fh ; количество оперячеек, содержимое которых подлежит предустановке
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf 5Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №1
; процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 5Fh,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 5Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .63 ; В счётчик проходов записывается количество оперячеек,
movwf 5Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,

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).
В этом случае, “картина” такая:

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


ячейки оперпамяти с адресами 70h … 7Fh (плюс, “зеркальное” отображение в ячейках 1-го банка с
адресами F0h … FFh), а остальные оперячейки не предустанавливаются.
То, что на этих картинках, в “непредустановленных” регистрах общего назначения,
“лежат” ноли, не должно вводить Вас в заблуждение, так как это работа не в
“железе”, а в MPLAB.
В реале, после инициализации ПИКа, в них будут “лежать” случайные числа (если, в
процессе конструирования устройства, можно “подпрячь” отладчик, то в нём это будет видно) .
Если нужно предустановить все регистры общего назначения, то это выглядит так:

Для 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-банковых ПИКов

Примечание: В приложении к 2-банковой работе, “межбанковые” переключения осуществляются с помощью одного-


разьединственного бита регистра STATUS с названием RP0 (выбор одной из 2-х возможных комбинаций).
В этих типах ПИКов, формально, биты RP1 и IRP зарезервированы для более “банкоёмких” типов ПИКов (обращаться
к ним не нужно), что упрощает “банкоработу”.

Так как 4 банка это не 2 банка (у 4-банковых ПИКов есть специфика), то настало время более
детально разобраться с “4-банковскими делами”:

Как видите, существует 2 способа адресных выборов “текущевожделеемых” банков.

Выбор банков при прямой адресации

Прямая адресация происходит в процессе любого обращения к содержимому регистра


оперпамяти, при том условии, что эти обращения не связаны с косвенной адресацией.
При работе с отображаемыми, во всех банках, регистрами общего и
специального назначения, “банковскими делами заморачиваться” не нужно.
Ими нужно “заморачиваться” при работе с неотображаемыми регистрами.
Если регистры отображаются частично, то есть, не во всех 4-х банках, а в
паре банков (например, в 0-м и 2-м или в 1-м и 3-м. Как в PIC16F873A), то в части касающейся
“отображаемости”, “ банковскими делами заморачиваться” не нужно, а в части
касающейся “неотображаемости”, нужно.

Наличие двух битов выбора банка (биты RP1, RP0 регистра STATUS) обусловлено тем, что
работа с 4-мя банками (128 х 4 = 512) требует наличия 9-ти битов, а в коде команды,
которая обращается к содержимому оперячейки, имеется только 7 битов (можно работать
только в “границах” одного 128-“ячеечного банка”. См. “вышележащую” картинку) , что недостаточно для того,
чтобы работать в “границах” 4-х банков.
Вот разработчики и придумали/добавили биты RP1 и RP0 (2 бита à 4 комбинации), поместив
их в регистр STATUS.
То есть,
 с помощью битов RP1 и RP0 (работа “в связке”) выбирается один из 4-х банков,
 а адресный выбор одной из оперячеек (работа внутри выбранного банка) определяется
кодом команды, которая обращается к её содержимому.
В части касающейся первого, можно сказать и так: состояние бита RP1 определяет
пару банков, а состояние бита RP0 определяет конкретный банк.

17
Выбор банков при косвенной адресации

Принципиальное отличие состоит в том, что в адресации участвуют не 7 битов,


входящих в код команды (см. “вышележащее” объяснение), а 8 битов указателя адреса (то есть,
регистра FSR. См. “вышележащую” картинку). Соответственно, можно косвенно адресоваться к
любой оперячейке двухбанкового массива.
Таким образом, если речь идёт о косвенной адресации, осуществляемой в 2-банковых
ПИКах, то, как говорится “вопрос исчерпан” (“цветут ромашки и поют соловьи”).
Если же речь идёт о косвенной адресации, осуществляемой в 4-банковых ПИКах, то
совсем не трудно догадаться о том, что при таком “раскладе”, нужно иметь
возможность программного выбора той или иной пары банков.
Вот разработчики и придумали/добавили бит IRP (1 бит à 2 комбинации), поместив его в тот
же регистр STATUS.
Если IRP = 0, то это работа в 0-м и 1-м банках,
а если IRP = 1, то это работа во 2-м и 3-м банках.

Работа в “связке”

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


осуществляется с помощью битов RP1 и RP0 регистра STATUS, а в случаях
применения косвенной адресации, выбор пары банков осуществляется с помощью бита
IRP регистра STATUS.
Сие, по-отдельности, не должно вызвать понятийных затруднений (надеюсь на это).
А если в комплексе?
Например, имеется некая “зона влияния” (условно) конкретного банка (по аналогии с “зоной
разрешения/запрета прерываний), и в этой “зоне” используются оба вышеописанных способа
адресации. Подобное имеет место быть “сплошь и рядом” (в очень большом количестве случаев).
В этих случаях, нужно учитывать состояния и бита IRP (под косвенную адресацию), и битов
RP1, RP0 (под прямую адресацию).
Отдельный пример: в “нижележащей” программе (не в следующей, а в той, которая “лежит” ниже её.
В ней предустанавливаются все регистры общего назначения) , есть такой фрагмент:
;....................................
START bcf STATUS,IRP ; Переход на работу в 0-м и 1-м банках.
; Если этого не сделать, то после осуществления перехода
; goto START (см. ниже), дальнейшая работа будет происходить
; не в “связке” 0-го и 1-го банков, а в “связке” 2-го и 3-го
; банков (“бяка”).
bsf STATUS,RP0 ; Так как при работе в 1-м банке, регистр счётчика проходов
bcf STATUS,RP1 ; “дислоцируется” в неотображаемой области оперпамяти,
; то переход в 1-й банк.
;....................................
; Вплоть до следующей “банковской перенастройки”.

“Влёт” в этот фрагмент происходит из пары банков 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-й банк.

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

Для PIC16F628 / 628A,


PIC16F876 / 876A / 877 / 877A
Работа с массивом регистров общего назначения 0-го банка. Группа регистров
18
общего назначения с адресами 70h … 7Fh отображается в остальных банках.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданного “сектора” оперпамяти, заданных числовых значений.
; Сначала, в декрементном порядке, производится предустановка чисел от 5Fh (в ячейке с адресом 20h),
; до 00h (в ячейке с адресом 7Fh) а затем производится очистка этих предустановок.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка регистров общего назначения 0-го банка, от ячейки с адресом 20h и до ячейки с адресом
; 7Fh, чисел, которые отличны от 0 (за исключением оперячейки с адресом 7Fh. В ней 0 выставляется по
; факту окончания потоковой предустановки).
; Так как, в данном случае, области оперпамяти с адресами 70h...7Fh (0-й банк), F0h...FFh, (1-й
; банк), 170h...17Fh (2-й банк), 1F0h...1FFh (3-й банк) являются отображаемыми, то они
; предустанавливаются одинаково (в оперячееках с адресами 7Fh, FFh, 17Fh, 1FFh ноли выставляется
; по факту окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
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 ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №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
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------

19
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду goto <туда, куда
; нужно>.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 7Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.

Для PIC16F628 / 628A

Для PIC16F876 / 876A / 877 / 877A

20
В данном случае, в 1, 2 и 3 банках отображается только часть массива регистров
общего назначения 0-го банка (см. “подмассив” с адресами 70h … 7Fh и его “зеркальные отображения” в
оперячейках с адресами F0h … FFh, 170h … 17Fh, 1F0h … 1FFh).
Если нужно предустановить только эти отображаемые “подмассивы” (4 штуки), то
необходимо:
 начальный адрес (заменить 20h на 70h),
 количество проходов (заменить .95 на .15),
 конечный адрес заменять не нужно (7Fh).
В этом случае, “картина” такая:

Для PIC16F628 / 628A

Для PIC16F876 / 876A / 877 / 877A

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-го банка.

movlw 20h ; Потоковая запись чисел начинается от оперячейки


movwf FSR ; с адресом 120h (см. соответствующую карту оперпамяти).
movlw .47 ; (.47=2Fh) В счётчик проходов (адрес ячейки 14Fh) записывается
movwf 4Fh ; количество оперячеек, содержимое которых подлежит предустановке
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 120h и 14Fh (их нельзя отобразить в одном
; байте. Гиблое дело), а 20h и 4Fh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 120h и 14Fh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).
; С учётом этого, а также того, что любой из банков расчитан на “дислокацию” 128-ми регистров,
; возникает некая “парная клоноподобность” (можно назвать и по-другому) адресации. В данном случае,
; в приложении к 0-му и 2-му банкам (что-то типа “адресной зеркалки”).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC----------------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_2 movf 4Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_2 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 4Fh,F ; - 1 из счётчика проходов.
goto SNOVA_2 ; Переход на начало следующей предустановки.
;--------------------------------------------------------------------------------------------------
; Примечание: в данном случае, в 3-м банке нет активных регистров общего назначения (за исключением
; отображаемых. Их предустановки произведены ранее), поэтому, в 3-м банке, ничего предустанавливать
; не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@---
; Предустановка, в оперячейках (от ячейки с адресом A0h и до ячейки с адресом EFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_2 bcf STATUS,IRP ; Так как далее предустанавливается <- ТОЧКА ОСТАНОВКИ №1
; содержимое регистров общего назначения 1-го банка,
; то переход на работу в 0-м и 1-м банках.
bsf STATUS,RP0 ; После этого, выбор конкретного банка этой “связки”,
bcf STATUS,RP1 ; в данном случае, 1-го банка.

movlw 0A0h ; Потоковая запись чисел начинается


; от оперячейки с адресом A0h
movwf FSR ; (см. соответствующую карту оперпамяти).
movlw .79 ; В счётчик проходов записывается количество оперячеек,
movwf 0EFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на

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-го банка.

movlw 20h ; Потоковая запись чисел начинается от оперячейки


movwf FSR ; с адресом 120h (см. соответствующую карту оперпамяти).
movlw .47 ; В счётчик проходов записывается количество оперячеек,
movwf 4Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 120h и 14Fh (их нельзя отобразить в одном
; байте. Гиблое дело), а 20h и 4Fh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 120h и 14Fh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).

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 ; Конец программы.

Для PIC16F876 / 876A / 877 / 877A


Предустановка всех регистров общего назначения.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений, причём,
; в приложении ко всем банкам.
;***************************************************************************************************
LIST p=16f876A ; Используется PIC16F876A.
#include <p16f876a.inc>; Подключение INC-файла PIC16F876A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 3F31H ; Включено: XT-генератор, PWRT,
; Выключено: защита, WDT, сброс BOR, LVP, DEBUG.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись

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-го банка.

movlw 10h ; Потоковая запись чисел начинается от оперячейки


movwf FSR ; с адресом 110h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 16Fh) записывается
movwf 6Fh ; количество оперячеек, содержимое которых подлежит предустановке
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 110h и 16Fh (их нельзя отобразить в одном
; байте. Гиблое дело), а 10h и 6Fh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 110h и 16Fh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC----------------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_2 movf 6Fh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_2 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 6Fh,F ; - 1 из счётчика проходов.
goto SNOVA_2 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 190h и до ячейки с адресом 1EFh,
; чисел, которые отличны от 0 (за исключением оперячейки с адресом 1EFh. В ней 0 выставляется по
; факту окончания потоковой предустановки).
; Так как содержимое отображаемой области оперпамяти предустановлено ранее (см. “вышележащие”
; комментарии), содержимое отображаемой группы регистров предустанавливать не нужно.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_2 bsf STATUS,RP0 ; Выбор 3-го банка
;(“влёт” в процедуру осуществляется из 2-го банка).
movlw 90h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 190h (см. соответствующую карту оперпамяти).
movlw .95 ; (.95=5Fh) В счётчик проходов (адрес ячейки 1EFh) записывается
movwf 0EFh ; количество оперячеек, содержимое которых подлежит предустановке
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 190h и 1EFh (их нельзя отобразить в одном
; байте. Гиблое дело), а 90h и EFh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 190h и 1EFh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC----------------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_3 movf 0EFh,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_3 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------

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-го банка).

movlw 10h ; Потоковая запись чисел начинается от оперячейки


movwf FSR ; с адресом 110h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 6Fh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 110h и 16Fh (их нельзя отобразить в одном
; байте. Гиблое дело), а 10h и 6Fh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 110h и 16Fh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_6 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD_6 ; Если все, то выход из процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf 6Fh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_6 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 190h и до ячейки с адресом 1EFh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD_6 bsf STATUS,RP0 ; Выбор 3-го банка.
; (“влёт” в процедуру осуществляется из 2-го банка).
movlw 90h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 190h (см. соответствующую карту оперпамяти).
movlw .95 ; В счётчик проходов записывается количество оперячеек,
movwf 0EFh ; содержимое которых подлежит предустановке.
bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с
; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;----------------------------------------------------------------------------------------------------
; ОБРАТИТЕ ВНИМАНИЕ на то, что выставляются адреса не 190h и 1EFh (их нельзя отобразить в одном
; байте. Гиблое дело), а 90h и EFh (можно отобразить в одном байте), но тем не менее,
; происходят обращения к оперячейкам с адресами 190h и 1EFh, так как ранее исполненная команда
; bsf STATUS,IRP, если так можно выразиться, “добавляет, к операдресу, единичку” (слева).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC---------------------------------------------------------
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA_7 btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, по сценарию
; “программа исполняется далее”, то команду goto START нужно заменить на команду goto <туда, куда
; нужно>.
;----------------------------------------------------------------------------------------------------
; Рабочее действие (в данном случае, очистка текущей оперячейки).
;----------------------------------------------------------------
clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;--------------------------------------
; Подготовка к следующей предустановке.
;--------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.

29
decf 0EFh,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_7 ; Переход на начало следующей предустановки.
;****************************************************************************************************
end ; Конец программы.

Для PIC16F873 / 873A / 874 / 874A


Предустановка всех регистров общего назначения.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений, причём,
; в приложении ко всем банкам.
;***************************************************************************************************
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-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 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 ; Отработаны все проходы или не все ?

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 ; Конец программы.

Для PIC16F873 / 873A / 874 / 874A


Предустановка регистров общего назначения 0-го и 2-го банков.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений.
;***************************************************************************************************
LIST p=16f873A ; Используется PIC16F873A.
#include <p16f873a.inc>; Подключение INC-файла PIC16F873A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 3F31H ; Включено: XT-генератор, PWRT,

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 на С.

Например, “вышележащая” программа предустановки всех регистров общего назначения


для PIC16F873 / 873A / 874 / 874A, в которой реализованы эти варианты очистки,
выглядит так (результаты работы этих вариантов программ одинаковы):

Для PIC16F873 / 873A / 874 / 874A


Предустановка всех регистров общего назначения (“компактный” вариант).
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданных “секторов” оперпамяти, заданных числовых значений, причём,
; в приложении ко всем банкам.
;***************************************************************************************************
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-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в регистрах общего назначения, от ячейки с адресом 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 из счётчика проходов.
36
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 ; (см. соответствующую карту оперпамяти).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC-----------
; Рабочее действие (очистка текущей оперячейки).
;-----------------------------------------------
SNOVA_2 clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;-------------------------------------------------------------------
; Подготовка к следующей предустановке и проверка состояния флага Z.
;-------------------------------------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
btfss STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto SNOVA_2 ; Если не все, то далее (текущая предустановка продолжается).
; Если все, то выход из процедуры предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 20h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
bcf STATUS,RP0 ; Выбор 0-го банка.
;(“влёт” в процедуру осуществляется из 1-го банка).
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC-----------
; Рабочее действие (очистка текущей оперячейки).
;-----------------------------------------------
SNOVA_3 clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;----------------------------------------------------------------------------------------
; Подготовка к следующей предустановке и проверка состояния бита №7 указателя операдреса.
;----------------------------------------------------------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
btfss FSR,7 ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto SNOVA_3 ; Если не все, то далее (текущая предустановка продолжается).
; Если все, то выход из процедуры предустановки.

37
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, то команду
; goto START нужно заменить на команду goto <туда, куда нужно>, либо без этой команды
; (будет исполняться то, что “лежит” ниже).
;----------------------------------------------------------------------------------------------------
;....................................
;....................................
;****************************************************************************************************
end ; Конец программы.

Ещё один пример: “вышележащая” программа предустановки отображаемых регистров


общего назначения, для PIC16F628 / 628A, PIC16F876 / 876A / 877 / 877A, в которой
реализован этот вариант очистки, выглядит так (результаты работы этих вариантов программ
одинаковы):
Для PIC16F628 / 628A,
PIC16F876 / 876A / 877 / 877A
Работа с массивом регистров общего назначения 0-го банка. Группа регистров
общего назначения с адресами 70h … 7Fh отображается в остальных банках.
;***************************************************************************************************
; Программа, позволяющая последовательно проверить (в симуляторе) работу двух вариантов
; предустановки, в ячейках заданного “сектора” оперпамяти, заданных числовых значений.
; Сначала, в декрементном порядке, производится предустановка чисел от 0Fh (в ячейке с адресом 70h),
; до 00h (в ячейке с адресом 7Fh) а затем производится очистка этих предустановок.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;--------------------------------------------------------------------------------------
; В данном случае (обращения не к названиям регистров, а к их адресам), можно обойтись
; без их “прописки” (контроль предустановок осуществляется в окне File Registers).
; После инициализации ПИКа, по умолчанию, установлен 0-й банк.
;--------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка регистров общего назначения 0-го банка, от ячейки с адресом 70h и до ячейки с адресом
; 7Fh, чисел, которые отличны от 0 (за исключением оперячейки с адресом 7Fh. В ней 0 выставляется по
; факту окончания потоковой предустановки).
; Так как, в данном случае, области оперпамяти с адресами 70h...7Fh (0-й банк), F0h...FFh, (1-й
; банк), 170h...17Fh (2-й банк), 1F0h...1FFh (3-й банк) являются отображаемыми, то они
; предустанавливаются одинаково (в оперячееках с адресами 7Fh, FFh, 17Fh, 1FFh ноли выставляется
; по факту окончания потоковой предустановки).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
START movlw 70h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 70h (см. соответствующую карту оперпамяти).
movlw .15 ; (.15=0Fh) В счётчик проходов (адрес ячейки 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 ; Переход на начало следующей предустановки.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка, в оперячейках (от ячейки с адресом 70h и до ячейки с адресом 7Fh), нолей.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
38
; Подготовительные операции.
;------------------------------------
VIHOD movlw 70h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 70h (см. соответствующую карту оперпамяти).
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC-----------
; Рабочее действие (очистка текущей оперячейки).
;-----------------------------------------------
SNOVA_1 clrf INDF ; В текущей ячейке оперпамяти предустанавливается ноль
; (сброс INDF означает сброс текущей ячейки оперпамяти).
;----------------------------------------------------------------------------------------
; Подготовка к следующей предустановке и проверка состояния бита №7 указателя операдреса.
;----------------------------------------------------------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
btfss FSR,7 ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto SNOVA_1 ; Если не все, то далее (текущая предустановка продолжается).
; Если все, то выход из процедуры предустановки.
goto START ; Если все, то переход на начало <- ТОЧКА ОСТАНОВКИ №2
; программы (по-новой).
; Если не все, то далее (текущая предустановка продолжается).
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, программа “зациклена” на своё начало (последовательное повторение
; предустановок), но если, по окончании предустановок, нужно выйти, из этой процедуры, то команду
; goto START нужно заменить на команду goto <туда, куда нужно>, либо без этой команды
; (будет исполняться то, что “лежит” ниже).
;----------------------------------------------------------------------------------------------------
;....................................
;....................................
;****************************************************************************************************
end ; Конец программы.

Применение косвенной адресации при работе с таблицами данных

Общие положения

Таблица данных это массив данных (несколько позиций/строк. В форме нескольких байтов),
который, с целью осуществления задуманного конструктором действия,
подлежит дальнейшему, последовательному считыванию (в том числе и с последующим
осуществлением модификации считанного, а также и прочих действий. Это зависит от конкретной задумки) .
То есть, “проведена аналогия” с тем, что всем привычно (с некой таблицей “того-сего”).
Естественно, что в приложении к нашему делу, имеется “табличная специфика”.
Оптимальная (с точки зрения простоты “эксплуатации” и т.д.) таблица данных является, если так
можно выразиться, “адреснолинейной” (а не “адресно-кусочно-рваной”).
В том смысле, что в “адреснолинейной” таблице, числовые значения адресов любой
пары соседних строк таблицы отличаются на единицу.
Если массив данных представляет собой “набор” N-количества “адреснолинейных”
таблиц, разделённых “адресно-кусочно-рваностью”, то целесообразно программно
разделить этот массив на N “адреснолинейных” таблиц и отрабатывать их
последовательно (естественно, при условии осуществления соответствующих, “влётных”, адресных коррекций).
Мотивация: в “адреснолинейном” случае, можно применить такую “компактную
красатульку”, как косвенная адресация (вплоть до иных, табличных “спецприбамбасов”. Это о ПИКах 18-й
серии и выше).
Прежде чем считать массив данных, нужно обеспечить его наличие, а иначе нечего
будет считывать/модифицировать/записывать.
То, о чём ранее шла речь, это один из способов создания массивов данных (таблиц),
подлежащих дальнейшей обработке.
А именно, в “вышележащих” случаях, речь шла только о записях, причём, только в
область оперпамяти, но ведь кроме неё есть ещё и EEPROM-память данных,
и Flash-память программ.
Туда тоже можно записать массив/массивы данных (а затем считать и т.д.).
Нет проблем, но при одном обязательном условии: нужно знать, как именно это
осуществить.
А пока продолжаю работать по последовательному, плановому, “удавному” принципу,
а заодно и ещё раз напоминаю о том, что массив/массивы данных (то есть, содержимое
таблицы/таблиц) можно записать (а соответственно и считать):
39
 в область оперпамяти,
 в EEPROM-память данных,
 во Flash-память программ.
Проще говоря, таблицу/таблицы можно создать как в любом из этих “мест”, так и в
комплексе.
Работаем дальше. Пока, с “привязкой” к оперпамяти.

Копирование массива данных, из одного “сектора” оперпамяти, в другой


(“чтение-модификация-запись”), с использованием косвенной адресации

Сразу обращаю Ваше внимание на то, что массив данных копируется, из одного
“сектора” оперпамяти, в другой, не “оптом”, а строго последовательно, начиная от 1-й
строки таблицы (1-го байта), и заканчивая последней (в итоге à тот же самый “опт”).
Один из вариантов подобного рода “свистопляски” выглядит так (“мал золотник, да дорог”!):

Для PIC16F628 / 628A,


PIC16F876 / 876A / 877 / 877A
Вариант программной процедуры копирования массива оперданных в заданный
“сектор” оперпамяти.
;***************************************************************************************************
; Программа, позволяющая последовательно отследить (в симуляторе) процесс отработки процедуры
; “чтение-модификация-запись”, в приложении к копированию содержимого массива оперданных (таблицы
; данных), из одного “сектора” оперпамяти, в другой.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;----------------------------------------
cblock 70h ; Назначение адреса первого регистра блока
; (в данном случае, содержимое оперячеек с адресами 70h..7Fh
; отображается во всех банках).
Count ; Счётчик проходов.
Reg ; Регистр хранения содержимого считанных оперданных.
endc ; Конец блока.
;------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************

; СНАЧАЛА СОЗДАЁМ ТАБЛИЦУ, СОДЕРЖИМОЕ КОТОРОЙ ПОДЛЕЖИТ ДАЛЬНЕЙШЕЙ ОБРАБОТКЕ.


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка регистров общего назначения 0-го банка, от ячейки с адресом 20h и до ячейки с адресом
; 2Fh (это 16 оперячеек), числами, которые отличны от 0.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .16 ; (.16=10h) В счётчик проходов (в “шапке” программы, ему
movwf Count ; присвоено название Count) записывается количество оперячеек,
; содержимое которых подлежит предустановке.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf Count,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №1
; процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf Count,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.

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 ; Конец программы.

Надеюсь на то, что, “врубившись” в предыдущие “разборки”, Вы поняли суть


“механизма” работы с регистрами общего назначения, в случаях применения которого,
“шапкопрописка” регистров общего назначения не обязательна, но в большинстве
случаев, программа не ограничивается только подобного рода программными
процедурами, и в ней есть другие процедуры, что связано с “шапкопропиской” тех
регистров общего назначения, которые в них задействуются.
И в самом деле, во многих случаях более удобно/комфортно обратиться к названию
регистра, а не к его операдресу (результат обращения одинаков), и если регистры
“шапкопрописаны”, то удобнее обращаться не к их адресам, а к тем названиям,
которые им присвоены.
В “вышележащей” программе, “шапкопрописаны” 2 регистра общего назначения, причём,
в отображаемой области оперпамяти.
То есть, с этими регистрами можно работать во всех банках, не “заморачиваясь”
переключениями банков (это относится только к работе с отображаемыми ячейками оперпамяти, и не более
того!!! А заодно и напоминаю о прямой адресации).
Та процедура, команды которой выделены тёмно-красным цветом, это привычная
(так как сие многократно использовалось выше), вспомогательная процедура предустановки массива
данных (суть à формирование таблицы данных).
В рассматриваемом случае, массив данных записывается в 16 оперячеек 0-го банка.
Так как регистр счётчика проходов (Count) не “дислоцируется” в последней оперячейке
массива (как ранее. В данном случае, он “прописан” в отображаемой области оперпамяти), то константа .15
заменена на константу .16 (а иначе последняя оперячейка массива не предустановится).
После окончания предустановки, начинается первый внутренний цикл типа
“чтение-модификация-запись” (ну очень уж распространённое “явление”. Дружески советую вникнуть в
“сермяжную” суть. Пригодится на все сто), которых (циклов), в данном случае, 16 штук (количество
циклов задаётся в счётчике проходов Count).
“Внутри” любого из этих циклов, последовательность работы такая:
 в регистр Reg, с применением косвенной адресации, считывается содержимое
одной из ранее предустановленных оперячеек 0-го банка (“чтение-модификация-запись”),
 далее, к содержимому любого из считанных байтов, приплюсовывается единица
(Reg + 1 = … Это простейшая модификация à “чтение-модификация-запись”).

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 “прописаны” в отображаемой (на все банки) области оперпамяти.

Если заменить команду bsf FSR,7 на команду bsf STATUS,RP0, то в приложении к


косвенной адресации (см. то, что следует после этой команды), смены банка не произойдёт, а
произойдёт “банковский конфуз” (можете проверить в симуляторе).
По поводу “зеркалки” (она упомянута в комментариях программы).
Это “адреснозеркальные” оперячейки, “лежащие” в различных банках.
Их операдреса отличаются только на величины адресных поправок (она осуществляется
посредством корректировки значения бита №7 указателя адреса, а при необходимости, и бита IRP регистра STATUS).
В данном случае (по умолчанию, IRP = 0, и это неизменно), для того чтобы процедура косвенной
адресации работала в “границах” 1-го банка, нужно выставить, в бите №7 указателя
адреса (FSR), единицу.
“Вышележащая” программа создана под “зеркалку”, но если нужно адресно изменить
местоположение модифицированного массива оперданных, то необходимо
заблокировать команды, которые выделены красным цветом, разблокировать команды,
которые выделены зелёным цветом, задать величину адресного смещения (например,
заменить 80h на 85h или на другое, приемлемое, числовое значение) и произвести ассемблирование.

Примечание: закрытие MPLAB и последующее его открытие эквивалентно инициализации


“виртуального” ПИКа.

Копирование массива данных, из заданного “сектора” EEPROM-памяти данных,


в заданный “сектор” оперпамяти (“чтение-модификация-запись”), с
использованием косвенной адресации

“Затравка” предмета этого разговора “дислоцируется” в статье Подпрограммы EEPROM


записи/чтения.
А именно, “базис” (в приложении к PIC16F628/628A, но можно “привязаться” и к другим типам ПИКов):
PIC16F628/628A
11 ПП потоковой, адресноинкрементной EEPROM-записи (с косвенной адресацией).
41 ПП потокового, адресноинкрементного EEPROM-чтения (с косвенной адресацией).

В этой же статье имеется и программа, посвящённая чтению-модификации-записи:

66 Для N-байтов данных (адресоинкремент, косвенная адресация).

В ней, массив, состоящий из 3-х байтов, копируется, из EEPROM-памяти данных, в


отображаемую область оперпамяти.

43
А именно, в “шапкопрописанные” регистры общего назначения с названиями Reg_1,
Reg_2 и Reg_3.
Их количество можно нарастить, но во-первых, отображаемая область оперпамяти
PIC16F628/628A (в частности) не резиновая и она очень ценна (обычно в ней “прописывают
важняковые/ширпотребные” регистры), а во-вторых, если массив данных внушителен, то
“замучаешься прописывать” (условно. “Шапка” будет “массивной”).
На мой взгляд, целесообразно “состряпать” то, что имеет бОльшие возможности и
одновременно, компактность.
Особый интерес представляет копирование массива данных в неотображаемую область
оперпамяти того банка, который “нравится” (условно).
Если уж я ранее “привязался” к 1-му банку, то скопирую в него (из “сектора” EEPROM-памяти)
массив, состоящий из 16-ти байтов (можно и больше/меньше, но пусть будет такое количество).
Программная реализация этого “техзадания” выглядит так:

Для PIC16F628 / 628A


Вариант копирования массива данных, из заданного “сектора” EEPROM-памяти,
в заданный “сектор” оперпамяти.
;***************************************************************************************************
; Программа, позволяющая последовательно отследить (в симуляторе) процесс отработки процедуры
; “чтение-модификация-запись”, в приложении к копированию содержимого массива данных (таблицы
; данных), из заданного “сектора” EEPROM-памяти, в заданный “сектор” оперпамяти.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;----------------------------------------
cblock 70h ; Назначение адреса первого регистра блока
; (в данном случае, содержимое оперячеек с адресами 70h..7Fh
; отображается во всех банках).
Count ; Счётчик проходов.
Reg ; Регистр оперсохранения текущих байтов,
; считанных из EEPROM-ячеек.
endc ; Конец блока.
;----------------------------------------
; СОЗДАЁМ EEPROM-ТАБЛИЦУ, СОДЕРЖИМОЕ КОТОРОЙ ПОДЛЕЖИТ ДАЛЬНЕЙШЕЙ ОБРАБОТКЕ.
org 2100 ; На стадии "прошивки", записываем, в EEPROM-память
de 0,1,2,3,4,5,6,7,8,9 ; (начиная от ячейки с адресом 00h),
de 0A,0B,0C,0D,0E,0F ; этот массив данных.
;-------------------------------------------------------------
; Пояснение: в данном случае, таблица является 16-позиционной.
;--------------------------------------------------------------------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
; ТАБЛИЦА СОЗДАНА (теперь есть с чем работать). ПОСЛЕДОВАТЕЛЬНО СЧИТЫВАЕМ ЕЁ
; ДАННЫЕ (в регистр Reg), МОДИФИЦИРУЕМ ИХ (инкремент) И ЗАПИСЫВАЕМ РЕЗУЛЬТАТЫ
; МОДИФИКАЦИЙ В ЗАДАННЫЙ “СЕКТОР” ОПЕРПАМЯТИ 1-го БАНКА.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Последовательное чтение данных из массива EEPROM-ячеек с адресами 00h..0Fh, модификация считанного
; (инкремент), после чего осуществляется последовательное копирование (запись) модифицированных
; данных в массив оперячеек с адресами A0h..AFh (“лежат” в неотображаемой области 1-го банка).
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
movlw 0A0h ; Задание адреса первой ячейки опермассива
movwf FSR ; (в данном случае, это оперячейка с адресом A0h).
bsf STATUS,RP0 ; Так как регистры спецназначения EEADR,EECON1,EEDATA "лежат"
; в 1-м банке, то выбор 1-го банка (это для прямой адресации).
movlw 0 ; Задание адреса первой ячейки EEPROM-массива.
movwf EEADR ; (в данном случае, это EEPROM-ячейка с адресом 00h).

movlw .16 ; Задание количества


movwf Count ; позиций/строк таблицы.
;####################################################################################################
; Циклическая ПП чтения-модификации-записи.
;####################################################################################################
SNOVA btfsc STATUS,Z ; Отработаны все циклы или не все ? <- ТОЧКА ОСТАНОВКИ №1
goto $ ; Если все, то “мертвяк”. <- ТОЧКА ОСТАНОВКИ №2
; Если не все, то далее.
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, по причине применения “мертвяка”, отрабатывается один полный цикл
44
; программы, но если нужно выйти, из этой процедуры, по сценарию “программа исполняется далее”,
; то команду goto $ нужно заменить на команду goto <туда, куда нужно> (выход с 1-м банком).
;----------------------------------------------------------------------------------------------------
; ЧИТАЕМ ДАННЫЕ ИЗ EEPROM-ПАМЯТИ
; Cчитывание содержимого текущей EEPROM-ячейки в регистр Reg
; (суть: оперсохранение считанных данных, с целью осуществления их дальнейшей модификации).
;------------------------------------------------------------------------------------------
bsf EECON1,RD ; Разрешение чтения.
movf EEDATA,W ; EEDATA -> W
movwf Reg ; W -> Reg
;--------------------------------------------------------------------------
; МОДИФИЦИРУЕМ СЧИТАННОЕ
; Модификация (в данном случае, очень простая. Она может быть и посложнее).
;--------------------------------------------------------------------------
incf Reg,F ; Reg + 1 = ... (результат -> Reg)
;-------------------------------------------------------------------------------------------
; ЗАПИСЫВАЕМ РЕЗУЛЬТАТ МОДИФИКАЦИИ В ОПЕРПАМЯТЬ
; Запись ранее считанного (из EEPROM-ячейки) числа, в соответствующую оперячейку 1-го банка.
;-------------------------------------------------------------------------------------------
movf Reg,W ; Ранее модифицированное, через W,
movwf INDF ; записывается в текущую оперячейку 1-го банка.
;---------------------------------------------------------------------------------
; Подготовка к следующему циклу чтения-модификации-записи и переход на его начало.
;---------------------------------------------------------------------------------
incf EEADR,F ; Адресноинкрементный выбор следующей EEPROM-ячейки.
incf FSR,F ; Адресноинкрементный выбор следующей оперячейки.
decf Count,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA ; Переход на начало следующего цикла.
;****************************************************************************************************
end ; Конец программы.

Как видите, программа достаточно компактна.


За счёт того, что EEPROM-таблица создана на стадии “прошивки” (см. концовку “шапки”
программы), а не программно (см. программу с номером 11 статьи Подпрограммы EEPROM записи/чтения).
Желающие “потренироваться” могут создать EEPROM-таблицу программно (советую. Дело
полезное).
Компактность достигается также и по причине отсутствия “прыжков”, из неотображаемой
области оперпамяти одного банка, в неотображаемую область оперпамяти другого
банка (и наоборот. В приложении к косвенной адресации).
То есть, состояние бита №7 указателя адреса (FSR) корректировать не нужно.
Обратите внимание на это:
org 2100 ; На стадии "прошивки", записываем, в EEPROM-память
de 0,1,2,3,4,5,6,7,8,9 ; (начиная от ячейки с адресом 00h),
de 0A,0B,0C,0D,0E,0F ; этот массив данных.
Увеличив значение 2100, можно изменить местоположение EEPROM-таблицы.
Например, если “настукать” 2105, то EEPROM-таблица начнётся не от ячейки с
адресом 00h, а от ячейки с адресом 05h.
Соответственно, в тексте программы, нужно скорректировать начальный EEPROM-адрес
(заменить 0 на 5).
Обратите внимание на то, что числа указаны без атрибутов систем счисления.
Можно и так (один из возможных вариантов). Это не ошибка.
В этом случае, MPLAB “автовоспринимает” их как шестнадцатеричные числа.
В тексте программы, шестнадцатеричные числа не должны начинаться с буквы.
Это ошибка.
Если это так (MPLAB укажет), то слева нужно “прислонить” ноль (например, 0A5, 0FA и т.п.).
Также обратите внимание на счётчик проходов.
Так как речь идёт о работе в двух “епархиях”, то на первый взгляд, нужно применить
2 счётчика проходов.
Можно и так, но зачем, ведь если хорошо подумать, то можно обойтись одним,
универсальным (это что-то типа “2 в одном флаконе”), что и имеет место быть.
И это удобно/комфортно, так как количество проходов задаётся одной цифрой (для обеих
“епархий”), плюс, командноскоростной выигрыш (при прочих, равных условиях).

45
Копирование массива данных, из заданного “сектора” оперпамяти, в заданный
“сектор” EEPROM-памяти данных (“чтение-модификация-запись”),
с использованием косвенной адресации

То есть, изменяем направление “перекачки данных” на противоположное (оперпамять à EEPROM):

Для PIC16F628 / 628A


Вариант программной процедуры копирования массива оперданных в заданный
“сектор” EEPROM-памяти.
;***************************************************************************************************
; Программа, позволяющая последовательно отследить (в симуляторе) процесс отработки процедуры
; “чтение-модификация-запись”, в приложении к копированию содержимого массива оперданных (таблицы
; данных), в заданный “сектор” EEPROM-памяти.
;***************************************************************************************************
LIST p=16f628A ; Используется PIC16F628A.
#include <p16f628a.inc>; Подключение INC-файла PIC16F628A.
errorlevel 2 ; Блокировка вывода сообщений, предупреждений
; (вывод только ошибок).
__CONFIG 03F21H ; Защита выключена, WDT выключен, XT-генератор.
;----------------------------------------
; "Прописка" регистров общего назначения.
;----------------------------------------
cblock 70h ; Назначение адреса первого регистра блока
; (в данном случае, содержимое оперячеек с адресами 70h..7Fh
; отображается во всех банках).
Count ; Счётчик проходов.
Reg ; Регистр оперсохранения текущих байтов,
; считанных из оперячеек.
endc ; Конец блока.
;------------------------------------
org 0 ; Выполнение программы начинается c 0-го PC-адреса.
;***********************************************************************************************
; СОЗДАЁМ ОПЕРТАБЛИЦУ, СОДЕРЖИМОЕ КОТОРОЙ ПОДЛЕЖИТ ДАЛЬНЕЙШЕЙ ОБРАБОТКЕ.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Предустановка регистров общего назначения 0-го банка, от ячейки с адресом 20h и до ячейки с адресом
; 2Fh (это 16 оперячеек), числами, которые отличны от 0.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
movlw 20h ; Потоковая запись чисел начинается от оперячейки
movwf FSR ; с адресом 20h (см. соответствующую карту оперпамяти).
movlw .16 ; (.16=10h) В счётчик проходов (в “шапке” программы, ему
movwf Count ; присвоено название Count) записывается количество оперячеек,
; содержимое которых подлежит предустановке.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая ПП предустановки.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SNOVA movf Count,W ; Так как в случае ненулевого результата декремента счётчика
; проходов, в дальнейшем, задействуется не счётчик проходов,
; а аккумулятор, то содержимое счётчика проходов копируется в W
; (команда movf воздействует на флаг Z).
btfsc STATUS,Z ; Отработаны все проходы или не все ?
; (Иными словами, предустановка закончена или нет ?)
goto VIHOD ; Если все, то выход из <- ТОЧКА ОСТАНОВКИ №1
; процедуры предустановки.
; Если не все, то далее (текущая предустановка продолжается).
;------------------------------------
; Рабочее действие.
;------------------------------------
movwf INDF ; В текущую оперячейку записывается значение счётчика проходов.
;------------------------------------
incf FSR,F ; Адресный выбор следующей оперячейки.
decf Count,F ; - 1 из счётчика проходов.
goto SNOVA ; Переход на начало следующей предустановки.
; ТАБЛИЦА СОЗДАНА (теперь есть с чем работать). ПОСЛЕДОВАТЕЛЬНО СЧИТЫВАЕМ ЕЁ
; ДАННЫЕ (в регистр Reg), МОДИФИЦИРУЕМ ИХ (инкремент) И ЗАПИСЫВАЕМ РЕЗУЛЬТАТЫ
; МОДИФИКАЦИЙ В ЗАДАННЫЙ “СЕКТОР” EEPROM-памяти.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Последовательное чтение данных из массива оперячеек с адресами 20h..2Fh, модификация считанного
; (инкремент), после чего осуществляется последовательное копирование (запись) модифицированных
; данных в массив EEPROM-ячеек с адресами 00h..0Fh.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Подготовительные операции.
;------------------------------------
VIHOD movlw 20h ; Потоковое чтение ранее записанного начинается
movwf FSR ; от оперячейки с адресом 20h.
bsf STATUS,RP0 ; Так как регистры спецназначения EEADR,EEDATA,EECON1,EECON2

46
; "лежат" в 1-м банке, то выбор 1-го банка.
movlw 0 ; Задание адреса первой ячейки EEPROM-массива
movwf EEADR ; (в данном случае, это EEPROM-ячейка с адресом 00h).

movlw .16 ; Задание количества


movwf Count ; позиций/строк таблицы.

bcf STATUS,Z ; Так как “влёт” в “нижележащую” проверку осуществляется с


; поднятым флагом Z (команды movlw и movwf не воздействуют на
; флаг Z), что блокирует исполнение “нижележащей” процедуры,
; то флаг Z опускается.
;####################################################################################################
; Циклическая ПП чтения-модификации-записи.
;####################################################################################################
SNOVA_1 btfsc STATUS,Z ; Отработаны все проходы или не все ?
goto $ ; Если все, то “мертвяк”. <- ТОЧКА ОСТАНОВКИ №2
; Если не все, то далее.
;----------------------------------------------------------------------------------------------------
; Примечание: в данном случае, по причине применения “мертвяка”, отрабатывается один полный цикл
; программы, но если нужно выйти, из этой процедуры, по сценарию “программа исполняется далее”,
; то команду goto $ нужно заменить на команду goto <туда, куда нужно> (выход с 1-м банком).
;----------------------------------------------------------------------------------------------------
; ЧИТАЕМ ДАННЫЕ ИЗ ОПЕРПАМЯТИ
; Cчитывание содержимого текущей оперячейки в регистр Reg
; (суть: оперсохранение считанных данных, с целью осуществления их дальнейшей модификации).
;------------------------------------------------------------------------------------------
movf INDF,W ; Содержимое текущей оперячейки копируется в W
movwf Reg ; W -> Reg
;--------------------------------------------------------------------------
; МОДИФИЦИРУЕМ СЧИТАННОЕ
; Модификация (в данном случае, очень простая. Она может быть и посложнее).
;--------------------------------------------------------------------------
incf Reg,F ; Reg + 1 = ... (результат -> Reg)
;------------------------------------------------------
; ЗАПИСЫВАЕМ РЕЗУЛЬТАТ МОДИФИКАЦИИ В EEPROM
; Запись байта в текущую EEPROM-ячейку.
;------------------------------------------------------
movf Reg,W ; Ранее модифицированное, через W,
movwf EEDATA ; записывается в EEDATA.
bsf EECON1,WREN ; "Глобальное" разрешение записи.

movlw 55h ; Обязательная


movwf EECON2 ; последовательность
movlw 0AAh ; команд.
movwf EECON2 ; ----“----
;------------------------------------
; Процедура записи.
;------------------------------------
bsf EECON1,WR ; "Запуск в работу" аппаратной процедуры записи.
;------------------------------------------------------------------
; Пояснение: по окончании записи, бит WR аппаратно сбрасывается в 0
; (блокировка "запуска в работу" аппаратной процедуры записи).
;------------------------------------------------------------------
btfsc EECON1,WR ; Запись завершена или нет?
goto $-1 ; Если не завершена, то проверка производится снова.
; Если завершена, то выход из "плавающей" задержки.
;---------------------------------------------------------------------------------
; Подготовка к следующему циклу чтения-модификации-записи и переход на его начало.
;---------------------------------------------------------------------------------
incf EEADR,F ; Адресноинкрементный выбор следующей EEPROM-ячейки.
incf FSR,F ; Адресноинкрементный выбор следующей оперячейки.
decf Count,F ; - 1 из счётчика проходов (команда decf воздействует на флаг Z).
goto SNOVA_1 ; Переход на начало следующего цикла.
;****************************************************************************************************
end ; Конец программы.

Возможны дополнения и корректировки.

Текущая работа 2011 года        http://ikarab.narod.ru         E-mail: karabea@lipetsk.ru

47

Вам также может понравиться