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

2-1/18.

Реализация шкального индикатора до 128 позиций (в данном случае -


на 100). Реализация нескольких шкальных индикаторов (в данном случае, двух:
на 100 и 128 позиций).

Теперь, с целью выбора направления "вектора тяги", нужно более конкретно


разобраться с "бегущей строкой".
Иначе, будут иметь место быть "два зайца, разбегающихся в разных направлениях".
Дело в том, что, в MT-12864… есть автоинкремент, но нет автодекремента.
Иными словами, если "уповать" на то, что есть, то надпись будет выводиться на
индикацию не справа налево, а слева направо, что, как Вы сами понимаете, создает
значительные неудобства в процессе осознания того, что выводится.
Вопрос: "Тупик"?
Ответ: это не тупик, а всего-навсего банальный, программный "геморрой" (не
смертельно, но хлопотно).
Просто нужно "сваять" процедуру, которая обеспечивает последовательную адресацию
в направлении справа налево ("принудительный автодекремент"), и все дела.
Плюс, "обслуживающая" специфика, связанная с этим "телодвижением".
И в самом деле, ведь никто не отменял "принудительную" (программную) адресацию.
Программно адресоваться можно как угодно (в пределах дозволенного), в том числе и
в части касающейся "клонирования" ехидно отсутствующего ("не виноватый я".
Разработчики подвели) автодекремента.
Вот и получается, что для организации "человеческой, бегущей строки", нужно
озаботиться программными "делами".
Это вполне реально, но сейчас я этим заниматься не буду.
Если в будущем возникнет такая потребность, то можно и озаботиться.
Сейчас же, я займусь "шкальными делами", как наиболее соответствующими "текущему
моменту" (в них, как раз и нужно выводить данные слева направо).
Итак, имеется шкала с максимальным количеством градаций = .64.
Дальше нельзя. Страница графического модуля не резиновая.
А вот "завожделелось" чего-то более длинного и могучего …
Например, шкалу, с максимальным количеством градаций = .100.
И чтобы без всяких "разрывов" (в одну линию).
Вопрос: "Как быть"?
Ответ: нужно "включить в работу" "одноименную" страницу 2-го кристалла.
Например, имеет место быть 80 попугаев, и шкала формируется в седьмых страницах
графического модуля.
Значит, всю "линию" 7-й страницы 1-го кристалла нужно "зачернить", а "линию длиной" в
80 – 64 = 16 попугаев
нужно вывести в 7-ю страницу 2-го кристалла (начиная с нулевого адреса).
Вот и вся "концепция".
С одной стороны, она "пахнет детским садом", а с другой стороны, она "пахнет
N-количеством высших образований", причем, не формальных и качественных.
Наличие в природе таких фактов, наводит на умнейшие мысли о единстве и борьбе
противоположностей.
Если кто-то из Вас является философом-электронщиком ("гусаром-схимником"), то вот
Вам и "глобальная", философская тема, в случае успешной отработки которой, вполне
можно получить не только степень, но и Нобелевскую премию.
Мои задачи гораздо скромнее & "заземленнее", и в соответствии с ними, нужно было
озаботиться реализацией конкретного (не "глобального"), "двуедино пахнущего" (см.
выше).
Озаботился.
Сначала, как и положено, "родилось бардальеро" (что естественно, то не безобразно),
но после приложения некоторых усилий, оно "превратилось" в то, что, на мой взгляд,
вполне приемлемо и может быть использовано в качестве "шкальной базы" ("толкача
шкального прогресса").
Получилось вот что (программа 12864_19.asm прилагается):

;********************************************************************************
; 12864_19.asm Одноканальный, шкальный индикатор на 100 позиций.
1
;********************************************************************************
.....................................
.....................................
;----------------------------------------------
; Объем программы: 1149 слов в памяти программ.
;================================================================================
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 - указатель страницы).
Reg1 equ 25h ; Регистр счетчика количества попугаев.
N_Zapoln1 equ 26h ; Регистр количества байтов заполнения шкалы
; (для 1-го кристалла).
N_Zapoln2 equ 27h ; Регистр количества байтов заполнения шкалы
; (для 2-го кристалла).
Flag equ 28h ; Указатель кристалла.
LED0 equ 30h ; Регистры, задействованные
LED1 equ 31h ; в ПП 2/10 преобразования.
;================================================================================
; Присвоение битам названий.
;================================================================================
.....................................
.....................................
;================================================================================
org 0 ; Начать выполнение программы с 0 адреса PC.
goto START ; Переход в ПП START.
;********************************************************************************

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Символ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "пробел".
;--------------------------------------------------------------------------------
Z_0....10
.....................................
;================================================================================
; Подпрограммы выбора страниц 1, 2, 3, 4, 5, 6, 7, 8.
;================================================================================
STRANICA_1...8
.....................................
;================================================================================
; Подпрограмма записи данных.
;================================================================================
WRITE_D
.....................................
;================================================================================
; Подпрограмма чтения данных.
;================================================================================
READ_D
.....................................
;================================================================================
2
; Подпрограмма стробирования.
;================================================================================
STROB
.....................................
;================================================================================
; Подпрограмма установки первого (самого левого) столбца страницы (адрес 00h).
;================================================================================
STOLB_1
.....................................
;================================================================================
; Подпрограмма заполнения страницы нулями.
;================================================================================
ZERO
.....................................
;================================================================================
; Подпрограмма выбора страницы, в случае совмещения 4-х таблиц,
; относящихся к одному кристаллу.
;================================================================================
VIBOR
.....................................
;================================================================================
; Подпрограмма числовой коррекции адреса "прыжка".
;================================================================================
N_STR
.....................................
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
PAUSE
.....................................
;================================================================================
; Подпрограмма выбора "обнуляемых" страниц.
;================================================================================
; При переходе в SBROS_STR, "бнуляются" 4, 8 и 7 страницы.
;---------------------------------------------------------
SBROS_STR call STRANICA_4 ; Выбор 4-й страницы.
;---> Возврат по стеку из ПП STRANICA_4
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
call STRANICA_8 ; Выбор 8-й страницы.
;---> Возврат по стеку из ПП STRANICA_8
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
;---------------------------------------------------------
; При переходе в SBROS_STR_1, "обнуляется" 7 страница.
;---------------------------------------------------------
SBROS_STR_1 call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; ПП записи в 6-ю страницу (в нее выводится картинка градуировки).
;================================================================================
ZAPIS_STR6
.....................................
;================================================================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START
.....................................
3
;================================================================================
; Инициализация графического модуля.
;================================================================================
.....................................
.....................................
;################################################################################
; Вывод на индикацию картинки 1-го "кадра".
;################################################################################
;*************************************
; Переход на 2-й кристалл.
;*************************************
.....................................
.....................................
;--------------------------------------------------------------------------------
; Запись картинки градуировки в 6-ю страницу 2-го кристалла.
;--------------------------------------------------------------------------------
call ZAPIS_STR6 ; Переход в ПП ZAPIS_STR6.
;---> Возврат по стеку из ПП ZAPIS_STR6
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 2-го кристалла (заполнение их нулями).
;--------------------------------------------------------------------------------
call SBROS_STR ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR
;*************************************
; Переход на 1-й кристалл.
;*************************************
.....................................
.....................................
;--------------------------------------------------------------------------------
; Запись картинки градуировки в 6-ю страницу 1-го кристалла.
;--------------------------------------------------------------------------------
call ZAPIS_STR6 ; Переход в ПП ZAPIS_STR6.
;---> Возврат по стеку из ПП ZAPIS_STR6
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 1-го кристалла (заполнение их нулями).
;--------------------------------------------------------------------------------
call SBROS_STR ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR
;################################################################################

;********************************************************************************
; А теперь можно "замерить" текущее количество попугаев.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Переход на 2-й кристалл.
;-------------------------------------
SNOVA bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;-------------------------------------
; Сброс 7 страницы 2-го кристалла.
;-------------------------------------
call SBROS_STR_1 ; Сброс 7 страницы 2-го кристалла.
;-------------------------------------
; Переход на 1-й кристалл.
;-------------------------------------
bsf PortB,E1 ; Включение 1-го кристалла.
bcf PortB,E2 ; Выключение 2-го кристалла.
;-------------------------------------
; Сброс 7 страницы 1-го кристалла.
;-------------------------------------
call SBROS_STR_1 ; Сброс 7 страницы 1-го кристалла.
;-------------------------------------
; Сброс указателя кристалла.
;-------------------------------------
clrf Flag ; Flag = 0.
4
;================================================================================
; "Закольцовка" счета и запись текущего количества попугаев
; в регистры оперативной памяти.
;================================================================================
incf Reg1,F ; Reg1 + 1 = ... (обеспечение "динамики")
movf Reg1,W ; Reg1 -> W

sublw .99 ; .99 - Reg1 = ...


btfss Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "-" (C=0 -> число от .100 и более),
; то Reg1 сбрасывается в 0.
goto $+2 ; Если "+" или =0 (C=1 -> число до .99
; включительно), то Reg1 не сбрасывается в 0.
clrf Reg1 ; А это сам сброс.

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


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

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод результата "подсчета" количества попугаев
; на индикацию в графический модуль.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Задание "координаты", с которой начнется запись байтов данных.
;--------------------------------------------------------------------------------
call STRANICA_5 ; Выбор 5-й страницы.
movlw b'01100000' ; Выбор адреса 33-го столбца (20h).
movwf PortC ; Вывод инструкции "Set Address" в порт С.
call STROB ; Строб под инструкцию.
;---> Возврат по стеку из ПП STROB
;--------------------------------------------------------------------------------
; Группа команд гашения незначащих нулей.
;--------------------------------------------------------------------------------
.....................................
.....................................
;--------------------------------------------------------------------------------
; "Администраторская" подпрограмма.
;--------------------------------------------------------------------------------
ADMIN
.....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;////////////////////////////////////////////////////////////////////////////////
; РАБОТА СО ШКАЛЬНЫМ ИНДИКАТОРОМ.
;////////////////////////////////////////////////////////////////////////////////
; Будем работать только в 1-м кристалле или в обеих? Анализ, "оргвыводы".
;================================================================================
movlw .64 ;
subwf N_Zapoln1,W ; N_Zapoln - .64 = ... (результат -> W).
btfss Status,C ; Результат "+" или "-" ?
goto $+5 ; Если "-" (C=0 -> число - до .63
; включительно), то работаем
; только в 1-м кристалле.
movwf N_Zapoln2 ; Если "+" или =0 (C=1 -> число от .64 и
; более), то
; 1. W (разница) -> N_Zapoln2 (подготовка
; данных для той части шкалы, которая "лежит"
; во 2-м кристалле,
5
bsf Flag,0 ; 2. Установка флага указателя кристалла
; (разрешение работы во 2-м кристалле)
movlw .63 ; 3. Подготовка к "сплошному" заполнению
movwf N_Zapoln1 ; шкалы в части касающейся 1-го кристалла.
;================================================================================
; Вывод данных на индикацию в 7-ю страницу 1-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
;--------------------------------------------------------------------------------
; Процедура вывода на индикацию массива байтов.
;--------------------------------------------------------------------------------
movf N_Zapoln1,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, то считается, что массив
; выведен и программа исполняется далее.
;--------------------------------------------------------------------------------
; Анализ состояния флага (бит №0 регистра Flag) указателя кристалла.
;--------------------------------------------------------------------------------
btfss Flag,0 ; Каково состояние флага указателя кристалла?
goto VIHOD ; Если Flag,0=0 (до .63 включительно), то
; группа команд работы со 2-м кристаллом
; обходится.
; Если Flag,0=1 (.64 и больше), то
; разрешается работа во 2-м кристалле.
;-------------------------------------
; Переход на 2-й кристалл.
;-------------------------------------
bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;================================================================================
; Вывод данных на индикацию в 7-ю страницу 2-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1

movf N_Zapoln2,W ;
movwf Temp ;

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


;---> Возврат по стеку из ПП TEXT_4 ; только для ПП TEXT_4.
movwf PortC ;
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
;---> Возврат по стеку из ПП WRITE_D

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

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
CIFRA
.....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;################################################################################
; ТАБЛИЦЫ ДАННЫХ 1-го "КАДРА".
;################################################################################
; "Счетверенные" данные 1, 2, 3, 5 страниц 2-го кристалла.
;================================================================================
TEXT_1
.....................................
;================================================================================
; "Счетверенные" данные 1, 2, 3, 5 страниц 1-го кристалла.
;================================================================================
TEXT_2
.....................................
;--------------------------------------------------------------------------------
; Данные 6-й страницы 1-го кристалла (код картинки градуировки).
;--------------------------------------------------------------------------------
TEXT_3 movlw high STR_3 ;
movwf PCLATH ;
;
movf Reg,W ;
addlw low STR_3 ; Аналогично.
btfsc Status,C ;
incf PCLATH,F ;
movf Reg,W ;

addwf PCL,F ;
STR_3 Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; Картинка
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; градуировки
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; (3Ch -
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; вертикальные
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; линии).
;################################################################################

;////////////////////////////////////////////////////////////////////////////////
; ТАБЛИЦА ДАННЫХ ШКАЛЫ (код картинки "ленты").
;////////////////////////////////////////////////////////////////////////////////
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 ;
7
STR_4 Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
;////////////////////////////////////////////////////////////////////////////////

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

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


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

Можно было "сваять" шкалу и на 128 позиций, но я "привязался" к количеству копеек


в рубле (по-моему, это наиболее универсально и доходчиво).

Работа программы
"Мать" - программа 12864_18.asm.
Старт, инициализация графического модуля и вывод на индикацию картинки 1-го
"кадра" - без изменений, за исключением записи в 6-ю страницу и "обнуления"
страниц.
Так как картинка градуировки выводится не в одну страницу, а в две, то получается 2
"клона".
По причине того, что с текстовой избыточностью не грех и побороться, я "состряпал"
ПП записи в 6-ю страницу (ZAPIS_STR6) и "вынес" ее в "обслугу".
Она вызывается командой call ZAPIS_STR6.
Если нужно вывести на индикацию, в тот или иной кристалл, картинку градуировки, то
исполняется эта команда, и все дела.
Так как картинка градуировки выводится на индикацию не в одну, а в две страницы,
то такой вызов происходит 2 раза.
Что касается "обнуления" страниц графического модуля, то в соответствии с
изменением картинки 1-го "кадра", изменился и порядок "обнуления" (в сторону
упрощения).

После вывода на индикацию картинки 1-го "кадра", начинаются "попугайные дела":

;********************************************************************************
; А теперь можно "замерить" текущее количество попугаев.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Переход на 2-й кристалл.
;-------------------------------------
SNOVA bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;-------------------------------------
; Сброс 7 страницы 2-го кристалла.
;-------------------------------------
call SBROS_STR_1 ; Сброс 7 страницы 2-го кристалла.
;-------------------------------------
; Переход на 1-й кристалл.
;-------------------------------------
bsf PortB,E1 ; Включение 1-го кристалла.

8
bcf PortB,E2 ; Выключение 2-го кристалла.
;-------------------------------------

; Сброс 7 страницы 1-го кристалла.


;-------------------------------------
call SBROS_STR_1 ; Сброс 7 страницы 1-го кристалла.

Вы видите начало циклической ПП SNOVA.


Она начинается с подготовительных операций.
Первым делом, в обеих кристаллах, организуются сбросы страниц.
В данном случае:

;================================================================================
; Подпрограмма выбора "обнуляемых" страниц.
;================================================================================
; При переходе в SBROS_STR, "бнуляются" 4, 8 и 7 страницы.
;---------------------------------------------------------
SBROS_STR call STRANICA_4 ; Выбор 4-й страницы.
;---> Возврат по стеку из ПП STRANICA_4
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
call STRANICA_8 ; Выбор 8-й страницы.
;---> Возврат по стеку из ПП STRANICA_8
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
;---------------------------------------------------------
; При переходе в SBROS_STR_1, "обнуляется" 7 страница.
;---------------------------------------------------------
SBROS_STR_1 call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.

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

Далее, к работе подготавливается регистр Flag:

;-------------------------------------
; Сброс указателя кристалла.
;-------------------------------------
clrf Flag ; Flag = 0.

Из названия должно быть понятно, что это регистр флагов.


В данном случае (один шкальный индикатор), задействуется один его бит (№0), но
если будет организовано несколько шкальных индикаторов, то и количество
задействованных битов будет бОльшим.
Речь о нем пойдет ниже.

Теперь нужно организовать "закольцовку" счета на числе .100:

;================================================================================
; "Закольцовка" счета и запись текущего количества попугаев
; в регистры оперативной памяти.
;================================================================================
incf Reg1,F ; Reg1 + 1 = ... (обеспечение "динамики")
9
movf Reg1,W ; Reg1 -> W

sublw .99 ; .99 - Reg1 = ...


btfss Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "-" (C=0 -> число от .100 и более),
; то Reg1 сбрасывается в 0.
goto $+2 ; Если "+" или =0 (C=1 -> число до .99
; включительно), то Reg1 не сбрасывается в 0.
clrf Reg1 ; А это сам сброс.

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


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

Она почти такая же, как и в "матери", но есть и существенные различия:

1. Проверка флага Z заменена на проверку флага C.


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

sublw .100
btfsc Status,Z
"лепим"
sublw .99
btfss Status,C

и все дела.
Вопрос: "Почему .99, а не .100" ?
Ответ: потому, что нулевой результат считается положительным.

2. "Безадресное" movwf N_Zapoln заменено на "адресное" movwf N_Zapoln1.


Подтекст: регистр N_Zapoln1 ориентирован на 1-й кристалл.
Далее, будет иметь место быть регистр N_Zapoln2, который будет ориентирован на 2-й
кристалл.
Так оно как-то "понятийносподручнее".

10
В результате всех этих "манипуляций" (суть "расписана" в предыдущем подразделе), с
учетом сказанного, текущее количество попугаев "осядет" и в регистре Mem1 (для ПП
BIN2_10), и в регистре N_Zapoln1 (исходные данные для работы в 7-й странице 1-го
кристалла).

Далее - 2/10 преобразование. Изменений нет.


Далее - вывод результата "подсчета" количества попугаев на индикацию в графический
модуль (в форме символов цифр). Изменений нет.

Итак, исходные данные, для шкального индикатора (текущее количество попугаев),


подготовлены.
Далее, ничто не мешает начать работу со шкальным индикатором:

;////////////////////////////////////////////////////////////////////////////////
; РАБОТА СО ШКАЛЬНЫМ ИНДИКАТОРОМ.
;////////////////////////////////////////////////////////////////////////////////
; Будем работать только в 1-м кристалле или в обеих? Анализ, "оргвыводы".
;================================================================================
movlw .64 ;
subwf N_Zapoln1,W ; N_Zapoln - .64 = ... (результат -> W).
btfss Status,C ; Результат "+" или "-" ?
goto $+5 ; Если "-" (C=0 -> число - до .63
; включительно), то работаем
; только в 1-м кристалле.
movwf N_Zapoln2 ; Если "+" или =0 (C=1 -> число от .64 и
; более), то
; 1. W (разница) -> N_Zapoln2 (подготовка
; данных для той части шкалы, которая "лежит"
; во 2-м кристалле,
bsf Flag,0 ; 2. Установка флага указателя кристалла
; (разрешение работы во 2-м кристалле)
movlw .63 ; 3. Подготовка к "сплошному" заполнению
movwf N_Zapoln1 ; шкалы в части касающейся 1-го кристалла.

Сначала нужно получить ответ на вопрос: "В регистре N_Zapoln1 лежит количество
попугаев до .63 включительно или более" (работаем только в 1-м кристалле или в
обеих)?
Для выяснения этого, организуется сравнение содержимого регистра N_Zapoln1 с
константой .64, после чего производится проверка состояния флага C.
После этого, имеют место быть 2 сценария:

1. Результат вычитания отрицательный (заем).


То есть, в регистре N_Zapoln1 "лежит" число до .63 включительно.
Проще говоря, зачем "лезть" во 2-й кристалл, если "линия до него не доползла"?
И нечего в него "лезть".
Зачем "заниматься бестолковкой" (подтверждать ранее установленные нули)?.
Обойти остальные 4 команды, и все дела (goto $+5).
При этом, флаг указателя кристалла (бит №0 регистра Flag) будет опущен, так как, в
регистре Flag, ранее, был предустановлен 0.
В дальнейшем, это позволит банально обойти всю процедуру вывода данных на
индикацию во 2-й кристалл.
От этого, скоростные качества программы только улучшатся.

2. Результат вычитания положительный.


То есть, в регистре N_Zapoln1 "лежит" число от .64 и более.
А вот в этом случае, "линия доползла" до 2-го кристалла, и в дальнейшем, вывод
данных на индикацию во 2-й кристалл игнорировать нельзя.
Значит, нужно подготовить массив байтов, предназначенный для вывода на индикацию
во 2-й кристалл.
Что сие означает?

11
Это означает всего-навсего то, что результат вычитания ("оседает" в W) нужно
банально скопировать в регистр N_Zapoln2 (movwf N_Zapoln2).

Далее, содержимое этого регистра будет определять количество байтов в массиве


байтов, который будет выведен на индикацию в 7-ю страницу 2-го кристалла.
Теперь нужно озаботиться выставлением признака работы со 2-м кристаллом
(bsf Flag,0).
После этого, в дальнейшем, процедура вывода данных на индикацию во 2-й кристалл,
обойдена не будет (будет отработана в полном объеме).
Далее, нужно озаботиться "зачернением" всей 7-й страницы 1-го кристалла (см.
"вышележащий" пример с числом .80).
То есть, в регистр N_Zapoln1, просто записывется фиксированное число .63 (3Fh).
Итак, данные подготовлены:

- в регистре N_Zapoln1, "лежит" количество байтов, которые нужно


вывести на индикацию в 7-ю страницу 1-го кристалла (выводятся всегда),
- в регистре N_Zapoln2, "лежит" количество байтов, которые нужно
вывести на индикацию в 7-ю страницу 2-го кристалла, в случае,
если Flag,0=1.
- в бите №0 регистра Flag, "лежит" признак обхода (0) или полной
отработки (1) процедуры вывода на индикацию, в 7-ю страницу 2-го
кристалла, массива байтов, число которых задается содержимым регистра
N_Zapoln2.

Теперь можно озаботиться и выводом "нарытого" на индикацию.


Сначала, в 7-ю страницу 1-го кристалла:

;================================================================================
; Вывод данных на индикацию в 7-ю страницу 1-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
;--------------------------------------------------------------------------------
; Процедура вывода на индикацию массива байтов.
;--------------------------------------------------------------------------------
movf N_Zapoln1,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, то считается, что массив
; выведен и программа исполняется далее.

Происходит адресация к 1-му столбцу 7-й страницы (ранее была установлена 5-я
страница).
Далее, следует "стандартная" процедура вывода на индикацию массива байтов.
Но с "выкрутасом": в регистр Temp копируется не фиксированная константа .64 (как
это делалось ранее), а содержимое регистра N_Zapoln1 (заранее "заготовленное"
количество байтов, подлежащих выводу на индикацию в шкалу).

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

После того, как эта процедура будет отработана, возникает вопрос: "А что дальше?
Обходить или нет процедуру вывода данных на индикацию, в 7-ю страницу
2-го кристалла"?
Значит, нужно устроить проверку флага указателя кристалла:

;--------------------------------------------------------------------------------
; Анализ состояния флага (бит №0 регистра Flag) указателя кристалла.
;--------------------------------------------------------------------------------
btfss Flag,0 ; Каково состояние флага указателя кристалла?
goto VIHOD ; Если Flag,0=0 (до .63 включительно), то
; группа команд работы со 2-м кристаллом
; обходится.
; Если Flag,0=1 (.64 и больше), то
; разрешается работа во 2-м кристалле.

Она очень проста.


Если Flag,0 = 0, то процедура вывода данных на индикацию, в 7-ю страницу
2-го кристалла, обходится (goto VIHOD), а если Flag,0 = 1, то процедура вывода данных
на индикацию, в 7-ю страницу 2-го кристалла, отрабатывается полностью.
Предположим, что имеет место быть второе:

;-------------------------------------
; Переход на 2-й кристалл.
;-------------------------------------
bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;================================================================================
; Вывод данных на индикацию в 7-ю страницу 2-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1

movf N_Zapoln2,W ;
movwf Temp ;

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


;---> Возврат по стеку из ПП TEXT_4 ; только для ПП TEXT_4.
movwf PortC ;
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
;---> Возврат по стеку из ПП WRITE_D

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

Сначала, осуществляется переход на 2-й кристалл.


По идее, после этого, к 7-й странице адресоваться не нужно, так как она была
установлена ранее.
13
И к 1-му столбцу тоже адресоваться не нужно, так как переход на работу во 2-й
кристалл сопровождается полным заполнением 7-й страницы 1-го кристалла (см.
установку константы .63).

А так как счетчик адреса графического модуля работает по кольцу, то результатом


следующего автоинкремента будет установка адреса столбца = 00h.
То есть, в данном случае, можно не переходить в 1-й столбец 7-й страницы.
В этом можно убедиться, заблокировав команды call STRANICA_7 и call STOLB_1.
Но я их оставил, так в ходе дальнейших, более расширенных "экспериментов", по
причине отсутствия этих команд, происходили различные адресные "чудеса" (кстати,
принеприятные).
А с ними à полная красота и ляпота.
Далее, следует такое же "на колу мочало", что и в случае вывода данных на
индикацию в 7-ю страницу 1-го кристалла.
Разница только в том, что количество байтов массива задается не содержимым
регистра N_Zapoln1, а содержимым регистра N_Zapoln2.
При этом, используется одна и та же таблица вычисляемого перехода
(см. ПП TEXT_4).
Далее - задержка на 0,3 сек. и "закольцовка" на следующий цикл программы
(goto SNOVA).
В случае обхода (Flag,0 = 0), процедура вывода данных на индикацию, в 7-ю страницу
2-го кристалла, просто не исполняется, и в ней, "до лучших времен", "заторчит"
результат сброса (нули), который производится в начале ПП SNOVA.
Градуировка - простейшая.
То есть, маркеры выставляются на каждом 8-м байте, начиная с 1-й позиции таблицы
подпрограммы TEXT_3.
В этом случае, достаточно и одной "градуировочной" таблицы.
Она используется при формировании картики градуировки в 6-х страницах обеих
кристаллов.
Результат работы программы 12864_19.asm проиллюстрирован этими фото:

Следующий вопрос "повестки дня": "Можно ли сваять две шкалы до 128-ми позиций
каждая"?
Ответ: очень даже можно. Можно даже и восемь.
На 8 "замахиваться" не буду, а две штуки "сваяю".
Просто добавлю, к уже имеющейся 100-позиционной шкале, 128-ми позиционную шкалу.
Их можно "привязать" к результатам двух функционально различных замеров
(например, попугаев и слонов), но я сейчас не буду усложнять то, что, на данном
этапе развития, должно выглядеть как можно проще.
Пока обойдусь одними попугаями, но для разнообразия, в "новорожденной" шкале,
будет визуально отображен счет не штук, а пар.
Проще говоря, под верхнюю шкалу будет задействован один инкремент, а под нижнюю
шкалу - два.
Кроме того, в нижней шкале будут задействованы все 128 позиций.
Получилась вот такая "учебно-тренировочная каракатица" (ругаю любя):

14
А вообще-то, это нужно видеть в "живой железяке" (в динамике).
Получится гораздо симпатичнее и интереснее.
Числу попугаев будут соответствовать показания верхней шкалы.
Вообще-то и показания нижней шкалы тоже будет ему соответствовать, но с
корректирующими поправками, связанными с умножением на 2 (2 инкремента) и с
учетом того, что .100 х 2 = .200, а количество позиций в нижней шкале - .128.
Пока, это не принципиально важно.
Потом, если нужно, можно и "подрихтовать" (дело техники).
Сейчас же, принципиально важным является "въезд" в программную "механику ваяния"
нескольких шкал, а заодно и "тренировка" в назначении нужного количества градаций.

;********************************************************************************
; 12864_20.asm Двухканальный, шкальный индикатор на 100 и на 128 позиций.
;********************************************************************************
.....................................
.....................................
;----------------------------------------------
; Объем программы: 1198 слов в памяти программ.
;================================================================================
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 - указатель страницы).
Reg1 equ 25h ; Регистр счетчика количества попугаев
; верхней шкалы.
N_Zapoln1 equ 26h ; Регистр количества байтов заполнения
; верхней шкалы (для 1-го кристалла).
N_Zapoln2 equ 27h ; Регистр количества байтов заполнения
; верхней шкалы (для 2-го кристалла).
Flag equ 28h ; Указатель кристалла.
Zap_128_1 equ 29h ; Регистр количества байтов заполнения
; нижней шкалы (для 1-го кристалла).
Zap_128_2 equ 2Ah ; Регистр количества байтов заполнения
; нижней шкалы (для 2-го кристалла).
R_1 equ 2Bh ; Регистр счетчика количества попугаев
; нижней шкалы.
LED0 equ 30h ; Регистры, задействованные
LED1 equ 31h ; в ПП 2/10 преобразования.
15
;================================================================================
; Присвоение битам названий.
;================================================================================
.....................................
.....................................
;================================================================================
org 0 ; Начать выполнение программы с 0 адреса PC.
goto START ; Переход в ПП START.
;********************************************************************************

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм, обеспечивающая "побайтное" формирование символов цифр
; ("знакогенератор").
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Символ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "пробел".
;--------------------------------------------------------------------------------
Z_0....10
.....................................
;================================================================================
; Подпрограммы выбора страниц 1, 2, 3, 4, 5, 6, 7, 8.
;================================================================================
STRANICA_1...8
.....................................
;================================================================================
; Подпрограмма записи данных.
;================================================================================
WRITE_D
.....................................
;================================================================================
; Подпрограмма чтения данных.
;================================================================================
READ_D
.....................................
;================================================================================
; Подпрограмма стробирования.
;================================================================================
STROB
.....................................
;================================================================================
; Подпрограмма установки первого (самого левого) столбца страницы (адрес 00h).
;================================================================================
STOLB_1
.....................................
;================================================================================
; Подпрограмма заполнения страницы нулями.
;================================================================================
ZERO
.....................................
;================================================================================
; Подпрограмма выбора страницы, в случае совмещения 4-х таблиц,
; относящихся к одному кристаллу.
;================================================================================
VIBOR
.....................................
;================================================================================
; Подпрограмма числовой коррекции адреса "прыжка".
;================================================================================
N_STR
.....................................
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
PAUSE
.....................................
16
;================================================================================
; Подпрограмма выбора "обнуляемых" страниц.
;================================================================================
; При переходе в SBROS_STR, "бнуляются" 4, 8 и 7 страницы.
;---------------------------------------------------------
SBROS_STR call STRANICA_4 ; Выбор 4-й страницы.
;---> Возврат по стеку из ПП STRANICA_4
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
;---------------------------------------------------------
; При переходе в SBROS_STR_1, "обнуляются" 7 и 8 страницы.
;---------------------------------------------------------
SBROS_STR_1 call STRANICA_8 ; Выбор 8-й страницы.
;---> Возврат по стеку из ПП STRANICA_8
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call ZERO ; И заполнение ее нулями.
;---> Возврат по стеку из ПП ZERO
return ; Возврат по стеку в то место, откуда
; произошел вызов подпрограммы.
;================================================================================
; ПП записи в 6-ю страницу (в нее выводится картинка градуировки).
;================================================================================
ZAPIS_STR6
.....................................
;================================================================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START
.....................................
clrf Reg1 ; Сброс регистра счетчика количества попугаев
; верхней шкалы.
clrf R_1 ; Сброс регистра счетчика количества попугаев
; нижней шкалы.
.....................................
;================================================================================
; Инициализация графического модуля.
;================================================================================
.....................................
.....................................
;################################################################################
; Вывод на индикацию картинки 1-го "кадра".
;################################################################################
;*************************************
; Переход на 2-й кристалл.
;*************************************
.....................................
.....................................
;--------------------------------------------------------------------------------
; Запись картинки градуировки в 6-ю страницу 2-го кристалла.
;--------------------------------------------------------------------------------
call ZAPIS_STR6 ; Переход в ПП ZAPIS_STR6.
;---> Возврат по стеку из ПП ZAPIS_STR6
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 2-го кристалла (заполнение их нулями).
;--------------------------------------------------------------------------------
call SBROS_STR ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR
;*************************************
17
; Переход на 1-й кристалл.
;*************************************
.....................................
.....................................
;--------------------------------------------------------------------------------
; Запись картинки градуировки в 6-ю страницу 1-го кристалла.
;--------------------------------------------------------------------------------
call ZAPIS_STR6 ; Переход в ПП ZAPIS_STR6.
;---> Возврат по стеку из ПП ZAPIS_STR6
;--------------------------------------------------------------------------------
; Запись в 4, 7, 8 страницы 1-го кристалла (заполнение их нулями).
;--------------------------------------------------------------------------------
call SBROS_STR ; Переход в ПП "обнуления" страниц.
;---> Возврат по стеку из ПП SBROS_STR
;################################################################################

;********************************************************************************
; А теперь можно "замерить" текущее количество попугаев.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Переход на 2-й кристалл.
;-------------------------------------
SNOVA bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;-------------------------------------
; Сброс 7 страницы 2-го кристалла.
;-------------------------------------
call SBROS_STR_1 ; Сброс 7 и 8 страниц 2-го кристалла.
;-------------------------------------
; Переход на 1-й кристалл.
;-------------------------------------
bsf PortB,E1 ; Включение 1-го кристалла.
bcf PortB,E2 ; Выключение 2-го кристалла.
;-------------------------------------
; Сброс 7 страницы 1-го кристалла.
;-------------------------------------
call SBROS_STR_1 ; Сброс 7 и 8 страниц 1-го кристалла.
;-------------------------------------
; Сброс указателя кристалла.
;-------------------------------------
clrf Flag ; Flag = 0.
;================================================================================
; "Закольцовка" счета и запись текущего количества попугаев
; в регистры оперативной памяти (ДЛЯ ВЕРХНЕЙ ШКАЛЫ).
;================================================================================
incf Reg1,F ; Reg1 + 1 = ... (обеспечение "динамики")
movf Reg1,W ; Reg1 -> W

sublw .99 ; .99 - Reg1 = ...


btfss Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "-" (C=0 -> число от .100 и более),
; то Reg1 сбрасывается в 0.
goto $+2 ; Если "+" или =0 (C=1 -> число до .99
; включительно), то Reg1 не сбрасывается в 0.
clrf Reg1 ; А это сам сброс.

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


movwf Mem1 ; в Mem1 (для BIN2_10) и в N_Zapoln1 (для
movwf N_Zapoln1 ; выбора количества байтов заполнения верхней
; шкалы).
;--------------------------------------------------------------------------------
; Теперь, текущее, двоичное количество попугаев нужно
; стандартно перевести в "набор" 2/10 чисел.
18
;--------------------------------------------------------------------------------
call BIN2_10 ; Переход в ПП 2/10 преобразования
; (то, что нужно преобразовать,
; "лежит" в Mem1).
;---> Возврат по стеку из ПП BIN2_10
;================================================================================
; "Закольцовка" счета и запись текущего количества попугаев в регистры
; оперативной памяти (ДЛЯ НИЖНЕЙ ШКАЛЫ).
;================================================================================
incf R_1,F ; Обеспечение "динамики":
incf R_1,F ; R_1 + 2 = ...

movf R_1,W ; R_1 -> W


sublw .127 ; .127 - R_1 = ...
btfss Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "-" (C=0 -> число от .128 и более),
; то R_1 сбрасывается в 0.
goto $+2 ; Если "+" или =0 (C=1 -> число до .127
; включительно), то R_1 не сбрасывается в 0.
clrf R_1 ; А это сам сброс.
movf R_1,W ; В любом случае, содержимое R_1 копируется в
movwf Zap_128_1 ; N_Zap_128_1 (для выбора количества байтов
; заполнения нижней шкалы).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Вывод результата "подсчета" количества попугаев
; на индикацию в графический модуль.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Задание "координаты", с которой начнется запись байтов данных.
;--------------------------------------------------------------------------------
call STRANICA_5 ; Выбор 5-й страницы.
movlw b'01100000' ; Выбор адреса 33-го столбца (20h).
movwf PortC ; Вывод инструкции "Set Address" в порт С.
call STROB ; Строб под инструкцию.
;---> Возврат по стеку из ПП STROB
;--------------------------------------------------------------------------------
; Группа команд гашения незначащих нулей.
;--------------------------------------------------------------------------------
.....................................
.....................................
;--------------------------------------------------------------------------------
; "Администраторская" подпрограмма.
;--------------------------------------------------------------------------------
ADMIN
.....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;////////////////////////////////////////////////////////////////////////////////
; РАБОТА С ВЕРХНЕЙ ШКАЛОЙ.
;////////////////////////////////////////////////////////////////////////////////
; Будем работать только в 1-м кристалле или в обеих? Анализ, "оргвыводы".
;================================================================================
movlw .64 ;
subwf N_Zapoln1,W ; N_Zapoln - .64 = ... (результат -> W).
btfss Status,C ; Результат "+" или "-" ?
goto $+5 ; Если "-" (C=0 -> число - до .63
; включительно), то работаем только в 1-м
; кристалле.
movwf N_Zapoln2 ; Если "+" или =0 (C=1 -> число от .64 и
; более), то:
; 1. W (разница) -> N_Zapoln2 (подготовка
; данных для той части шкалы, которая "лежит"
; во 2-м кристалле.
bsf Flag,0 ; 2. Установка флага указателя кристалла
; (разрешение работы во 2-м кристалле).
movlw .63 ; 3. Подготовка к "сплошному" заполнению
movwf N_Zapoln1 ; шкалы в части касающейся 1-го кристалла.
19
;================================================================================
; Вывод данных на индикацию в 7-ю страницу 1-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
;--------------------------------------------------------------------------------
; Процедура вывода на индикацию массива байтов.
;--------------------------------------------------------------------------------
movf N_Zapoln1,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, то считается, что массив
; выведен и программа исполняется далее.
;--------------------------------------------------------------------------------
; Анализ состояния флага (бит №0 регистра Flag) указателя кристалла.
;--------------------------------------------------------------------------------
btfss Flag,0 ; Каково состояние флага указателя кристалла?
goto VIHOD ; Если Flag,0=0 (до .63 включительно), то
; группа команд работы со 2-м кристаллом
; обходится.
; Если Flag,0=1 (.64 и больше), то
; разрешается работа во 2-м кристалле.
;-------------------------------------
; Переход на 2-й кристалл.
;-------------------------------------
bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;================================================================================
; Вывод данных на индикацию в 7-ю страницу 2-го кристалла.
;================================================================================
call STRANICA_7 ; Выбор 7-й страницы.
;---> Возврат по стеку из ПП STRANICA_7
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1

movf N_Zapoln2,W ;
movwf Temp ;

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


;---> Возврат по стеку из ПП TEXT_4 ; только для ПП TEXT_4.
movwf PortC ;
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
;---> Возврат по стеку из ПП WRITE_D

decf Temp,F ;
btfss Temp,7 ;
goto $-7 ;
;////////////////////////////////////////////////////////////////////////////////
; РАБОТА С НИЖНЕЙ ШКАЛОЙ.
;////////////////////////////////////////////////////////////////////////////////
20
; Переход на 1-й кристалл.
;-------------------------------------
VIHOD bsf PortB,E1 ; Включение 1-го кристалла.
bcf PortB,E2 ; Выключение 2-го кристалла.
;================================================================================
; Будем работать только в 1-м кристалле или в обеих? Анализ, "оргвыводы".
;================================================================================
movlw .64 ;
subwf Zap_128_1,W ;
btfss Status,C ; Аналогично, только для регистров
goto $+5 ; Zap_128_1 и Zap_128_2.
movwf Zap_128_2 ;
bsf Flag,1 ;
movlw .63 ;
movwf Zap_128_1 ;
;================================================================================
; Вывод данных на индикацию в 8-ю страницу 1-го кристалла.
;================================================================================
call STRANICA_8 ; Выбор 8-й страницы.
;---> Возврат по стеку из ПП STRANICA_8
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1
;--------------------------------------------------------------------------------
; Процедура вывода на индикацию массива байтов.
;--------------------------------------------------------------------------------
movf Zap_128_1,W ;
movwf Temp ;
call TEXT_4 ;
movwf PortC ; Аналогично, только для
movlw high WRITE_D; регистра Zap_128_1.
movwf PCLATH ;
call WRITE_D ;
decf Temp,F ;
btfss Temp,7 ;
goto $-7 ;
;--------------------------------------------------------------------------------
; Анализ состояния флага (бит №1 регистра Flag) указателя кристалла.
;--------------------------------------------------------------------------------
btfss Flag,1 ; Аналогично, только для бита №1 регистра
goto VIHOD_1 ; Flag и переход происходит на метку VIHOD_1.
;-------------------------------------
; Переход на 2-й кристалл.
;-------------------------------------
bcf PortB,E1 ; Выключение 1-го кристалла.
bsf PortB,E2 ; Включение 2-го кристалла.
;================================================================================
; Вывод данных на индикацию в 8-ю страницу 2-го кристалла.
;================================================================================
call STRANICA_8 ; Выбор 8-й страницы.
;---> Возврат по стеку из ПП STRANICA_8
call STOLB_1 ; Выбор 1-го столбца страницы.
;---> Возврат по стеку из ПП STOLB_1

movf Zap_128_2,W ;
movwf Temp ;

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


;---> Возврат по стеку из ПП TEXT_4 ; только для ПП TEXT_4.
movwf PortC ;
movlw high WRITE_D;
movwf PCLATH ;
call WRITE_D ;
;---> Возврат по стеку из ПП WRITE_D

decf Temp,F ;
btfss Temp,7 ;
21
goto $-7 ;
;////////////////////////////////////////////////////////////////////////////////

VIHOD_1 call PAUSE ; Задержка 0,3 сек.


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

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Группа подпрограмм вывода на индикацию символов цифр.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
CIFRA
.....................................
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

;################################################################################
; ТАБЛИЦЫ ДАННЫХ 1-го "КАДРА".
;################################################################################
; "Счетверенные" данные 1, 2, 3, 5 страниц 2-го кристалла.
;================================================================================
TEXT_1
.....................................
;================================================================================
; "Счетверенные" данные 1, 2, 3, 5 страниц 1-го кристалла.
;================================================================================
TEXT_2
.....................................
;--------------------------------------------------------------------------------
; Данные 6-й страницы 1-го кристалла (код картинки градуировки).
;--------------------------------------------------------------------------------
TEXT_3 movlw high STR_3 ;
movwf PCLATH ;
;
movf Reg,W ;
addlw low STR_3 ; Аналогично.
btfsc Status,C ;
incf PCLATH,F ;
movf Reg,W ;

addwf PCL,F ;
STR_3 Dt 0xFC,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; Картинка
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; градуировки
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; (3Ch -
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; вертикальные
Dt 0x3C,0x08,0x08,0x08,0x08,0x08,0x08,0x08 ; линии).
;################################################################################

;////////////////////////////////////////////////////////////////////////////////
; ТАБЛИЦА ДАННЫХ ШКАЛЫ (код картинки "ленты").
;////////////////////////////////////////////////////////////////////////////////
TEXT_4 movlw high STR_4 ;
movwf PCLATH ;

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


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

22
addwf PCL,F ;
STR_4 Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
Dt 0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC
;////////////////////////////////////////////////////////////////////////////////

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

Программа 12864_20.asm прилагается.


Красным цветом выделено то, что относится к нижней шкале.
Собственно говоря, и объяснять-то особо нечего, так как последовательно исполняются
две, в принципе, одинаковые процедуры.
Разница только в деталях (регистр Flag используется в обеих случаях, только
задействуются разные его биты):

- в названиях регистров: вместо Reg1 à R_1, вместо N_Zapoln1 à


Zap_128_1, вместо N_Zapoln2 à Zap_128_2,
- в двух инкрементах содержимого регистра R_1, вместо одного инкремента
содержимого регистра Reg1,
- в "номинале закольцовки" счета, так как количество градаций шкалы
возросло с .100 до .128,
- в отсутствии копирования текущего, числового значения количества
попугаев в регистр Mem1 (для ПП BIN2_10), так как это копирование было
произведено ранее,
- в дополнительном задействовании еще одного флага указателя кристалла
(бит №1 регистра Flag),
- в "превращении" одной метки VIHOD в две: VIHOD и VIHOD_1. Кроме того,
что это необходимо для организации обходов (само собой), это
необходимо и для обеспечения последовательного вывода на индикацию
картинок шкал.

В каждом полном цикле работы программы, первой выводится картинка верхней


шкалы, а второй - картинка нижней шкалы.
Левые половины этих картинок (1-й кристалл) выводятся на индикацию всегда, а
правые половины этих картинок (2-й кристалл) могут либо не выводиться на
индикацию (текущее, числовое значение количества попугаев от .0 до .63), либо
выводиться (текущее, числовое значение количества попугаев равно или более .64).
О градуировке.
В данном случае, применена самая простая, горизонтальная градуировка: метки
выставляются через каждые 8 позиций (а можно и через каждые 16 и 32 позиции).
Поэтому можно обойтись одной таблицей.
В том случае, когда метки нужно равномерно выставить, например, через количество
позиций, не равных или не кратных 8-ми, нужно работать либо с двумя таблицами
(для каждого кристалла - своя), либо с одной, но при условии организации исходного,
адресного запроса не 1-го столбца соответствующей страницы 2-го кристалла, а того,
который обеспечивает равномерность градуировки.

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

23