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

2-1/17.

Реализация 64-позиционного шкального индикатора, а заодно и "бегущей


строки". Оптимизация текста ПП вывода на индикацию массива байтов.

Ранее речь шла о выводе на индикацию числового значения байта/байтов (результатов


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

Дано: процедура подсчета количества попугаев. Для наглядности, я ее оставил.


Только изменил принцип работы "считалки".
Ранее, она считала по закону 2 в степени N, который, как Вы сами понимаете,
вопиюще нелинеен.
Если линейно "привязать" показания шкального индикатора к этой нелинейности, то
получится черт знает что (дисплей не резиновый. В нем только 1024 столбца, а в
странице, и того меньше).
Вывод: с попугаями нужно что-то делать.
В том смысле, что часть из них архинеобходимо "кастрировать" (самцов), а иначе
управы на них вообще не будет.
Они должны "размножаться" не такими "бешенными темпами", а строго линейно.
Вот Вам и необходимость последовательного инкремента.
Вопрос: "А каков порог экологической угрозы"?
Ответ: это зависит от количества байтов в странице графического модуля.
Если один "новорожденный" попугай будет равен одному столбцу, то "порог
экологической угрозы" будет либо 64 попугая, если шкальный индикатор "ваяется" на
одной странице графического модуля, либо 128 попугаев, если шкальный индикатор
"ваяется" на двух страницах (с одинаковыми номерами) графического модуля (речь
идет о горизонтальном, шкальном индикаторе).
Примечание: шкальный индикатор можно "сваять" не по горизонтали, а по вертикали,
но это сложнее. Вполне реально, но пока отпадает.
С учетом принципа "от простого к сложному", "ваяю" горизонтальный, шкальный
индикатор, считающий до 63-х "живых" попугаев.
Плюс 0 ("гибель вида". Самая левая позиция), в случае "экологической угрозы".
Всего - 64 градации.
Проще говоря, под один шкальный индикатор выделяется одна страница кристалла.
Например, 1-го кристалла (но можно и во 2-м).
"Местечко расчищено" путем "убийства" сценариев №№ 1 и 2 ("мать" - программа
12864_17.asm).
1
Как только "рождается" один попугай, так в шкальном индикаторе заполняется один
дополнительный столбец.
Проще всего, сформировать банальную "ленту" из байтов с числовым значением FFh,
но я ее сделал немного поуже (6 вертикальных, активных точек. Числовое значение
FCh) и пометил столбцы, кратные числу 8, своеобразными "маркерами" ("пимпочками"),
которые "выделяются из общей массы" (7 вертикальных, активных точек. Числовое
значение FEh).
А в самый правый столбец "ленты", вывел "супермаркер"/"суперпимпочку" (для
разнообразия) с числовым значением FFh.
Посмотрите на "вышележащие" фото, и Вы увидите эти "пимпочки".
После успеха этой "концессии", мое буйное воображение вообще взбунтовалось, и
ничего не оставалось делать, как продублировать "вышележащий" шкальный индикатор,
"нижележащим".
Оба мерят одно и то же, но в верхний, выводится банальная "лента с пимпочками", а
в нижний - оригинальный "паровоз (а может быть даже и тепловоз) c 6-ю вагонами"
(всем железнодорожникам - пламенный привет!).
"Идеология" такова: паровоз перевозит попугаев.
В паровозе едут до 16 попугаев, а в каждом вагоне, до 8-ми.
Вот и получается 64 штуки.
Как только "паровоз доезжает" до правой "границы" страницы графического модуля,
всему составу наступает "Гитлер капут" (там "партизанами заложена мина").
Почему?
А потому, что "засечен/застукан противный", 64-й попугай, а это уже явный перебор и
вопиющее безобразие.
Поэтому, я полностью одобряю радикальные методы наведения элементарного порядка.
А как же без него?
Сегодня попугаи, завтра слоны, а послезавтра инопланетяне прилетят и все
захватят/поработят.
Я, по натуре, совсем не злой. И птичек жалко. А куда деваться?
А если серьезно, то сие достигается за счет организации "принудительного"
(программного) сброса содержимого регистра Reg1, по достижении им числа .64.
То есть, "закольцовка" счета (сброс в 0) производится не в момент перехода от числа
.255 к числу .256, а в момент перехода от числа .63 к числу .64.
Делается это на удивление просто (см. ниже).
Всего несколько дополнительных команд.
Итак, цифирки количества попугаев меняются.
В строгом соответствии с этими изменениями, слева, откуда не возьмись, "линейно
выползает лента с пимпочками" ("сюрприз").
Синхронно с ней, "едет и паровоз" (еще один "сюрприз").
В конечном итоге à "подрыв на мине" и дальнейшее "на колу мочало".
"Для полного счастья", не хватает фиксированной градуировки (в данном случае, метки
следуют через каждые 8 столбцов).
Нет проблем. Посмотрите на фото (6-я страница 1-го кристалла).
Это делается в 1-м "кадре".
Серьезный вывод из несерьезно сказанного: если как следует "въехать" в то, что
будет иметь место быть ниже, то можно реализовать не только шкальный индикатор
(или несколько), но и "бегущую строку" (или несколько).
Причем, в "бегущую строку", можно будет выводить не только символы стандартного
набора (цифры, буквы и т.д.), но и все то, что "в голову взбредет" (естественно, в
пределах дозволенного).
Именно это, я и стараюсь продемонстрировать (см. ж/д состав).
В понятийном/стратегическом смысле, лучше всего, условиться так:
- в 7-й странице 1-го кристалла, реализован шкальный индикатор,
- в 8-й странице 1-го кристалла, реализована "бегущая строка".
В данном случае, когда имеют место быть не "дерганья", а последовательное
"наращивание массы" числа, лежащего в регистре Reg1, никакой функциональной
разницы между первым и вторым нет.

2
В случае же, если будут иметь место быть "дерганья" (резкие изменения значений
чисел, которые нужно отобразить), первое "имеет право на жизнь", а вот "бегущая
строка даст дуба", так как будет нарушен основной ее принцип: информация в
"бегущую строку" должна выводиться последовательно, с фиксированным шагом (чаще
всего - в одну "позицию"), и в одном направлении.
Иначе получится не "бегущая строка", а черт знает что (визуальная мУка).
А теперь, ближе к "животрепещущим" деталям.
Ниже, Вы видите текст программы, в которой реализовано "вышележащее" (программа
12864_18.asm. Полный текст прилагается).
В целях обеспечения комфортного "въезда", я ее как следует "обкарнал", но основные
"моменты" - в полной целости и сохранности.
Кстати, по сравнению с предыдущими программами, программа 12864_18.asm не такая
уж и "массивная":

;********************************************************************************
; 12864_18.asm Учебное устройство, осуществляющее "подсчет" (имитация)
; количества "размножающихся" попугаев. Результат подсчета
; выводится на индикацию в графический модуль MT-12864...
; (оба сценария "усопли". Вместо них, имеет место быть шкальный
; индикатор на 64 позиции и "бегущая строка")
;********************************************************************************
; "Практикум по конструированию устройств на 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.
;----------------------------------------------
; Объем программы: 1203 слова в памяти программ.
;================================================================================
LIST p=16F873A ; Задание типа микроконтроллера.
__CONFIG 3F71H ; Включено: XT-генератор, PWRT, сброс BOR,
; Выключено: защита, WDT, LVP, DEBUG.
;================================================================================
; Регистры специального назначения.
;================================================================================
.............................

;================================================================================
; Регистры общего назачения.
;================================================================================
Temp equ 20h ; Регистр количества проходов.
Reg equ 21h ; Регистр выбора сценария вычисляемого
; перехода (плюс, используется в ПП BIN2_10).
Mem1 equ 22h ; Регистры задержки, а также и хранения
Mem2 equ 23h ; результата кольцевого сдвига
Mem3 equ 24h ; (кроме того, Mem1 - указатель страницы).
3
Reg1 equ 25h ; Регистр счетчика количества попугаев.
N_Zapoln equ 26h ; Регистр количества байтов заполнения шкалы.
LED0 equ 30h ; Регистры, задействованные
LED1 equ 31h ; в ПП 2/10 преобразования.
;================================================================================
; Присвоение битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
Z equ 2 ; Флаг нулевого результата.
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.
;********************************************************************************

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Символ "0".
;-------------
Z_0 .............................
;-------------
; Символ "1".
;-------------
Z_1 .............................
;-------------
; Символ "2".
;-------------
Z_2 .............................
;-------------
; Символ "3".
;-------------
Z_3 .............................
;-------------
; Символ "4".
;-------------
Z_4 .............................
;-------------
; Символ "5".
;-------------
Z_5 .............................
;-------------
; Символ "6".
;-------------
Z_6 .............................
;-------------
; Символ "7".
;-------------
Z_7 .............................
;-------------
; Символ "8".
;-------------
Z_8 .............................
;-------------
; Символ "9".
;-------------
Z_9 .............................
;-------------
; "Пробел".
4
;-------------
Z_10 .............................
;================================================================================
; Подпрограммы выбора страниц (1...8) кристалла.
;================================================================================
; ПП установки адреса 1-й страницы.
;------------------------------------
STRANICA_1 ..........................
;------------------------------------
; ПП установки адреса 2-й страницы.
;------------------------------------
STRANICA_2 ..........................
;------------------------------------
; ПП установки адреса 3-й страницы.
;------------------------------------
STRANICA_3 ..........................
;------------------------------------
; ПП установки адреса 4-й страницы.
;------------------------------------
STRANICA_4 ..........................
;------------------------------------
; ПП установки адреса 5-й страницы.
;------------------------------------
STRANICA_5 ..........................
;------------------------------------
; ПП установки адреса 6-й страницы.
;------------------------------------
STRANICA_6 ..........................
;------------------------------------
; ПП установки адреса 7-й страницы.
;------------------------------------
STRANICA_7 ..........................
;------------------------------------
; ПП установки адреса 8-й страницы.
;------------------------------------
STRANICA_8 ..........................
;================================================================================
; Подпрограмма записи данных.
;================================================================================
WRITE_D ..........................
;================================================================================
; Подпрограмма чтения данных.
;================================================================================
READ_D ..........................
;================================================================================
; Подпрограмма стробирования.
;================================================================================
STROB ..........................
;================================================================================
; Подпрограмма установки первого (самого левого) столбца страницы (адрес 00h).
;================================================================================
STOLB_1 ..........................
;================================================================================
; Подпрограмма заполнения страницы нулями.
;================================================================================
ZERO ..........................
;================================================================================
; Подпрограмма выбора страницы, в случае совмещения 4-х таблиц, относящихся
; к одному кристаллу.
;================================================================================
VIBOR ..........................
;================================================================================
; Подпрограмма числовой коррекции адреса "прыжка".
;================================================================================
; В случае возврата, отсчет от 1-й команды retlw ...
;------------------------------------------------------------------
5
N_STR ..........................
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
PAUSE ..........................
;================================================================================
; Подпрограмма "обнуления" 4, 6, 7 и 8 страниц.
;================================================================================
; "Обнуляются" 4, 6, 7 и 8 страницы.
;------------------------------------
SBROS_STR ..........................
;------------------------------------
; "Обнуляются" 4, 7 и 8 страницы.
;------------------------------------
SBROS_STR_1 .........................
;================================================================================

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

;################################################################################
; Вывод на индикацию картинки 1-го "кадра".
;################################################################################
; Включение 2-го кристалла.
;*************************************
..........................
;--------------------------------------------------------------------------------
; Выбор страницы, в случае совмещения 4-х таблиц, относящихся к одному кристаллу.
;--------------------------------------------------------------------------------
..........................
KOLCO call VIBOR ; Переход в подпрограмму выбора страницы, в
; случае совмещения 4-х таблиц, относящихся
; к одному кристаллу.
;---> Возврат по стеку из ПП VIBOR ;
;--------------------------------------------------------------------------------
; Запись в 1, 2, 3, 5 страницы 2-го кристалла.
;--------------------------------------------------------------------------------
..........................
call TEXT_1 ; Переход в ПП TEXT_1.
;---> Возврат по стеку из ПП TEXT_1
..........................
decfsz Mem1,F ; Декремент указателя страницы, после чего
goto KOLCO ; либо переход на заполнение следующей
; страницы, либо выход из процедуры.
;--------------------------------------------------------------------------------
; Запись в 4, 6, 7, 8 страницы 2-го кристалла (заполнение нулями).
;--------------------------------------------------------------------------------
call SBROS_STR ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR
;*************************************
; Включение 1-го кристалла.
;*************************************
..........................
;--------------------------------------------------------------------------------
; Выбор страницы, в случае совмещения 4-х таблиц, относящихся к одному кристаллу.
;--------------------------------------------------------------------------------
6
..........................
KOLCO_1 call VIBOR ; Переход в подпрограмму выбора страницы, в
; случае совмещения 4-х таблиц, относящихся
; к одному кристаллу.
;---> Возврат по стеку из ПП VIBOR ;
;--------------------------------------------------------------------------------
; Запись в 1, 2, 3, 5 страницы 1-го кристалла.
;--------------------------------------------------------------------------------
..........................
call TEXT_2 ; Переход в ПП TEXT_2.
..........................
decfsz Mem1,F ; Декремент указателя номера страницы, после
goto KOLCO_1 ; чего либо переход на заполнение следующей
; страницы, либо выход из процедуры.
;--------------------------------------------------------------------------------
; Запись в 6-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
..........................
call TEXT_3 ; Переход в ПП TEXT_3.
..........................
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 1-го кристалла (заполнение нулями).
;--------------------------------------------------------------------------------
call SBROS_STR_1 ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR_1
;################################################################################

;********************************************************************************
; А теперь можно "замерить" текущее количество попугаев.
;********************************************************************************
SNOVA incf Reg1,F ; Reg1 + 1 = ... (обеспечение "динамики")
movf Reg1,W ; Reg1 -> W
sublw .64 ; .64 - Reg1 = ...
btfsc Status,Z ; Выходить на следующее кольцо счета или нет?
goto $+2 ; Если да, то Reg1 сбрасывается в 0.
goto $+2 ; Если нет, то Reg1 не сбрасывается в 0.
clrf Reg1 ; А это сам сброс.

movf Reg1,W ; В любом случае, содержимое Reg1 копируется


movwf Mem1 ; в Mem1 (для BIN2_10) и в N_Zapoln (для
movwf N_Zapoln ; выбора количества байтов заполнения шкалы).
;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно стандартно перевести
; в "набор" 2/10 чисел.
;--------------------------------------------------------------------------------
call BIN2_10 ; Переход в ПП 2/10 преобразования
; (то, что нужно преобразовать, "лежит"
; в Mem1).
;---> Возврат по стеку из ПП BIN2_10

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Задание "координаты", с которой начнется запись байтов данных
; (страница 5, 33-й столбец).
;--------------------------------------------------------------------------------
..........................
;--------------------------------------------------------------------------------
; Группа команд гашения незначащих нулей (работа с LED1).
;--------------------------------------------------------------------------------
..........................
;--------------------------------------------------------------------------------
; "Администраторская" подпрограмма (работа с LED1 и LED0).
;--------------------------------------------------------------------------------
..........................
7
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;////////////////////////////////////////////////////////////////////////////////
; РАБОТА СО ШКАЛЬНЫМ ИНДИКАТОРОМ (в 1-м кристалле. Он установлен ранее).
;////////////////////////////////////////////////////////////////////////////////
; Вывод данных на индикацию в 7-ю страницу (шкала без "выкрутасов").
;--------------------------------------------------------------------------------
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
call ZERO ; Сброс в 0 предыдущих показаний.
;---> Возврат по стеку из ПП ZERO
;--------------------------------------------------------------------------------
; Процедура вывода на индикацию массива байтов.
;--------------------------------------------------------------------------------
movf N_Zapoln,W ; Копирование количества байтов заполнения
movwf Temp ; шкалы в регистр Temp (назначение числа
; проходов).
call TEXT_4 ; Переход в ПП TEXT_4 (на эту команду
; происходит "закольцовка").
;---> Возврат по стеку из ПП TEXT_4
movwf PortC ; ----"----
movlw high WRITE_D; Стандартно.
movwf PCLATH ; ----"----
call WRITE_D ; ----"----
;---> Возврат по стеку из ПП WRITE_D
;-------------------------------------
; "Концовка".
;-------------------------------------
decf Temp,F ; Temp - 1 = ...
btfss Temp,7 ; В бит №7 регистра Temp 0 или 1 ?
goto $-7 ; Если 0, то на индикацию выводится
; следующий байт массива.
; Если это 1, то массив выведен и
; программа исполняется далее.
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ВАРИАНТ "КОНЦОВКИ".
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;;; decf Temp,F ; Temp - 1 = ...
;;; movlw .255 ;
;;; subwf Temp,W ; Temp - .255 = ...
;;; btfss Status,Z ; Это число .255 или другое ?
;;; goto $-9 ; Если не .255, то на индикацию выводится
;;; ; следующий байт массива.
;;; ; Если это .255, то массив выведен и
;;; ; программа исполняется далее.
;--------------------------------------------------------------------------------
; Вывод данных на индикацию в 8-ю страницу ("паровоз и 6 вагонов").
;--------------------------------------------------------------------------------
call STRANICA_8 ;
;---> Возврат по стеку из ПП STRANICA_8
call STOLB_1 ;
;---> Возврат по стеку из ПП STOLB_1
call ZERO ;
;---> Возврат по стеку из ПП ZERO

movf N_Zapoln,W ;
movwf Temp ;

call TEXT_5 ; Аналогично,


movwf PortC ; только для ПП TEXT_5.
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;

8
decf Temp,F ;
btfss Temp,7 ;
goto $-7 ;
;////////////////////////////////////////////////////////////////////////////////
call PAUSE ; Задержка 0,3 сек.
;---> Возврат по стеку из ПП PAUSE
;================================================================================
; Далее - "на колу мочало" ("закольцовка").
;================================================================================
goto SNOVA ; Переход на следующий цикл программы.
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Подготовительные операции.
;------------------------------------
CIFRA movwf Mem1 ; Сохранение, в Mem1, содержимого
; текущего LEDа.
movlw .8 ; В регистр Temp записывается
movwf Temp ; число проходов.
;================================================================================
; Циклическая ПП вывода на индикацию символов цифр (в нее "врезана" группа
; команд анализа числового значения содержимого текущего LEDа).
;================================================================================
VERH ..........................
;*************************************
; "Врезка".
;*************************************
; Для символа "0".
;-------------------------------------
..........................
call Z_0 ; Если =0, то переход в "знакогенератор"
;---> Возврат по стеку из ПП Z_0 ; символа "0" (подготовка к выводу на
goto VIVOD ; индикацию текущего байта), а после возврата
; - обход всей процедуры анализа.
;-------------------------------------
; Для символа "1".
;-------------------------------------
..........................
call Z_1 ; Переход в "знакогенератор" символа "1".
;---> Возврат по стеку из ПП Z_1
goto VIVOD ;
;-------------------------------------
; Для символа "2".
;-------------------------------------
..........................
call Z_2 ; Переход в "знакогенератор" символа "2".
;---> Возврат по стеку из ПП Z_2
goto VIVOD ;
;-------------------------------------
; Для символа "3".
;-------------------------------------
..........................
call Z_3 ; Переход в "знакогенератор" символа "3".
;---> Возврат по стеку из ПП Z_3
goto VIVOD ;
;-------------------------------------
; Для символа "4".
;-------------------------------------
..........................
call Z_4 ; Переход в "знакогенератор" символа "4".
;---> Возврат по стеку из ПП Z_4
goto VIVOD ;
;-------------------------------------
; Для символа "5".
9
;-------------------------------------
..........................
call Z_5 ; Переход в "знакогенератор" символа "5".
;---> Возврат по стеку из ПП Z_5
goto VIVOD ;
;-------------------------------------
; Для символа "6".
;-------------------------------------
..........................
call Z_6 ; Переход в "знакогенератор" символа "6".
;---> Возврат по стеку из ПП Z_6
goto VIVOD ;
;-------------------------------------
; Для символа "7".
;-------------------------------------
..........................
call Z_7 ; Переход в "знакогенератор" символа "7".
;---> Возврат по стеку из ПП Z_7
goto VIVOD ;
;-------------------------------------
; Для символа "8".
;-------------------------------------
..........................
call Z_8 ; Переход в "знакогенератор" символа "8".
;---> Возврат по стеку из ПП Z_8
goto VIVOD ;
;-------------------------------------
; Для символа "9".
;-------------------------------------
..........................
call Z_9 ; Переход в "знакогенератор" символа "9".
;---> Возврат по стеку из ПП Z_9
goto VIVOD ;
;-------------------------------------
; Для символа "пробел".
;-------------------------------------
..........................
call Z_10 ; Переход в "знакогенератор" символа "пробел"
;---> Возврат по стеку из ПП Z_10
;*************************************
; Конец "врезки".
;*************************************
VIVOD movwf PortC ; Вывод текущего байта кода символа в PortC.
call WRITE_D ; Переход в ПП записи байта данных.
;---> Возврат по стеку из ПП WRITE_D
decfsz Temp,F ; Temp - 1 = ...
goto VERH ; Если результат не=0, то на индикацию
; выводится следующий байт.
return ; Если результат =0, то возврат по стеку в то
; "место", из которого произошел вызов ПП
; CIFRA (с дальнейшим переходом на обработку
; содержимого следующего LEDа).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;################################################################################
; ТАБЛИЦЫ ДАННЫХ 1-го "КАДРА".
;################################################################################
; КРИСТАЛЛ 2
;================================================================================
; "Счетверенные" данные 1, 2, 3, 5 страниц 2-го кристалла.
;================================================================================
; Анализ указателя номера страницы с целью числовой коррекции адреса "прыжка".
;--------------------------------------------------------------------------------
TEXT_1 call N_STR ; Переход в ПП числовой коррекции адреса
; "прыжка".
10
;---> Возврат по стеку из ПП N_STR ;

..........................

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

; КРИСТАЛЛ 2
; ---------Таблица 1-й страницы----------
; Надпись "ывода на"
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 ; Reg+0=...
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-й страницы----------


; Надпись "ю итога "
Dt 0x00,0xF8,0x20,0x70,0x88,0x88,0x70,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00
Dt 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00 ; Reg+.64=...
Dt 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00
Dt 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

; ---------Таблица 3-й страницы----------


; Надпись "его-либо"
Dt 0x00,0x00,0x70,0xA8,0xA8,0xA8,0x30,0x00
Dt 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x00
Dt 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00
Dt 0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x00 ; Reg+.128=...
Dt 0x00,0x00,0x40,0x88,0x78,0x08,0xF8,0x00
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00
Dt 0x00,0x00,0x78,0x94,0x94,0x92,0x72,0x00
Dt 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00

; ---------Таблица 5-й страницы----------


; Надпись "попугаев"
Dt 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00
Dt 0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00
Dt 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00
Dt 0x00,0x00,0x18,0xA0,0xA0,0xA0,0x78,0x00 ; Reg+.192=...
Dt 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0x70,0xA8,0xA8,0xA8,0x30,0x00
Dt 0x00,0x00,0xF8,0xA8,0xA8,0xA8,0x50,0x00

;================================================================================
; КРИСТАЛЛ 1
;================================================================================
; "Счетверенные" данные 1, 2, 3, 5 страниц 1-го кристалла.
;================================================================================
TEXT_2 call N_STR ;
;---> Возврат по стеку из ПП N_STR ;

..........................

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

; КРИСТАЛЛ 1
; ---------Таблица 1-й страницы----------
11
; Надпись "Пример в"
STR_2 Dt 0x00,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00
Dt 0x00,0x00,0xF8,0x48,0x48,0x48,0x30,0x00
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00
Dt 0x00,0x00,0xF8,0x10,0x20,0x10,0xF8,0x00 ; Reg+0=...
Dt 0x00,0x00,0x70,0xA8,0xA8,0xA8,0x30,0x00
Dt 0x00,0x00,0xF8,0x48,0x48,0x48,0x30,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0xF8,0xA8,0xA8,0xA8,0x50,0x00

; ---------Таблица 2-й страницы----------


; Надпись "индикаци"
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00
Dt 0x00,0x00,0xF8,0x20,0x20,0x20,0xF8,0x00
Dt 0x00,0x00,0xC0,0x68,0x58,0x48,0xF8,0x00
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00 ; Reg+.64=...
Dt 0x00,0x00,0xF8,0x20,0x50,0x88,0x00,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0x78,0x40,0x40,0x78,0xC0,0x00
Dt 0x00,0x00,0xF8,0x40,0x20,0x10,0xF8,0x00

; ---------Таблица 3-й страницы----------


; Надпись "замера ч"
Dt 0x00,0x00,0x88,0xA8,0xA8,0xA8,0x50,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0xF8,0x10,0x20,0x10,0xF8,0x00
Dt 0x00,0x00,0x70,0xA8,0xA8,0xA8,0x30,0x00 ; Reg+.128=...
Dt 0x00,0x00,0xF8,0x48,0x48,0x48,0x30,0x00
Dt 0x00,0x00,0x40,0xA8,0xA8,0xA8,0xF0,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0x18,0x20,0x20,0x20,0xF8,0x00

; ---------Таблица 5-й страницы----------


; Надпись " X= "
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0xC6,0x28,0x10,0x28,0xC6,0x00
Dt 0x00,0x00,0x28,0x28,0x28,0x28,0x28,0x00 ; Reg+.192=...
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Dt 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;--------------------------------------------------------------------------------
; Данные 6-й страницы 1-го кристалла
;--------------------------------------------------------------------------------
TEXT_3 ..........................

addwf PCL,F ;

; Картинка градуировки (3Ch - вертикальные линии).


STR_3 Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
Dt 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3C
;################################################################################

;////////////////////////////////////////////////////////////////////////////////
; ТАБЛИЦЫ ДАННЫХ ШКАЛЬНОГО ИНДИКАТОРА.
;////////////////////////////////////////////////////////////////////////////////
; Таблица конфигурации байтов, которыми заполняется шкала (без "выкрутасов").
12
; Через каждые 8 байтов выставлен маркер.
;================================================================================
TEXT_4 movlw high STR_4 ;
movwf PCLATH ;

movf Temp,W ; Аналогично.


addlw low STR_4 ;
btfsc Status,C ;
incf PCLATH,F ;
movf Temp,W ;

addwf PCL,F ;
STR_4 Dt 0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; Темно-красным
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; цветом выделены
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; маркеры
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
;================================================================================
; Таблица конфигурации байтов, которыми заполняется шкала.
; С "выкрутасами" ("паровоз и 6 вагонов").
;================================================================================
TEXT_5 movlw high STR_5 ;
movwf PCLATH ;

movf Temp,W ; Аналогично.


addlw low STR_5 ;
btfsc Status,C ;
incf PCLATH,F ;
movf Temp,W ;

addwf PCL,F ;
STR_5 Dt 0x70,0xF8,0xFC,0x74,0x7E,0xF4,0xFC,0x74
Dt 0x7C,0xFC,0xFC,0x7C,0x7C,0xFC,0xFC,0x78
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
;////////////////////////////////////////////////////////////////////////////////

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

Темно-синим цветом выделено то, что относится к 1-му "кадру'.


Красным цветом выделено то, что относится к шкальному индикатору/"бегущей строке".

Работа программы

Из "матери" (12864_17.asm) "убраны" 1-й и 2-й сценарии.


Соответственно, освободились 7-е и 8-е страницы обеих кристаллов.
В них и выведен шкальный индикатор (7-я стр. 1-го кристалла) и аналог "бегущей
строки" (8-я стр. 1-го кристалла).
Картинка 1-го "кадра" выводится на индикацию "по образу и подобию" вывода картинки
1-го "кадра" "материнской" программы (12864_17.asm).
Различие только в том, что в 6-ю страницу 1-го кристалла записываются не нули, а
картинка фиксированной градуировки:
13
;--------------------------------------------------------------------------------
; Запись в 6-ю страницу 1-го кристалла
;--------------------------------------------------------------------------------
..........................
call TEXT_3 ; Переход в ПП TEXT_3.
..........................
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 1-го кристалла (заполнение нулями).
;--------------------------------------------------------------------------------
call SBROS_STR_1 ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR_1

С учетом того, что сценарии №№ 1 и 2 "усопли", в 1-м "кадре", нулями нужно


"забивать" 3 страницы 1-го кристалла: 4-ю, 7-ю и 8-ю.
В 6-ю страницу 1-го кристалла, на индикацию выводится картинка фиксированной
градуировки, код которой "заложен" в ПП TEXT_3.
Так как бОльшая часть процедуры "забития нулями" "тупо" повторяется при выводе на
индикацию картинки 1-го "кадра" и в 1-й, и во 2-й кристалл, то я оформил эту
процедуру в виде отдельной подпрограммы, которая вызывается с помощью команды
call.
При выводе на индикацию картинки 1-го "кадра" во 2-й кристалл, она отрабатывается
полностью (нулями "забиваются" 4, 6, 7, 8 страницы. Переход в ПП SBROS_STR).
При выводе на индикацию картинки 1-го "кадра" в 1-й кристалл, ПП отрабатывается не
полностью, а частично (нулями "забиваются" 4, 7, 8 страницы. Переход на
метку/подпрограмму SBROS_STR_1).
Короче, сие есть достаточно немудреные особенности формирования картинки 1-го
"кадра" в данном, конкретном случае.
После того, как на индикацию будет выведена картинка 1-го "кадра", "замеряется"
текущее количество попугаев:

;********************************************************************************
; А теперь можно "замерить" текущее количество попугаев.
;********************************************************************************
SNOVA incf Reg1,F ; Reg1 + 1 = ... (обеспечение "динамики")
movf Reg1,W ; Reg1 -> W
sublw .64 ; .64 - Reg1 = ...
btfsc Status,Z ; Выходить на следующее кольцо счета или нет?
goto $+2 ; Если да, то Reg1 сбрасывается в 0.
goto $+2 ; Если нет, то Reg1 не сбрасывается в 0.
clrf Reg1 ; А это сам сброс.

movf Reg1,W ; В любом случае, содержимое Reg1 копируется


movwf Mem1 ; в Mem1 (для BIN2_10) и в N_Zapoln (для
movwf N_Zapoln ; выбора количества байтов заполнения шкалы).
;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно стандартно перевести
; в "набор" 2/10 чисел.
;--------------------------------------------------------------------------------
call BIN2_10 ; Переход в ПП 2/10 преобразования
; (то, что нужно преобразовать, "лежит"
; в Mem1).
;---> Возврат по стеку из ПП BIN2_10

Так как речь идет о линейно нарастающем количестве попугаев, применена команда
incf.
"Предметом ее вожделения" назначен регистр Reg1.
Регистры Reg2 и Reg3 (см. "мать") "убиты за ненужностью".
Обратите внимание на команды, выделенные красным цветом.
Именно они и обеспечивают "динамику" шкалы, в диапазоне 64-х градаций.

14
Это осуществляется достаточно просто: постепенно "наращиваемое" число, которое
"лежит" в регистре Reg1 просто сравнивается (в начале каждого внутреннего цикла) с
константой .64.
Если это число "нарастилось" до .64, то содержимое регистра Reg1 банально
сбрасывается в ноль, после чего, дальнейший счет происходит от 0.
Последнее и есть, упомянутый выше, "подрыв на партизанской мине".
Итак, содержимое регистра Reg1 "заанализировано" и в случае чего, нужным образом
скорректировано.
После этого, его можно скопировать в регистр Mem1.
Далее, содержимое регистра Mem1 будет использовано как исходные данные для
осуществления 2/10 преобразования (см. переход в ПП BIN2_10).
Но особенность заключается в том, что после возврата из ПП BIN2_10, в регистре
Mem1, будет "лежать" число, которое и близко не будет соответствовать содержимому
регистра Reg1.
А ведь дальше-то (после возврата из ПП BIN2_10) нужно выводить результат
"подсчета" количества попугаев на индикацию в графический модуль.
Если при этом использовать регистр Mem1, то будут не "попугайные дела", а
сплошной конфуз.
То есть, при выводе результата "подсчета" количества попугаев на индикацию в
графический модуль, регистр Mem1 применять нельзя.
Значит, кроме сохранения содержимого регистра Reg1, в регистре Mem1 (для ПП
BIN2_10), нужно сохранить его и еще в одном регистре.
В качестве такового, используется регистр N_Zapoln (с намеком на текущее количество
байтов заполнения шкалы), который представляет собой те "закрома", из которых
"черпаются" исходные данные для процедур шкального индикатора/"бегущей строки".
А теперь о десятичной разрядности.
В данном случае, максимальная, десятичная разрядность = 2.
То есть, для отображения результата "размножения" попугаев (от .0 до .63-х), с
избытком хватит и одного регистра общего назначения.
Таким образом, ПП BIN2_10 должна обеспечивать преобразование всего-навсего одного
байта (Mem1) в два десятичных разряда (LED0 и LED1).
Остальные "материнские" LEDы просто "отправляются к праотцам" (что и имеет место
быть).
При таком "раскладе", ничего лучшего, чем ПП 2/10 преобразования Сергея Рослика,
просто нет (абсолютно вне конкуренции).
Поэтому я ее и применил, а заодно и вспомнил Сергея добрым словом.
На всякий случай, после директивы end программы 12864_18.asm, я "нарисовал"
соответствующий вариант стандартной ПП 2/10 преобразования.
Можете сравнить.
Так как речь идет всего о двух десятичных разрядах, то и последующие действия

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод результата "подсчета" количества попугаев на индикацию
; в графический модуль.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Задание "координаты", с которой начнется запись байтов данных
; (страница 5, 33-й столбец).
;--------------------------------------------------------------------------------
..........................
;--------------------------------------------------------------------------------
; Группа команд гашения незначащих нулей (работа с LED1).
;--------------------------------------------------------------------------------
..........................
;--------------------------------------------------------------------------------
; "Администраторская" подпрограмма (работа с LED1 и LED0).
;--------------------------------------------------------------------------------
..........................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

существенно упрощаются/карнаются (по отношению к "матери").

15
Просто все лишнее "выкидывается на помойку" (см. текст программы 12864_18.asm, в
сравнении с текстом 12864_17.asm).
После этого, несколько нарушается "визуальная центровка" результата подсчета
попугаев.
Но это дело поправимое: просто изменяется адрес, с которого начинается заполнение
данными 5-й страницы 1-го кристалла (адрес 33-го столбца à 20h), и все дела.
А можно и не изменять. Кому как нравится.

После того, как в регистрах LED0 и LED1 "осядет" результат 2/10 преобразования,
начинается "основное действо".
А теперь пару слов о замысле.
Изначально, "привяжусь" не к "бегущей строке", а к шкальному индикатору.
Что "лежит" в регистре N_Zapoln ?
В нем "лежит" текущее количество попугаев.
Вот Вам и количество байтов, которое нужно вывести на индикацию в 7-ю страницу
1-го кристалла, из расчета того, что одному попугаю соответствует один столбец
(линейная зависимость).
Следовательно, числовое значение содержимого регистра N_Zapoln (от .0 до .63)
определяет номер одного из 64-х сценариев табличного вычисляемого перехода, на
котором заканчивается вывод на индикацию текущей группы байтов.
Соответственно, количество байтов, в этой группе, может быть различно (зависит от
содержимого регистра N_Zapoln).
Первым всегда выводится байт 1-го сценария вычисляемого перехода (я его пометил
"суперпимпочкой" с числовым значением FFh).
Направление вывода: от байта 1-го сценария, к байту, номер сценария которого задает
содержимое регистра N_Zapoln.
Теперь нужно определиться с числовыми значениями этих байтов.
Каковы они?
А какие зададите, такие и будут.
В простейшем случае, можно заполнить всю таблицу вычисляемого перехода байтами
с одинаковыми числовыми значениями.
Например, FFh ("лента" высотой в 8 точек), FEh ("лента" высотой в 7 точек), FCh
("лента" высотой в 6 точек) и т.д.
Я "сваял" "ленту" высотой в 6 точек, но с "маркерными пимпочками" (через каждые 8
байтов).
Мне кажется, что так симпатичнее и порядка больше (это "движущееся безобразие"
можно комфортно, визуально "привязать" к имеющейся фиксированной градуировке).

Итак, сначала "делаются координатные дела": выбирается 1-й столбец 7-й страницы
(напоминаю, что ранее был включен 1-й кристалл):

;////////////////////////////////////////////////////////////////////////////////
; РАБОТА СО ШКАЛЬНЫМ ИНДИКАТОРОМ (в 1-м кристалле. Он установлен ранее).
;////////////////////////////////////////////////////////////////////////////////
; Вывод данных на индикацию в 7-ю страницу (шкала без "выкрутасов").
;--------------------------------------------------------------------------------
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
call ZERO ; Сброс в 0 предыдущих показаний.
;---> Возврат по стеку из ПП ZERO

Далее следует "обнуление" содержимого этой страницы (call ZERO).


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

16
Далее, для обеспечения нормальной отработки процедуры вывода на индикацию
массива байтов, нужно "перегрузить" число текущего количества попугаев из регистра
N_Zapoln в регистр Temp:

movf N_Zapoln,W ; Копирование количества байтов заполнения


movwf Temp ; шкалы в регистр Temp (назначение числа
; проходов).
call TEXT_4 ; Переход в ПП TEXT_4 (на эту команду
; происходит "закольцовка").
;---> Возврат по стеку из ПП TEXT_4

После этого, можно "прыгать" в ПП TEXT_4:

;////////////////////////////////////////////////////////////////////////////////
; ТАБЛИЦЫ ДАННЫХ ШКАЛЬНОГО ИНДИКАТОРА.
;////////////////////////////////////////////////////////////////////////////////
; Таблица конфигурации байтов, которыми заполняется шкала (без "выкрутасов").
; Через каждые 8 байтов выставлен маркер.
;================================================================================
TEXT_4 movlw high STR_4 ;
movwf PCLATH ;

movf Temp,W ; Аналогично.


addlw low STR_4 ;
btfsc Status,C ;
incf PCLATH,F ;
movf Temp,W ;

addwf PCL,F ;
STR_4 Dt 0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; Темно-красным
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; цветом выделены
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC ; маркеры
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
;================================================================================

В состав стандартной ПП TEXT_4, входит таблица, в которой "расписаны" числовые


значения всех 64-х байтов, подлежащих выводу на индикацию в 7-ю страницу 1-го
кристалла.
Именно содержимое этой таблицы и формирует "линию с пимпочками".
Числовые значения байтов "пимпочек" (маркеров) выделены темно-красным цветом.
В данном случае, имеет место быть моя индивидуальная фантазия.
Вы можете нафантазировать свое (в простейшем случае - все FFh).
Принцип формирования "линии" очень прост.
Например, имеет место быть количество попугаев = .15.
В этом случае, на индикацию будет выведено содержимое двух верхних строк
таблицы. И т.д.

После возврата из ПП TEXT_4, отрабатывается стандартная группа команд вывода на


индикацию текущего байта:

movwf PortC ; ----"----


movlw high WRITE_D; Стандартно.
movwf PCLATH ; ----"----
call WRITE_D ; ----"----
;---> Возврат по стеку из ПП WRITE_D

Ничего нового в ней нет.


А вот далее, новое появляется.
Подоплека.
17
Ранее, мы имели дело с тем, что в регистр Temp записывалась константа .64, а
далее, это число уменьшалось.
В данном же случае, направление счета противоположно: от .0 до .63.
Поэтому, "концовка" процедуры вывода на индикацию массива байтов будет выглядеть
так:
;------------------------------------
; Вариант концовки №1.
;------------------------------------
decf Temp,F ; Temp - 1 = ...
movlw .255 ;
subwf Temp,W ; Temp - .255 = ...
btfss Status,Z ; Это число .255 или другое ?
goto $-9 ; Если не .255, то на индикацию выводится
; следующий байт массива.
; Если это .255, то массив выведен и
; программа исполняется далее.
Теория.
Если на входе в процедуру, в регистре N_Zapoln будет "лежать" 0, то результатом
декремента будет число .255, что есть "глюк".
В этом случае, вместо того чтобы выйти из процедуры, рабочая точка программы
"улетит туда, куда Макар телят не гонял".
Поэтому, критерием отработки процедуры вывода на индикацию массива байтов,
должно быть не число .0, а число .255.
Что и имеет место быть.
Вот Вам и еще одна разновидность ПП вывода на индикацию массива байтов (вношу
свою посильную лепту).
В обеих разновидностях - одинаковое количество команд.
Теперь даже можно выбрать ту из них, которая Вам больше нравится.
Но наибольший, практический интерес представляет "малокомандная" концовка.
Принцип ее работы "упирается" в тот факт, что число .255 выглядит как 1111 1111.
Короче, нужно проанализировать состояние бита №7, сделать "оргвыводы", и все дела.

;------------------------------------
; Вариант концовки №2.
;------------------------------------
decf Temp,F ; Temp - 1 = ...
btfss Temp,7 ; В бит №7 регистра Temp 0 или 1 ?
goto $-7 ; Если 0, то на индикацию выводится
; следующий байт массива.
; Если это 1, то массив выведен и
; программа исполняется далее.

Почему это представляет наибольший интерес?


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

Вернусь к своим "котлетам".


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

18
Если Вы думаете, что я сейчас буду заниматься тем, что я называю "на колу мочало",
то Вы ошибаетесь.
Все уже объяснено выше.
Разница только в номере страницы и коде картинки:

;--------------------------------------------------------------------------------
; Вывод данных на индикацию в 8-ю страницу ("паровоз и 6 вагонов").
;--------------------------------------------------------------------------------
call STRANICA_8 ;
;---> Возврат по стеку из ПП STRANICA_8
call STOLB_1 ;
;---> Возврат по стеку из ПП STOLB_1
call ZERO ;
;---> Возврат по стеку из ПП ZERO

movf N_Zapoln,W ;
movwf Temp ;

call TEXT_5 ; Аналогично,


movwf PortC ; только для ПП TEXT_5.
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;

decf Temp,F ;
btfss Temp,7 ;
goto $-7 ;
.....................................
.....................................

;================================================================================
; Таблица конфигурации байтов, которыми заполняется шкала.
; С "выкрутасами" ("паровоз и 6 вагонов").
;================================================================================
TEXT_5 movlw high STR_5 ;
movwf PCLATH ;

movf Temp,W ; Аналогично.


addlw low STR_5 ;
btfsc Status,C ;
incf PCLATH,F ;
movf Temp,W ;

addwf PCL,F ;
STR_5 Dt 0x70,0xF8,0xFC,0x74,0x7E,0xF4,0xFC,0x74
Dt 0x7C,0xFC,0xFC,0x7C,0x7C,0xFC,0xFC,0x78
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C
Dt 0x40,0x7C,0xE4,0xE4,0x7C,0xE4,0xE4,0x7C

Картинку "ваял" в программе Петра Высочанского (KS0108).


Кто желает, тот может "сваять" свою. Нет проблем.
Меняете код и получаете вожделенное.
Вопрос: "Можно ли объединить таблицы ПП TEXT_4 и TEXT_5 в одну"?
Ответ: да за ради Бога (см. предыдущий подраздел).
Изменяя величину задержки ПП PAUSE, можно регулировать скорость "подсчета"
попугаев. Принципиальная схема - без изменений.
"Шейте", включайте и любуйтесь. Надеюсь, что улыбнетесь.

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

19