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

2-1/14.

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


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

Начну с того, что в принципе, все просто:

В простейшем случае (см. рис. 1), "закольцовка" также простейшая.


А если подсчет чего-либо происходит достаточно медленно, и за счет этого
достигается приемлемая (по времени) цикличность, то и задержка не нужна.
Главная задача заключается в том, чтобы знать и уметь реализовывать на практике
"вышележащие, базовые словосочетания".
Заверяю Вас, что приобретение подобного рода знаний и умений вовсе не является
мечтой о полете в космос.
Можно сообразить и еще что-нибудь "покруче", но пока достаточно и рис. 2.
Программа называется 12864_15.asm (прилагается).
На мой взгляд, именно в таком виде и нужно "ваять" "материнскую" программу.
"Расшифровка".
Если призвать на помощь элементарный здравый смысл, то он Вам скажет
следующее: "Сначала нужно сваять коровомычащую мать (чтобы было чему
мычать), а только после этого домагаться от нее несусветной красоты и
ляпоты".
Делюсь жизненным опытом: кто этого не понимает, тому будет не "мать",
а "мать-перемать".
Согласитесь со мной, что между этими понятиями есть очень существенная разница.
Примечание: Вы уж извините меня, грешника, за такие словосочетания. Как говорится,
"все для фронта, все для победы" (упор на "прошибаемость").
По-моему, настало время дать "научное" определение словосочетанию "мычание
коровы" (извиняюсь за недосмотр. Мое упущение).
"Мычание коровы" есть самый райский из всех райских звуков, в части
касающейся того, что вожделеется. Этот звук буквально осчастливливает
(обратите внимание на отсутствие кавычек).
Все серьезные и "крутые" дела начинаются именно с "мычания коровы", и им
же заканчиваются (в случае успеха).
Нужно только уметь добиться того, чтобы в конце различных этапов работы
(желательно плановых), "корова замычала".
А чтобы это имело место быть, нужно и встать пораньше, и на лужок ее вывести, и
за сиськи, с умом, подергать, и т.д. (см. трудовые будни животноводов).
По-другому не получится (см. надпись сценария №2).
1
Вернее, получится, но не то, что нужно: коровы, если их "раздраконить", лягаться и
бодаться умеют (кстати, тяжелая весовая категория).
В связи с этим, в части касающейся графических модулей, имеет место быть некий
психологический барьер.
Шутка-ли, как-никак, а по скромному, объем программы 12864_15.asm составляет 2176
слов в памяти программ.
А может быть и больше.
Вопрос: "Как уложить на лопатки этого программного монстра"?
Ответ: нужно вспомнить о Хрущевском принципе "крупнопанельного домостроения".
Сначала - упор на общую стратегию, а потом, "тихим сапом" (коварно), осуществляется
поэтапное "просачивание" в детали (в тактику).
То есть, изначально, нужно "сваять коровомычащую мать", а только после этого, ее
"расширять и углублять" ("мухи отдельно, котлеты отдельно").
Требования к "коровомычащей матери" просты: программа должна работать в "железе"
так, как задумано.
При этом, она, вероятнее всего, будет далека от совершенства (чем сложнее
программа, тем вероятнее), но в дальнейшем, этот дефект можно будет, спокойно и в
рабочем порядке (при "наличии отсутствия" лени), исправить.
На начальном же этапе работы, важно то, чтобы программа, "худо-бедно", но работала
(в соответствии с задуманным) и самое главное, была бы понятна.
Вывод: в части касающейся графических модулей, "коровомычащая мать"
должна быть составлена под "сплошное" заполнение дисплея байтами данных.
В этом случае, программа получается, хотя и не "реактивной", но наиболее простой
для понимания.
Работа по "ваянию" любой программы должна начинаться с определения ее стратегии
(азбука).
То есть, речь идет о составлении блок-схемы программы.
Это можно сделать различными способами.
Вот один из них (для разнообразия):

;********************************************************************************
; 12864_15.asm Учебное устройство, осуществляющее "подсчет" (имитация)
; количества "размножающихся" попугаев. Результат подсчета
; выводится на индикацию в графический модуль MT-12864...
; (вариант "сплошного" заполнения)
;********************************************************************************
....................................
;================================================================================
org 0 ; Начать выполнение программы с 0 адреса PC.
goto START ; Переход в ПП START.
;********************************************************************************

==================================="ОБСЛУГА"=====================================
;================================================================================
; Подпрограмма выбора символов цифр.
;================================================================================
....................................
;================================================================================
; Подпрограммы выбора страниц (1...8) кристалла.
;================================================================================
....................................
;================================================================================
; Подпрограмма записи данных.
;================================================================================
....................................
;================================================================================
; Подпрограмма чтения данных.
;================================================================================
....................................
;================================================================================
; Подпрограмма стробирования.
2
;================================================================================
....................................
;================================================================================
; Подпрограмма установки первого (самого левого) столбца страницы (адрес 00h).
;================================================================================
....................................
;================================================================================
; ПП задержки (около 2 сек.)
;================================================================================
....................................
;============================== КОНЕЦ "ОБСЛУГИ" =================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START .............................
;================================================================================
; Инициализация графического модуля.
;================================================================================
....................................
;================================================================================

;################################################################################
; Вывод на индикацию картинки 1-го "кадра".
;################################################################################
....................................
;################################################################################

;################################################################################
; Вывод на индикацию картинки 1-го и 2-го сценариев (циклическая ПП SNOVA).
;################################################################################
; Сценарий №1: "Берегите природу - мать Вашу"!
;################################################################################
SNOVA .............................
;================================================================================
; Задержка, определяющая время визуальной фиксации надписи сценария №1.
;================================================================================
....................................

;################################################################################
; Сценарий №2: "Кто не работает, тот лапу сосёт"
;################################################################################
....................................
;================================================================================
; Задержка, определяющая время визуальной фиксации надписи сценария №2.
;================================================================================
....................................

;################################################################################
; А теперь можно "замерить" текущее количество попугаев.
;################################################################################
ЗДЕСЬ МОЖНО РАБОТАТЬ НЕ ТОЛЬКО С ПОПУГАЯМИ, НО И СО "ЗМЕЙ ГОРЫНЫЧАМИ", "ШТУКАМИ",
"ГЕРЦАМИ", "ВОЛЬТАМИ", "СЕКУНДАМИ" И ПРОЧЕЙ "РАЗНОКАЛИБЕРНОЙ БРАТИЕЙ" (это уж
кому что в голову взбредет)
;################################################################################
call BIN2_10 ; Переход в ПП BIN2/10.
;---> Возврат по стеку из ПП BIN2_10

3
;################################################################################
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;################################################################################
....................................
;################################################################################
; Далее - "на колу мочало" ("закольцовка").
;================================================================================
goto SNOVA ; Переход на следующий цикл программы.
;================================================================================

==================================="ОБСЛУГА"=====================================
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр (0...9).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Таблицы данных 1-го "кадра".
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
....................................
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Таблицы данных сценария №1: "Берегите природу - мать Вашу"!
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
....................................
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Таблицы данных сценария №2: "Кто не работает, тот лапу сосет"
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
....................................
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;============================== КОНЕЦ "ОБСЛУГИ" =================================

;********************************************************************************
; Подпрограмма двоично-десятичного преобразования.
;********************************************************************************
BIN2_10.............................
;********************************************************************************
end ; Конец программы.

Черным цветом выделено то, о чем шла речь в предыдущих подразделах.


Темно-синим цветом выделено то, что относится к работе с картинкой 1-го "кадра".
Зеленым цветом выделено то, что относится к работе с картинками 1-го и 2-го
сценариев.
Синим цветом выделено то "место", в котором замеряется количество чего-либо.
Красным цветом выделено то, что относится к выводу на индикацию результатов
замера чего-либо.
Фиолетовым цветом выделена ПП 2/10 преобразования.
Цветом хаки выделены комментарии.

Упорно акцентирую Ваше внимание на том, что умение отличить "важняка"


от его "обслуги", есть исключительно ценное умение, а заодно и основа
стратегического "порядка в мозгах".
В данном случае, "ОБСЛУГОЙ" названны те ПП, переход в которые происходит с
задействованием стека (call …).

4
Для того чтобы "обслуга нагло не покушалась на статус важняка" (а ей только волю
дай …), она "безжалостно, с помощью кнута, согнана в 2 стада" (а можно и в одно.
На любителя).
Чуть что - "щелчок кнутом", и строптивости как не бывало ("статус-кво восстановлен").
Можно "раскидать" как-то и по другому (имеются ввиду "ОБСЛУГА" и ПП BIN2_10), но
это уже Ваше личное дело (только не забывайте про Message[306]).
Я "раскидал" так, как имеет место быть.
По существу, это то же самое, что изображено на рис. 2, но только более
детализированное и "адаптированное" к тексту конкретной программы.
Конечно же, многие детали осталось "за кадром" (это естественно), но стратегия
программы выражена вполне "членораздельно" и "ненадрывнопупковопонимаемо".
На начальном этапе "вгрызания", с этим нужно хорошенько разобраться (напоминаю
про Матросова).
После того, как Вы услышите отчетливый и конкретный звук "Му" (критерий успешности
работы), можно двигаться дальше.
То есть, в направлении детализации "спектральных составляющих" этого звука:

;********************************************************************************
; 12864_15.asm Учебное устройство, осуществляющее "подсчет" (имитация)
; количества "размножающихся" попугаев. Результат подсчета
; выводится на индикацию в графический модуль MT-12864...
; (вариант "сплошного" заполнения)
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; За основу, взяты программные наработки Милевского А.З. mazr@bk.ru
; Попугайная и прочая специфика: Корабельников Е.А.
;********************************************************************************
; Используются операторы high и low.
; Инициализация графического модуля - "штатная", с использованием флагов статуса.
;================================================================================
; Функции выводов порта С:
; RC0...RC7 - выводы данных.
; Функции выводов порта В:
; RB0 - Е2 ; управление правым (2-м) кристаллом,
; RB1 - Е1 ; управление левым (1-м) кристаллом,
; RB2 - E ; на этом выводе формируются стробирующие импульсы,
; RB3 - A0 ; управление режимами "данные/команды",
; RB7 - R/W ; управление режимами "чтение/запись",
; RB4 - RES ; внешний сброс,
; остальные выводы порта В не задействованы.
; Выводы порта С не используются.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Используется PIC16F873A.
;----------------------------------------------
; Объем программы: 2176 слов в памяти программ
;================================================================================
LIST p=16F873A ; Задание типа микроконтроллера.
__CONFIG 3F71H ; Включено: XT-генератор, PWRT, сброс BOR,
; Выключено: защита, WDT, LVP, DEBUG.
;================================================================================
; Регистры специального назначения.
;================================================================================
PCLATH equ 0Ah ; Регистр PCLATH (используется при
; работе с PCH).
PCL equ 02h ; Регистр младшего байта счетчика команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.
PortB equ 06h ; Регистр защелок порта B.
PortC equ 07h ; Регистр защелок порта C.
TrisB equ 06h ; Регистр выбора направлений работы

5
; выводов порта B (банк 1).
TrisC equ 07h ; Регистр выбора направлений работы
; выводов порта С (банк 1).
;================================================================================
; Регистры общего назачения.
;================================================================================
Temp equ 20h ; Регистр количества проходов.
Reg equ 21h ; Регистр выбора сценария вычисляемого
; перехода (плюс, используется в ПП BIN2_10).
Mem1 equ 22h ; Регистры задержки, а также
Mem2 equ 23h ; и хранения результата
Mem3 equ 24h ; кольцевого сдвига.
Reg1 equ 25h ; Регистры, входящие в
Reg2 equ 26h ; состав кольцевого,
Reg3 equ 27h ; сдвигового регистра.

LED0 equ 30h ; ----"----


LED1 equ 31h ; ----"----
LED2 equ 32h ; Регистры, задействованные
LED3 equ 33h ; в ПП 2/10 преобразования.
LED4 equ 34h ; ----"----
LED5 equ 35h ; ----"----
;================================================================================
; Присвоение битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
RP0 equ 5 ; Бит выбора банка.
E2 equ 0 ; Бит выбора 2-го кристалла.
E1 equ 1 ; Бит выбора 1-го кристалла.
E equ 2 ; Бит стробирования.
A0 equ 3 ; Бит выбора режима "команды/данные".
R_W equ 7 ; Бит выбора режима "чтение/запись".
;================================================================================
org 0 ; Начать выполнение программы с 0 адреса PC.
goto START ; Переход в ПП START.
;********************************************************************************

;================================================================================
; Подпрограмма выбора символов цифр.
;================================================================================
CIFRA addwf PCL,F ; Вычисляемый переход.
goto C_0 ; Символ "0".
goto C_1 ; Символ "1".
goto C_2 ; Символ "2".
goto C_3 ; Символ "3".
goto C_4 ; Символ "4".
goto C_5 ; Символ "5".
goto C_6 ; Символ "6".
goto C_7 ; Символ "7".
goto C_8 ; Символ "8".
goto C_9 ; Символ "9".
;================================================================================
; Подпрограммы выбора страниц (1...8) кристалла.
;================================================================================
; ПП установки адреса 1-й страницы.
;------------------------------------
STRANICA_1 movlw b'10111000' ; Выбор адреса 1-й страницы.
movwf PortC ; Вывод команды выбора адреса страницы
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB ;
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;------------------------------------
; ПП установки адреса 2-й страницы.
6
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 3-й страницы.
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 4-й страницы.
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 5-й страницы.
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 6-й страницы.
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 7-й страницы.
;------------------------------------
АНАЛОГИЧНО
;------------------------------------
; ПП установки адреса 8-й страницы.
;------------------------------------
АНАЛОГИЧНО
;================================================================================
; Подпрограмма записи данных.
;================================================================================
WRITE_D bsf PortB,A0 ; Обеспечение условия работы
; с байтами данных (1).
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
bcf PortB,A0 ; Обеспечения условия работы с командами (0).
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; Подпрограмма чтения данных.
;================================================================================
READ_D call STROB ; Строб (инициализация чтения).
;---> Возврат по стеку из ПП STROB
movf PortC,W ; Копирование считанного байта данных в W.
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; Подпрограмма стробирования.
;================================================================================
STROB bsf PortB,E ; Формирование
bcf PortB,E ; стробирующего импульса.
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; Подпрограмма установки первого (самого левого) столбца страницы (адрес 00h).
;================================================================================
STOLB_1 movlw b'01000000' ; Выбор адреса 1-го столбца (00h).
movwf PortC ; Вывод команды выбора адреса столбца
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; ЗАДЕРЖКА (около 2 сек.)
;================================================================================
PAUSE movlw .93 ;
movwf Mem1 ;
7
movlw .38 ;
movwf Mem2 ;
movlw .11 ;
movwf Mem3 ;

decfsz Mem1,F ; Стандартный


goto $-1 ; 3-байтный
decfsz Mem2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Mem3,F ;
goto $-5 ;

return ; Возврат по стеку в то место, откуда


; произошел вызов подпрограммы.
;================================================================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы портов В и С
clrf TrisC ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.

movlw .1 ; "Закладка" единицы в младший бит


movwf Reg1 ; младшего байта 3-байтного кольцевого
clrf Reg2 ; регистра Reg3 (H)/Reg2 (M)/Reg1 (L)
clrf Reg3 ; (в остальных битах - нули).

bsf PortB,4 ; Подготовка к сбросу графического модуля.

bcf PortB,A0 ; Подготовка к исполнению команд.


bsf PortB,E1 ; Включение обеих
bsf PortB,E2 ; кристаллов.
;================================================================================
; Инициализация графического модуля.
;================================================================================
; Сброс графического модуля.
;-----------------------------------------
bcf PortB,4 ; Формирование импульса длительностью более
nop ; 1 мкс. По спаду импульса, выполняются
bsf PortB,4 ; инструкции "Display OFF" и "Display
; StartLine" (назначается адрес 1-й строки).
movlw b'00111111' ; Инструкция "Display ON"
movwf PortC ; (включение дисплея).
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;-----------------------------------------
; Подготовка к чтению статуса состояния.
;-----------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'11111111' ; Все выводы порта С
movwf TrisC ; работают на вход.
bcf Status,RP0 ; Переход в 0-й банк.

bsf PortB,R_W ; Установка режима чтения (R/W=1).


NO_INIT call STROB ; Строб ("запуск в работу" инструкции
; "Status Read").
;---> Возврат по стеку из ПП STROB
;----------------------------------------------
; Анализ состояний флагов BUSY и RESET.
;----------------------------------------------
nop ; "Перестраховочная" задержка в 1 м.ц.
8
btfsc PortC,7 ; Флаг BUSY поднят (1) или опущен (0) ?
goto NO_INIT ; Если BUSY=1 (модуль не готов к работе с
; М/К),то состояние BUSY опрашивается еще раз
; Если BUSY=0 (модуль готов к работе с М/К),
; то переход на анализ состояния флага RESET.
btfsc PortC,4 ; Флаг RESET поднят (1) или опущен (0) ?
goto START ; Если RESET=1 (сброс не было), то переход
; на начало исполнения программы.
; Если RESET=0 (сброс был), то программа
; исполняется далее.
;-----------------------------------------
; Подготовка к работе в режиме записи.
;-----------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisC ; Все выводы порта С работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
bcf PortB,R_W ; Установка режима записи (R/W=0).
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB

;################################################################################
; Вывод на индикацию картинки 1-го "кадра".
;################################################################################
; Включение 2-го кристалла.
;*************************************
bcf PortB,E1 ; Выключение 1-го кристалла.
;--------------------------------------------------------------------------------
; Запись в 1-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
; Подготовительные операции.
;--------------------------------------
call STRANICA_1 ; Выбор 1-й страницы.
call STOLB_1 ; Выбор 1-го столбца страницы.
movlw .64 ; Назначение
movwf Temp ; числа проходов.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Циклическая ПП заполнения байтами данных столбцов страницы.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
WR_1 movf Temp,W ; Число проходов --> в W.
sublw .64 ; .64 - Temp = ... (результат --> в W).
movwf Reg ; В регистр Reg записывается номер текущего
; сценария вычисляемого перехода.
;-------------------------------------
; Отработка ПП, в состав которой
; входит вычисляемый переход.
;-------------------------------------
call TEXT_1 ; Переход в ПП TEXT_1.
;---> Возврат по стеку из ПП TEXT_1
;-------------------------------------
; Вывод на индикацию текущего байта
; данных ("лежит" в W).
;-------------------------------------
movwf PortC ; Установка на линиях DB7...DB0 числового
; значения текущего байта данных.
movlw high WRITE_D; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; ПП WRITE_D (через W).
call WRITE_D ; Переход в ПП WRITE_D (с предустановленным
; значением PCH).
;---> Возврат по стеку из ПП WRITE_D
decfsz Temp,F ; Число проходов уменьшается на 1.
goto WR_1 ; Если результат не=0, то переход на
; обработку следующего байта данных.
; Если =0, то запись в 1-ю страницу
; заканчивается и программа исполняется
; далее.
9
;--------------------------------------------------------------------------------
Запись во 2-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 3-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 4-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 5-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 6-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;*************************************
; Включение 1-го кристалла.
;*************************************
bsf PortB,E1 ; Включение 1-го кристалла.
bcf PortB,E2 ; Выключение 2-го кристалла.
;--------------------------------------------------------------------------------
Запись в 1-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись во 2-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 3-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 4-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 5-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
; Запись в 6-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;================================================================================

;################################################################################
; Вывод на индикацию картинки 1-го и 2-го сценариев (циклическая ПП SNOVA).
;################################################################################
; Сценарий №1: "Берегите природу - мать Вашу"!
;################################################################################
; Запись в 7-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
SNOVA call STRANICA_7 ;
call STOLB_1 ;
movlw .64 ;
movwf Temp ;

movf Temp,W ;
sublw .64 ;
movwf Reg ; То же самое, только
10
call TEXT_1_1 ; переход происходит
movwf PortC ; в ПП TEXT_1_1.
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
decfsz Temp,F ;
goto $-9 ;
;--------------------------------------------------------------------------------
; Запись в 8-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;*************************************
; Включение 2-го кристалла.
;*************************************
bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;--------------------------------------------------------------------------------
Запись в 7-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 8-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;================================================================================
; Задержка, определяющая время визуальной "фиксации" надписи сценария №1.
;================================================================================
call PAUSE ; Переход в ПП задержки.
;---> Возврат по стеку из ПП PAUSE

;################################################################################
; Сценарий №2: "Кто не работает, тот лапу сосёт"
;################################################################################
Запись в 7-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Запись в 8-ю страницу 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;*************************************
; Включение 1-го кристалла.
;*************************************
bsf PortB,E1 ; Включение 1-го кристалла.
bcf PortB,E2 ; Выключение 2-го кристалла.
;--------------------------------------------------------------------------------
; Запись в 7-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
; Запись в 8-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
call STRANICA_8 ;
call STOLB_1 ;
movlw .64 ;
movwf Temp ;

movf Temp,W ;
sublw .64 ;
movwf Reg ;
movlw high TEXT_2_4; Так как далее следует переход на 2-ю
movwf PCLATH ; страницу памяти программ ПИКа, то
; производится "плавающая" коррекция
; содержимого PCH.
call TEXT_2_4 ; То же самое, только
movwf PortC ; переход происходит
11
movlw high WRITE_D; в ПП TEXT_2_4.
movwf PCLATH ;
call WRITE_D ;
decfsz Temp,F ;
goto $-.11 ;
;================================================================================
; Задержка, определяющая время визуальной "фиксации" надписи сценария №2.
;================================================================================
call PAUSE ; Переход в ПП задержки.
;---> Возврат по стеку из ПП PAUSE

;################################################################################
; А теперь можно "замерить" текущее количество попугаев.
;################################################################################
; Сдвиг, в кольцевом регистре, единицы влево (умножение на 2).
;--------------------------------------------------------------------------------
bcf Status,C ; Сброс флага переноса-заема.
rlf Reg1,F ; Сдвиг содержимого 3-байтного
rlf Reg2,F ; регистра Reg3/Reg2/Reg1
rlf Reg3,F ; влево на один бит.
;--------------------------------------------------------------------------------
; Теперь, для обеспечения того, чтобы единица не "гибла", а "гоняла по кольцу",
; нужно переписать содержимое бита С в младший бит младшего байта.
;--------------------------------------------------------------------------------
btfsc Status,C ; Если С=1, то в Reg1,0
goto $+2 ; записывается 1.
goto $+2 ; А если С=0, то в Reg1,0
bsf Reg1,0 ; ничего не записывается (Reg1,0=0).
;--------------------------------------------------------------------------------
; Теперь нужно озаботиться сохранением результата сдвига, а иначе, начиная от
; 2-го "витка" полного цикла программы и далее, всем попугаям будет "Гитлер
; капут" (все "помрут". Птичек жалко).
;--------------------------------------------------------------------------------
movf Reg1,W ;
movwf Mem1 ;
movf Reg2,W ; Reg3/Reg2/Reg1 -> Mem3/Mem2/Mem1
movwf Mem2 ;
movf Reg3,W ;
movwf Mem3 ;
;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно стандартно перевести
; в "набор" 2/10 чисел.
;--------------------------------------------------------------------------------
movlw high BIN2_10; Это нужно потому, что ПП BIN2_10 "лежит" на
movwf PCLATH ; 2-й странице памяти программ
; (см. Message[306]).
call BIN2_10 ; Теперь можно "прыгать".
;---> Возврат по стеку из ПП BIN2_10

movlw high STRANICA_5 ; Это нужно потому, что возврат произошел


movwf PCLATH ; из 2-й страницы памяти программ, а далее-то
; работать нужно в 1-й (ориентация на ПП,
; вызываемую ближайшей командой call).

;################################################################################
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;################################################################################
; Задание "координаты", с которой начнется запись байтов данных.
;--------------------------------------------------------------------------------
call STRANICA_5 ; Выбор 5-й страницы.
movlw b'01010000' ; Выбор адреса 17-го столбца (10h).
movwf PortC ; Вывод инструкции "Set Address" в порт С.
call STROB ; Строб под инструкцию.
;---> Возврат по стеку из ПП STROB
;--------------------------------------------------------------------------------
12
; "Администраторская" группа команд.
;--------------------------------------------------------------------------------
movf LED5,W ; "Цифирь", из LED5, копируется в W,
call CIFRA ; после чего - "прыжок" в ПП CIFRA.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED4,W
call CIFRA ; Аналогично, но для LED4.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED3,W
call CIFRA ; Аналогично, но для LED3.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED2,W
call CIFRA ; Аналогично, но для LED2.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED1,W
call CIFRA ; Аналогично, но для LED1.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED0,W
call CIFRA ; Аналогично, но для LED0.
;---> Возврат по стеку из ПП CIFRA
;================================================================================
; Далее - "на колу мочало" ("закольцовка").
;================================================================================
goto SNOVA ; Переход на следующий цикл программы.
;================================================================================

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод на индикацию символа "0".
;--------------------------------------------------------------------------------
C_0 movlw .8 ; В регистр Temp записывается
movwf Temp ; число проходов.
WZ_0 movf Temp,W ; Temp -> W.
sublw .8 ; .8 - Temp = ... (результат -> в W).
movwf Reg ; W -> Reg
call Z_0 ; Переход в "знакогенератор" символа "0".
;---> Возврат по стеку из ПП Z_0
movwf PortC ; Вывод текущего байта кода символа "0"
; в PortC.
movlw high WRITE_D; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; ПП WRITE_D (через W).
call WRITE_D ; Переход в ПП записи байта данных.
;---> Возврат по стеку из ПП WRITE_D
decfsz Temp,F ; Temp - 1 = ...
goto WZ_0 ; Если результат не=0, то на индикацию
; выводится следующий байт.
return ; Если результат =0, то возврат по стеку в то
; "место", из которого произошел вызов ПП
; CIFRA (с дальнейшим переходом на обработку
; содержимого следующего LEDа).
;--------------------------------------------------------------------------------
Вывод на индикацию символа "1".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "2".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
13
;--------------------------------------------------------------------------------
Вывод на индикацию символа "3".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "4".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "5".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "6".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "7".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "8".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Вывод на индикацию символа "9".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;================================================================================

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Символ "0".
;--------------------------------------------------------------------------------
Z_0 movlw high M_0 ; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; (retlw ...) табличного перехода
; (помечена меткой M_0).
movf Reg,W ; Reg -> W

addwf PCL,F ; Вычисляемый переход.


M_0 Dt 0x00,0x00,0x7C,0xA2,0x92,0x8A,0x7C,0x00 ; Код символа "0"
;--------------------------------------------------------------------------------
Символ "1".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "2".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "3".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "4".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "5".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
14
Символ "6".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "7".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "8".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Символ "9".
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;================================================================================

;################################################################################
; ТАБЛИЦЫ ДАННЫХ 1-го "КАДРА" И СЦЕНАРИЕВ №1 и №2.
;################################################################################
; Таблицы данных 1-го "кадра".
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; КРИСТАЛЛ 2
;--------------------------------------------------------------------------------
; Данные 1-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
TEXT_1 movlw high STR_1 ; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; (retlw ...) табличного перехода
; (помечена меткой STR_1).
;--------------------------------------
; Анализ выхода или нет за пределы
; текущего блока памяти программ.
;--------------------------------------
movf Reg,W ; Номер сценария вычисляемого перехода --> W.
addlw low STR_1 ; Суммирование номера сценария и числового
; значения младшего байта адреса (в PC)
; ПП STR_1 (через W).
;---------------------------------------------
; Проверка на наличие или отсутствие переноса
; (PCH+1 или этого делать не нужно?).
;---------------------------------------------
btfsc Status,C ; Перенос был или нет?
incf PCLATH,F ; Если был, то PCLATH+1 (PCH+1=...).
movf Reg,W ; Если не был, то инкремента содержимого PCH
; не происходит и номер сценария вычисляемого
; перехода (в любом случае) копируется в W.
;--------------------------------------
; Табличный, вычисляемый переход.
;--------------------------------------
addwf PCL,F ;
STR_1 Dt 0x00,0xF8,0x90,0x90,0x60,0x00,0xF8,0x00
Dt 0x00,0x00,0xF8,0xA8,0xA8,0xA8,0x50,0x00
Dt 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00
Dt 0x00,0x00,0xC0,0x68,0x58,0x48,0xF8,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0xF8,0x20,0x20,0x20,0xF8,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
;--------------------------------------------------------------------------------
Данные 2-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 3-й страницы 2-го кристалла
15
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 4-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 5-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 6-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
; КРИСТАЛЛ 1
;--------------------------------------------------------------------------------
Данные 1-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 2-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 3-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 4-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 5-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 6-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Таблицы данных сценария №1: "Берегите природу - мать Вашу"!
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Данные 7-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 8-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 7-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 8-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Таблицы данных сценария №2: "Кто не работает, тот лапу сосет"
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Данные 7-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
16
;--------------------------------------------------------------------------------
Данные 8-й страницы 2-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 7-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;--------------------------------------------------------------------------------
Данные 8-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
АНАЛОГИЧНО
;================================================================================

;********************************************************************************
; Подпрограмма двоично-десятичного преобразования.
;********************************************************************************
BIN2_10 bcf Status,C ; Сброс флага переноса-заема.
movlw .24 ; Задание числа проходов
movwf Temp ; преобразования.
clrf LED0 ; Сброс регистра LED0.
clrf LED1 ; ------"------ LED1.
clrf LED2 ; ------"------ LED2.
;--------------------------------------------------------------------------------
; Циклический сдвиг влево, через бит С регистра Status.
;--------------------------------------------------------------------------------
LOOP_16 rlf Mem1,F ; Циклический сдвиг влево 3-байтного числа,
rlf Mem2,F ; записанного в группе регистров
rlf Mem3,F ; Mem3/Mem2/Mem1, на одну позицию влево,
; через бит С регистра Status.
rlf LED0,F ; Циклический сдвиг влево 3-байтного числа,
rlf LED1,F ; записанного в группе регистров
rlf LED2,F ; LED2/LED1/LED0, на одну позицию влево,
; через бит С регистра Status.
decfsz Temp,F ; Temp - 1 = ... (результат -> Temp).
goto adjDEC ; Если результат не=0, то переход в ПП adjDEC,
; а если =0, то программа исполняется далее.
;--------------------------------------------------------------------------------
; Порязрядное распределение полубайтов регистров LED0...2
; по младшим полубайтам регистров LED0...5.
;--------------------------------------------------------------------------------
swapf LED2,W ; Запись старшего полубайта LED2
andlw 0Fh ; в младший полубайт LED5
movwf LED5 ; -------------------------------

movfw LED2 ; Запись младшего полубайта LED2


andlw 0Fh ; в младший полубайт LED4
movwf LED4 ; -------------------------------

swapf LED1,W ; Запись старшего полубайта LED1


andlw 0Fh ; в младший полубайт LED3
movwf LED3 ; -------------------------------

movfw LED1 ; Запись младшего полубайта LED1


andlw 0Fh ; в младший полубайт LED2
movwf LED2 ; -------------------------------

swapf LED0,W ; Запись старшего полубайта LED0


andlw 0Fh ; в младший полубайт LED1
movwf LED1 ; -------------------------------

movfw LED0 ; Запись младшего полубайта LED0


andlw 0Fh ; в младший полубайт LED0
movwf LED0 ; -------------------------------

return ; Возврат по стеку в то "место", из которого


17
; вызывалась ПП BIN2_10.
;--------------------------------------------------------------------------------
; Запись в регистр FSR адресов регистров LED0...2 для
; дальнейшей косвенной адресации к ним в ПП adjBCD.
;--------------------------------------------------------------------------------
adjDEC movlw LED0 ; Запись в регистр FSR адреса регистра LED0,
movwf FSR ; с дальнейшим переходом в ПП adjBCD.
call adjBCD ;
;---> Возврат по стеку из ПП adjBCD.
movlw LED1 ; То же самое, но для регистра LED1.
movwf FSR ;
call adjBCD ;
;---> Возврат по стеку из ПП adjBCD.
movlw LED2 ; То же самое, но для регистра LED2.
movwf FSR ;
call adjBCD ;
;---> Возврат по стеку из ПП adjBCD.
goto LOOP_16 ; Переход на следующее кольцо числовых
; преобразований.
;--------------------------------------------------------------------------------
; Основные операции преобразования двоичных чисел в двоично-десятичные.
;--------------------------------------------------------------------------------
adjBCD movlw 3 ; Суммирование содержимого текущего LED с
addwf 0,W ; числом 03h, с записью результата операции,
movwf Reg ; через регистр W, в регистр Reg.

btfsc Reg,3 ; Анализ состояния бита №3 регистра Reg.


movwf 0 ; Если бит №3 = 1, то содержимое регистра Reg
; копируется в текущий LED.
movlw 30 ; Если бит №3 = 0, то содержимое текущего LED
addwf 0,W ; складывается с константой 30h, с записью
movwf Reg ; результата операции, через регистр W,
; в регистр Reg.
btfsc Reg,7 ; Анализ состояние бита №7 регистра Reg.
movwf 0 ; Если бит №7 = 1, то содержимое регистра Reg
; копируется в текущий LED.
retlw 0 ; Если бит №7 = 0, то регистр W очищается и
; происходит возврат по стеку в ПП adjDEC.
;********************************************************************************
end ; Конец программы.

"Боевая раскраска" - та же.


Обратите внимание на большое количество слов "АНАЛОГИЧНО".
"Аналогично", оно и есть "аналогично" (почти одинаково).
Разница только в исходных данных.
Кстати, умение присваивать этот "статус" очень сильно облегчает жизнь и позволяет
"обломать рога" даже той программе, которая, по первости, ужасает своей "массой".
Вывод: способность к выявлению аналогий (один из элементов сведения чего-либо
к звуку "Му") нужно всячески развивать, холить и лелеять.
Первые процедуры, в некоторых группах аналогичных подпрограмм (в части
касающейся предмета текущего разговора), детально "расписаны".

Работа программы
То, что относится к инициализации графического модуля и до окончания вывода на
индикацию картинки 1-го "кадра", достаточно подробно объяснено ранее.
Специфика заключается только в самой картинке 1-го "кадра" (другая "живопись")
Картинка 1-го "кадра" выводится на индикацию не в "объеме" всего дисплея, а в
строках, с 1 по 6, обеих кристаллов.
Почему? Потому, что в строки 7 и 8 обеих кристаллов, позднее будут выведены на
индикацию картинки 1-го или 2-го сценариев.
Это означает то, что после завершения вывода на индикацию картинки 1-го "кадра",
строки 7 и 8 обеих кристаллов будут "забиты" байтами с числовыми значениями FFh,
ранее выведенными на индикацию в результате инициализации графического модуля.
18
Но эта "чернота" визуально ощущаться не будет, так как сразу же после окончания
вывода на индикацию картинки 1-го "кадра", начнется вывод на индикацию картинки
1-го сценария.

После того, как закончится вывод на индикацию картинки 1-го сценария,


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

;################################################################################
; А теперь можно "замерить" текущее количество попугаев.
;################################################################################
; Сдвиг, в кольцевом регистре, единицы влево (умножение на 2).
;--------------------------------------------------------------------------------
bcf Status,C ; Сброс флага переноса-заема.
rlf Reg1,F ; Сдвиг содержимого 3-байтного
rlf Reg2,F ; регистра Reg3/Reg2/Reg1
rlf Reg3,F ; влево на один бит.
;--------------------------------------------------------------------------------
; Теперь, для обеспечения того, чтобы единица не "гибла", а "гоняла по кольцу",
; нужно переписать содержимое бита С в младший бит младшего байта.
;--------------------------------------------------------------------------------
btfsc Status,C ; Если С=1, то в Reg1,0
goto $+2 ; записывается 1.
goto $+2 ; А если С=0, то в Reg1,0
bsf Reg1,0 ; ничего не записывается (Reg1,0=0).
;--------------------------------------------------------------------------------
; Теперь нужно озаботиться сохранением результата сдвига, а иначе, начиная от
; 2-го "витка" полного цикла программы и далее, всем попугаям будет "Гитлер
; капут" (все "помрут"/обнулятся. Птичек жалко).
;--------------------------------------------------------------------------------
movf Reg1,W ;
movwf Mem1 ;
movf Reg2,W ; Reg3/Reg2/Reg1 -> Mem3/Mem2/Mem1
movwf Mem2 ;
movf Reg3,W ;
movwf Mem3 ;

19
;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно стандартно перевести
; в "набор" 2/10 чисел.
;--------------------------------------------------------------------------------

"Попугайные дела вершатся" в программно организованном, кольцевом, 3-байтном


регистре Reg3/Reg2/Reg1.
Кольцевым называется сдвиговый регистр, в котором организована обратная
связь с выхода триггера самого старшего разряда на управляющий, счетный
вход триггера самого младшего разряда.
Если в каком-нибудь одном триггере кольцевого регистра предустановить единицу (в
остальных триггерах - нули), после чего "затактировать" его, то эта единица будет
"гонять по кольцу до посинения".
Это соответствует математическому закону Х = 2 в степени N.
В случае "правого гоняния", будет … 16, 8, 4, 2 … (последовательное деление на 2, с
учетом работы по кольцу), а в случае "левого гоняния", будет … 2, 4, 8, 16 …
(последовательное умножение на 2, с учетом работы по кольцу).
В случае программной реализации кольцевого регистра, нужно просто-напросто, с
соблюдением порядка старшинства, произвести несколько последовательных,
циклических сдвигов содержимого тех регистров, которые входят в состав кольцевого
регистра, и организовать перенос содержимого бита №7 самого старшего байта в бит
№0 самого младшего байта.
То есть, речь идет о применении команд rlf (в данном случае, мне больше по душе
последовательное умножение на 2) и о переносе содержимого бита №7 регистра Reg3,
в бит №0 регистра Reg1, через бит С регистра Status.
Для обеспечения полной гарантии безошибочности результата кольцевого сдвига, в
начале процедуры кольцевого сдвига, бит С сбрасывается в 0.
Далее - сдвиг влево, на один бит, содержимого 3-байтного регистра Reg3/Reg2/Reg1:

bcf Status,C ; Сброс флага переноса-заема.


rlf Reg1,F ; Сдвиг содержимого 3-байтного
rlf Reg2,F ; регистра Reg3/Reg2/Reg1
rlf Reg3,F ; влево на один бит.

После его завершения, в бите С регистра Status, "заляжет" уровень бита №7 регистра
Reg3.
Для того чтобы имел место быть кольцевой регистр, его нужно скопировать в бит №0
регистра Reg1:

btfsc Status,C ; Если С=1, то в Reg1,0


goto $+2 ; записывается 1.
goto $+2 ; А если С=0, то в Reg1,0
bsf Reg1,0 ; ничего не записывается (Reg1,0=0).

Это и есть программная организация, упомянутой выше, обратной связи.


Остается только скопировать содержимое Reg3/Reg2/Reg1 в 3-байтный регистр
оперативной памяти Mem3/Mem2/Mem1:

movf Reg1,W ;
movwf Mem1 ;
movf Reg2,W ; Reg3/Reg2/Reg1 -> Mem3/Mem2/Mem1
movwf Mem2 ;
movf Reg3,W ;
movwf Mem3 ;

Вопрос: "А зачем нужен этот геморрой? Пусть данные и лежат в Reg3/Reg2/Reg1".
Ответ: дело в том, что далее отрабатывается ПП 2/10 преобразования.
Если войти в нее с 3-байтным регистром Reg3/Reg2/Reg1, то на выходе из нее, этот
регистр просто-напросто обнулится (см. ПП BIN2_10).
То есть, будет уничтожен "объект двигания" (единица), и результатом всех
последующих сдвигов будет не то, что нужно, а "дебильный ноль" (смерть замысла).
20
Кто не верит, тот может проверить.
А в случае наличия "вышележащей перегрузки" в Mem3/Mem2/Mem1, а соответственно
и в случае обработки, в ПП BIN2_10, содержимого Mem3/Mem2/Mem1, этого не
произойдет.
Ну и ладушки. "Размножение попугаев корректно обеспечено".
Далее, "штатно" отрабатывается ПП BIN2_10 (надеюсь, что понятно, зачем это нужно).

;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно стандартно перевести
; в "набор" 2/10 чисел.
;--------------------------------------------------------------------------------
movlw high BIN2_10; Это нужно потому, что ПП BIN2_10 "лежит" на
movwf PCLATH ; 2-й странице памяти программ
; (см. Message[306]).
call BIN2_10 ; Теперь можно "прыгать".
;---> Возврат по стеку из ПП BIN2_10

movlw high STRANICA_5 ; Это нужно потому, что возврат произошел


movwf PCLATH ; из 2-й страницы памяти программ, а далее-то
; работать нужно в 1-й (ориентация на ПП,
; вызываемую ближайшей командой call).

Остановлюсь на специфике.
Дело в том, что в данном случае, ПП BIN2_10 "засунута" мной аж в самый "низ"
программы.
То есть, она "лежит" на 2-й странице памяти программ ПИКа.
А "скачем-то" из 1-й страницы (нестыковочка номер один).
Поэтому, перед "скачком" в эту ПП, нужно озаботиться "волшебной" коррекцией
содержимого PCH ("наводка" à Message[306]), что и имеет место быть.
То же самое нужно учесть и при возврате.
И в самом деле, первым, после возврата, осуществляется условный переход в ПП
STRANICA_5, которая "дислоцируется" на 1-й странице памяти программ.
А возврат-то происходит из 2-й страницы памяти программ (нестыковочка номер
два).
Значит, нужно озаботиться еще одной "волшебной" коррекцией содержимого PCH, что
и имеет место быть.
Вывод: каждое Message[306] должно быть "просканировано на молекулярном
уровне".
Особенности ПП BIN2_10.
3-байтный регистр способен отобразить до 256х256х256=16 777 216 состояний.
В идеале, это предполагает задействование 8-ми десятичных разрядов индикации.
Но в наличии только 6 (см. картинку 1-го "кадра").
ПП BIN2_10 "ваялась" в расчете не на 8, а на 6 десятичных разрядов индикации.
В случае "двигания" влево одной единицы, динамика "размножения" попугаев (число
попугаев выделено зеленым цветом) будет выглядеть так:

1 00000000 00000000 00000001 - .1 13 00000000 00010000 00000000 - .4096


2 00000000 00000000 00000010 - .2 14 00000000 00100000 00000000 - .8192
3 00000000 00000000 00000100 - .4 15 00000000 01000000 00000000 - .16384
4 00000000 00000000 00001000 - .8 16 00000000 10000000 00000000 - .32768
5 00000000 00000000 00010000 - .16 17 00000001 00000000 00000000 - .65536
6 00000000 00000000 00100000 - .32 18 00000010 00000000 00000000 - .131072
7 00000000 00000000 01000000 - .64 19 00000100 00000000 00000000 - .262144
8 00000000 00000000 10000000 - .128 20 00001000 00000000 00000000 - .524288
9 00000000 00000001 00000000 - .256 21 00010000 00000000 00000000 - .1048576
10 00000000 00000010 00000000 - .512 22 00100000 00000000 00000000 - .2097152
11 00000000 00000100 00000000 - .1024 23 01000000 00000000 00000000 - .4194304
12 00000000 00001000 00000000 - .2048 24 10000000 00000000 00000000 - .8388608

Стрелкой показан переход на следующий "виток счета".


21
Если предустановить не одну, а несколько единиц, то естественно, что значения чисел
будут другими (не трудно просчитать).
Так как, в данном случае, количество активных, десятичных разрядов индикации всего
6, то в дисплее будут отображаться только те числа, которые выделены зеленым
цветом.
Числа, выделенные белым цветом, как бы "выходят за пределы зоны видимости" и
отображаться не будут.
Вот Вам и вполне конкретное объяснение той "числовой свистопляски", которая будет
наблюдаться.
Причем, нужно учесть, что первым, после включения питания устройства, на индикацию
будет выведен не символ "1", а символ "2".
Почему?
Потому, что, до начала отработки ПП BIN2_10, произошел один сдвиг содержимого
3-байтного регистра Reg3/Reg2/Reg1.
На следующих "витках" счета, после "убийства всего вида", "подсчет" попугаев
начнется с цифры "1".

После отработки ПП BIN2_10, можно заняться выводом данных на индикацию:

;################################################################################
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;################################################################################
; Задание "координаты", с которой начнется запись байтов данных.
;--------------------------------------------------------------------------------
call STRANICA_5 ; Выбор 5-й страницы.
movlw b'01010000' ; Выбор адреса 17-го столбца (10h).
movwf PortC ; Вывод инструкции "Set Address" в порт С.
call STROB ; Строб под инструкцию.
;---> Возврат по стеку из ПП STROB
;--------------------------------------------------------------------------------
; "Администраторская" группа команд.
;--------------------------------------------------------------------------------
movf LED5,W ; "Цифирь", из LED5, копируется в W,
call CIFRA ; после чего - "прыжок" в ПП CIFRA.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED4,W
call CIFRA ; Аналогично, но для LED4.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED3,W
call CIFRA ; Аналогично, но для LED3.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED2,W
call CIFRA ; Аналогично, но для LED2.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED1,W
call CIFRA ; Аналогично, но для LED1.
;---> Возврат по стеку из ПП CIFRA
;------------------------------------
movf LED0,W
call CIFRA ; Аналогично, но для LED0.
;---> Возврат по стеку из ПП CIFRA
;================================================================================
; Далее - "на колу мочало" ("закольцовка").
;================================================================================
goto SNOVA ; Переход на следующий цикл программы.
;================================================================================

22
Сначала "делаются адресные дела", то есть, задаются "координаты" того столбца, в
который необходимо вывести первый байт первого массива байтов.
Далее, отрабатывается "администраторская" группа команд.
Она состоит из однотипных "подгрупп" команд.
Разница только в обращениях к разным LEDам.
Таким образом, для того чтобы понять, как выводятся на индикацию содержимое всех
LEDов, достаточно понять, как выводится на индикацию содержимое одного LEDа.
Например, LED5.
После того, как содержимое регистра LED5 копируется в регистр W, происходит
условный переход в ПП выбора символов цифр:

;================================================================================
; Подпрограмма выбора символов цифр.
;================================================================================
CIFRA addwf PCL,F ; Вычисляемый переход.
goto C_0 ; Символ "0".
goto C_1 ; Символ "1".
goto C_2 ; Символ "2".
goto C_3 ; Символ "3".
goto C_4 ; Символ "4".
goto C_5 ; Символ "5".
goto C_6 ; Символ "6".
goto C_7 ; Символ "7".
goto C_8 ; Символ "8".
goto C_9 ; Символ "9".

Примечание: используются программные наработки Александра Милевского.


ПП выбора символов цифр представляет собой вычисляемый переход, переход на
исполнение которого (извиняюсь за тавтологию) происходит по стеку, но возврата из
которого, по стеку, нет.
Возврат по стеку происходит не в этой ПП, а в другой. И это есть специфика.
Основная функция ПП CIFRA - выбор сценария вывода на индикацию символа той
или иной цифры, в зависимости от двоично-десятичного значения числа, "лежащего" в
младшем полубайте регистра LED...
Под каждый символ цифры имеется свой сценарий.
Примечание: командами retlw … тут никак не обойдешься, ведь код символа состоит
не из одного, а из нескольких байтов.
Например, в регистре LED5, "лежит" число .0.
Соответственно произойдет безусловный переход в ПП C_0:

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод на индикацию символа "0".
;--------------------------------------------------------------------------------
C_0 movlw .8 ; В регистр Temp записывается
movwf Temp ; число проходов.
WZ_0 movf Temp,W ; Temp -> W.
sublw .8 ; .8 - Temp = ... (результат -> в W).
movwf Reg ; W -> Reg
call Z_0 ; Переход в "знакогенератор" символа "0".
;---> Возврат по стеку из ПП Z_0
movwf PortC ; Вывод текущего байта кода символа "0"
; в PortC.
movlw high WRITE_D; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; ПП WRITE_D (через W).
call WRITE_D ; Переход в ПП записи байта данных.
;---> Возврат по стеку из ПП WRITE_D
decfsz Temp,F ; Temp - 1 = ...
goto WZ_0 ; Если результат не=0, то на индикацию
; выводится следующий байт.
return ; Если результат =0, то возврат по стеку в то
23
; "место", из которого произошел вызов ПП
; CIFRA (с дальнейшим переходом на обработку
; содержимого следующего LEDа).
;--------------------------------------------------------------------------------
.................................
.................................

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Символ "0".
;--------------------------------------------------------------------------------
Z_0 movlw high M_0 ; Установка в PCH числового значения старшего
movwf PCLATH ; байта адреса (в PC) первой команды
; (retlw ...) табличного перехода
; (помечена меткой M_0).
movf Reg,W ; Reg -> W

addwf PCL,F ; Вычисляемый переход.


M_0 Dt 0x00,0x00,0x7C,0xA2,0x92,0x8A,0x7C,0x00 ; Код символа "0"
;--------------------------------------------------------------------------------

ПП С_0, в "связке" с ПП Z_0 (и с соответствующей "обслугой"), по своей сути,


представляет собой группу подпрограмм вывода на индикацию массива байтов.
То есть, то, что было "расписано" ранее.
Просто в данном случае, имеется специфика, заключающаяся в выводе на индикацию
массива из 8-ми байтов.
А это, в свою очередь, привело к отказу от использования оператора low.
И в самом деле, массив "объемом" 8 байтов настолько "слабомассивен", что
вероятность "прохода границы" между блоками памяти программ ПИКа, через таблицу
вычисляемого перехода, мала.
Хотя, объективности ради, нужно сказать, что такое "волевое решение", не
способствует абсолютной "безбяковости" вычисляемого перехода (не универсально), и
если ее необходимо гарантированно обеспечить, то нужно задействовать и оператор
low.
А можно и не задействовать, но в этом случае, нужно "сходить" в окно ROM и
убедиться в отсутствии "прохода границы", между блоками памяти программ, через
таблицы вычисляемых переходов, которые не "обслуживаются" оператором low.
В данном случае, именно это и имеет место быть, и поэтому я отказался от
применения оператора low.
В принципе, в части касающейся команд

Z_0 movlw high M_0 ; Установка в PCH числового значения старшего


movwf PCLATH ; байта адреса (в PC) первой команды
; (retlw ...) табличного перехода
; (помечена меткой M_0).
можно сказать то же самое.
Если эту коррекцию содержимого PCH убрать, то можно освободится и от регистра
Reg (не копировать содержимое W в Reg), но я пока не стал рисковать это делать
(больше одного раза, за один "присест", не рискую) и применил, хотя и "массивный",
но универсальный вариант, с надеждой на то, что на конечной стадии работы над
программой, удастся кое-что как следует "обкарнать".
По поводу цифры .8.
Это есть количество байтов данных, выводимых на индикацию, в ходе формирования
картинки любого из символов цифр.
То есть, в данном случае, речь идет просто-напросто о "сплошном" заполнении одного
квадрата (матрицы 8х8 или "виртуального знакоместа"), по образу и подобию
"сплошного" заполнения страницы графического модуля (только "масштаб помельче").
Почему я это сделал?

24
Потому, что так проще ("пусть безобразно, но зато однообразно" - армейская
мудрость).
С "просветами", устроить "разборки" можно позже (по ходу компромиссной
оптимизации).
И никуда они, родимые, не денутся, так как находятся "под колпаком у Мюллера".
Что это такое? Спросите у Штирлица.
Он-то выкрутился, но ведь это же - феномен. Не все такие.
Короче, всему свое время.
После отработки ПП С_0 (а также и сопровождающей ее "обслуги"), происходит
возврат по стеку на начало обработки содержимого следующего LEDа.
И так далее. Пока все LEDы не будут "отработаны".
Факт такого радостного события свидетельствует о том, что человеческий глаз сможет
оценить результат "попугайной любви", в ее цифровой форме.
После этого à переход на начало полного цикла программы (goto SNOVA), и все
повторяется снова, но только не с начала программы, а с начала сценария №1.
Это имеет место быть, начиная от 2-го "витка" полного цикла программы и далее.
Именно за счет такой "закольцовки" и за счет наличия у графического модуля
оперативной памяти данных, картинка 1-го "кадра" "заторчит в дисплее на веки
вечные" (до выключения питания).

По ходу дела, принципиально важное уточнение, касающееся оператора $.


Обратите внимание на часть программной процедуры 2-го сценария, связанного с
выводом на индикацию массива байтов 8-й страницы 1-го кристалла:

;--------------------------------------------------------------------------------
; Запись в 8-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
call STRANICA_8 ;
call STOLB_1 ;
movlw .64 ;
movwf Temp ;

movf Temp,W ;
sublw .64 ;
movwf Reg ;
movlw high TEXT_2_4; Так как далее следует переход на 2-ю
movwf PCLATH ; страницу памяти программ ПИКа, то
; производится "плавающая" коррекция
; содержимого PCH.
call TEXT_2_4 ; То же самое, только
movwf PortC ; переход происходит
movlw high WRITE_D; в ПП TEXT_2_4.
movwf PCLATH ;
call WRITE_D ;
decfsz Temp,F ;
goto $-.11 ;

Предмет внимания выделен красным цветом.


Обратите внимание на точку (признак десятичной системы исчисления), выставленную
перед цифрой 11.
Если будет иметь место быть goto $-11, то это будет "воспринято" как goto $-11h или
как goto $-.17.
Соответственно, рабочая точка программы "прыгнет вверх" не на 11-ю команду, а на
17-ю команду, что, согласитесь со мной, есть не совсем приятный "сюрприз".
Тоже самое касается и "прыжка вниз" (goto $+…).
"Мораль сей басни такова": при работе с числами до 9-ти включительно, можно
просто указать цифру (без "заморачивания" системой исчисления), но при работе
с числами от 10-ти и более, нужно либо озаботиться выставлением точки
(если отсчет ведется в десятичной системе исчисления), либо указать число,
"прописанное" в 16-ричной системе исчисления.

25
Число, "не укомплектованное" атрибутом системы исчисления,
"воспринимается железякой" как 16-ричное.

А вот теперь можно "лезть" и в "полномасштабный" текст программы 12864_15.asm


("крупногабаритная, коровомычащая мать". Кстати, добродушная. Лягаться и бодаться
будет только в экстремальных ситуациях).
И ничего страшного в этой программе нет, так как она составлена по вполне
"дебильному" принципу многократного повторения (на разные лады) одного и того же.
За счет этого и "наращивается масса".
Если такие повторения заменить словом "АНАЛОГИЧНО" (см. выше. Суперважно!!!), то
после этого, имеется очень высокая вероятность того, что Вы усладите свой слух
"райским звуком Му" (это одно из моих текущих вожделений).
Вопрос: "А можно ли, кроме попугаев, оптово озаботиться например, Змеями
Горынычами, количеством пусков крылатых ракет, количеством хлопаний дверями,
временем работы сноповязалки и т.д., и т.п."?
Ответ: а почему бы и нельзя? Лишь бы соответствующие датчики имели место быть.
8 строк по 16 символов это вовсе не "хухры мухры", а очень даже солидно.
"Отчетливо пахнет" достаточно "крутыми железяками" (потенциальными).
И это еще по-скромному (про графики и прочие "выкрутасы" не упоминаю).
Вот и подумайте, "стоит ли овчинка выделки"?
На мой взгляд, ох как стоит … Поэтому и "маньячно грызу" (плюс, охота пуще неволи).
Общее замечание: моя информация предназначена для людей, которые не страдают
отсутствием воображения и чувства юмора.
По-моему, это очень способствует эффективному усвоению "музыки нулей и единиц".
Как только представлю себе отсутствие оного, так плохо становится и жить неохота.
Поэтому, стараюсь этого и не представлять (тихий ужас. Киборг. Волосы дыбом).
Надеюсь, что в этом смысле, у Вас все в порядке, и Вы являетесь именно теми
людьми, которые смогут отчетливо представить себе, например, "коровомычащую мать",
а также и прочие образы.
Принципиальная схема под программу 12864_15.asm - см. рис. 1 подраздела 2-1/11.

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru

26