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

2-1/9.

Реализация вертикального смещения отображаемой информации


(прокрутки). Смещение картинки вверх и вниз на заданное количество строк и
на заданное количество "кадров". Плюс, то же самое, но "покристалльно"
("рулевой" - PIC16F873A).

Направление "копания" - практическая реализация возможности прокрутки


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

В данном случае, в дисплее будут отображаться картинки "кадров", искусственно


"разорванных" на 2 части.
"Координаты границ разрывов" этих картинок будут "плавающими" (изменяющимися), и
они будут зависеть от числовых значений младших 6-ти битов инструкции "Display
StartLine" (в битах №№6 и 7 должны быть установлены единицы).
В них можно записать адрес той строки, с которой начнется формирование верхнего
"среза" картинки "кадра".
А так как можно последовательно задать любой адрес строки дисплея (от 1-й до
64-й), то верхний "срез" картинки "кадра" (а следовательно и всю картинку) можно
последовательно "двигать" по всему дисплею.
При этом, если содержимое "кадра" не изменяется (как в данном случае), то он как
бы "рвется" на 2 части, а "граница" этого разрыва будет последовательно смещаться
(в пределах дисплея) вверх или вниз.
"Разрыв" картинки "кадра" на 2 части объясняется тем, что оперативная память
графического модуля работает по кольцу.
Проще говоря, тот "обрывок кадра", который не успел сформироваться (на момент
окончания заполнения последней, 64-й строки дисплея), будет выведен на индикацию,
начиная с 1-й строки дисплея.
Вот Вам и суть принципа прокрутки (в контексте заданных условий).
Чтобы осуществить последовательную прокрутку "кадра", нужно, в конце каждого цикла
вывода на индикацию байтов данных "кадра", осуществить инкремент или декремент
содержимого младших 6-ти битов инструкции "Display StartLine" (еще раз напоминаю,
что в битах №№7 и 6 должны быть единицы).
В первом случае (инкремент), будет осуществлена последовательная прокрутка "кадра"
вверх, а во втором случае (декремент) - последовательная прокрутка "кадра" вниз.
Специфика этого "действа" заключается в том, что после инкремента или декремента
содержимого инструкции "Display StartLine", нужно озаботиться восстановлением
единиц в двух старших битах (№7 и №6) этой инструкции.
А как же иначе, ведь инкремент или декремент содержимого инструкции "Display
StartLine" может привести к совершенно безобразному "убийству" этой инструкции (в
бите №7 и/или бите №6, вместо единиц, ноль/нули), а соответственно и к
невозможности ее дальнейшего исполнения ("глюку").

1
Вот Вам и вся "сермяжная" суть.
Вопрос: "Как ее реализовать на практике"?
Ответ: молча. Со знанием дела и спокойствием мамонта. В рабочем порядке.
Лучше всего "раздробить" решение этой задачи на этапы:

1. Непрерывная прокрутка вверх/вниз (без остановки прокрутки).


2. Прокрутка вверх/вниз на заданное количество строк.
3. Прокрутка вверх/вниз на заданное количество полных сдвигов "кадра".
4. Прокрутка вверх/вниз вышеперечисленного, но только в пределах 1-го
или 2-го кристаллов.

Примечание: далее, "матерью назначена" программа 12864_1.asm.

1. Непрерывная прокрутка вверх/вниз (без остановки прокрутки).

а) непрерывная прокрутка вверх


Программа называется 12864_6.asm (прилагается).
Принципиальная схема под нее и под "нижележащие" программы à см. рис. 1
подраздела 1/4.
Пугаться "общего, массивного фона" не нужно, так как то, что нужно изменить в
"матери", вовсе не является чем-то заумным:
..................................
..................................

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

movlw b'11000000' ; Запись, в регистр выбора строки, инструкции


movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
..................................
;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
2
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ НЕПРЕРЫВНОГО ПРОКРУЧИВАНИЯ.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
incf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки + 1).
bsf Line,6 ; Обеспечение дальнейшего выполнения
bsf Line,7 ; инструкции "Display StartLine".
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).
;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................
;********************************************************************************
end ; Конец программы.

Красным цветом выделено то, что нужно добавить в "мать".

В "шапке" программы, нужно "прописать" регистр общего назначения Line.


В него будут записываться текущие инструкции "Display StartLine", числовые значения
которых, по ходу отработки программы (от цикла к циклу), будут меняться.
В ПП START, нужно добавить команду предустановки регистра Line, представляющую
собой инструкцию "Display StartLine", которая задает адрес строки по умолчанию
(ведь с чего-то нужно начинать?).
Проще говоря, какой адрес строки назначите, с того адреса строки дисплея, по
умолчанию, и начнется формирование "верхушки кадра".
В данном случае, по умолчанию, в младших 6-ти битах, выставлен адрес 1-й строки
дисплея (movlw b'11000000'), с обязательным учетом того, что для обеспечения
последующего выполнения инструкции "Display StartLine", в битах с №№7 и 6,
необходимо выставить единицы.
Если нужно начать с той строки дисплея, которая Вам больше по душе, то никаких
проблем нет. Меняете адрес строки и все дела.
Что "наменяете", с того и начнете.
Соответственно, в ПП установки текущей строки, нужно "перегрузить" содержимое
регистра Line в регистр W (movf Line,W).
После вывода на индикацию картинки "кадра", нужно "слегка подзадержаться" (в
данном случае, задержка составляет 0,3 сек., но можно и изменить ее "номинал").
Эта задержка определяет скорость прокрутки.
При назначении ее "номинала", нужно учитывать время полного поворота жидких
кристаллов (можно ориентироваться на значение 150…200 мс.).
Если эту задержку сделать слишком малой, то картинка будет "блеклой" (не
достаточно контрастной), а если большой, то "кадр" будет прокручиваться медленно.
После того, как задержка будет отработана, с целью последующего перехода на
следующую строку дисплея, нужно осуществить инкремент содержимого регистра Line,
что и миеет место быть (incf Line,F).
Но ведь инкремент может привести к изменению содержимого битов №№7 и 6 регистра
Line, то есть, к "убийству" инструкции "Display StartLine"?
И в самом деле, ведь, например, после 1111 1111 следует 0000 0000.
3
Вывод: каждый раз, после инкремента, в биты №№6 и 7 регистра Line, нужно
записывать единицы, что и имеет место быть (bsf Line,6 и bsf Line,7).
Это гарантирует последующую "жизнь" инструкции "Display StartLine".
Далее, нужно озаботиться тем, чтобы оба кристалла были включенными (по условию
задачи, прокрутка производится в обеих кристаллах).
Вопрос: "Почему этим нужно озаботиться"?
Ответ: потому, что на момент исполнения описываемой процедуры, включен только 2-й
кристалл (см. программу 12864_1.asm), а 1-й кристалл выключен.
Значит, нужно включить 1-й кристалл, что и имеет место быть (bsf PortB,E1).
После этого, можно "закольцовываться" на начало следующего цикла вывода данных
("кадра") на индикацию (goto SNOVA).
Причем, с предустановленным значением инструкции "Display StartLine"
(см. bsf Line,6 и bsf Line,7).
Вопрос: "Что сие означает"?
Ответ: это означает то, что следующий "кадр" будет
выведен на индикацию, с вертикальным смещением
на одну строку дисплея (в данном случае, "кадр"
сместится вверх).
А если это повторяется многократно/циклически (пока
включено питание)?
Это и есть непрерывная прокрутка "кадра" в дисплее.
А теперь оцените сложность программной реализации
непрерывной прокрутки.
Она минимальна.
Вывод: честь и
хвала
разработчикам за
инструкцию "Display
StartLine".
Слева Вы видите
фотографии,
которые
иллюстрируют
процесс прокрутки.
Пояснение: для того чтобы картинка "кадра" двигалась вверх (по направлению от 64-й
строки дисплея к 1-й), нужно обеспечить отсчет адресов в противоположном
направлении (в сторону увеличения).
Это и есть обоснование необходимости применения команды инкремента (в данном
случае).

а) непрерывная прокрутка вниз


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

movlw b'11000000' ; Запись, в регистр выбора строки, инструкции


movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
4
..................................
;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ НЕПРЕРЫВНОГО ПРОКРУЧИВАНИЯ.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
decf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки - 1).
bsf Line,6 ; Обеспечение дальнейшего выполнения
bsf Line,7 ; инструкции "Display StartLine".
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).
;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................
;********************************************************************************
end ; Конец программы.

Различие выделено красным цветом (вместо команды incf, команда decf).


Это "мычание коровы" даже и комментировать не хочется.

2. Прокрутка вверх/вниз на заданное количество строк (в пределах одного


"кадра").

а) прокрутка вверх на заданное количество строк


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

movlw b'11000000' ; Запись, в регистр выбора строки, инструкции


movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).
movlw .32 ; Задание количества
movwf N_STROK ; сдвигов строк.
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
..................................

;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ ПРОКРУЧИВАНИЯ В ПРЕДЕЛАХ N-СТРОК (N задается в ПП START).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Анализ содержимого регистра количества строк прокрутки N_STROK.
;---------------------------------------------------------------
decf N_STROK,F ; N_STROK - 1 = ...
btfsc Status,Z ; Результат декремента =0 или не =0 ?
goto $ ; Если =0, то "СТОП-МАШИНА" (заданное
; количество строк прокручено).
; Если не=0, то программа исполняется
; далее (прокрутка продолжается).
;---------------------------------------------------------------
; ПП подготовки к вертикальному смещению "кадра" на одну строку.
;---------------------------------------------------------------
incf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки + 1).
6
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).

;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................

В этом случае, в программу введен дополнительный регистр общего назначения с


названием N_STROK.
В него (в ПП START) записывается количество строк, на которые нужно сдвинуть
картинку в дисплее.
В данном случае, я выставил 32 строки (вертикальное смещение на "пол-кадра").
При вертикальном смещении не более чем на один "кадр", это количество строк не
должно превышать числа .64 (количество строк в дисплее).
Если это так, то о содержимом битов №№7 и 6 инструкции "Display StartLine" можно
не беспокоиться, так как в них всегда будут выставлены единицы.
Перед переходом на новый цикл вывода "кадра" на индикацию, содержимое регистра
N_STROK декрементируется, а результат декремента анализируется на соответствие
или нет нулю.
Короче, банальнейшая "постановка на счетчик".
После отработки 32-х циклов выводов "кадра" на индикацию - "мертвяк" (остановка
прокрутки).

b) прокрутка вниз на заданное количество строк


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

movlw b'11000000' ; Запись, в регистр выбора строки, инструкции


movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).
movlw .32 ; Задание количества
movwf N_STROK ; сдвигов строк.
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
..................................

;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################

7
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ ПРОКРУЧИВАНИЯ В ПРЕДЕЛАХ N-СТРОК (N задается в ПП START).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Анализ содержимого регистра количества строк прокрутки N_STROK.
;---------------------------------------------------------------
decf N_STROK,F ; N_STROK - 1 = ...
btfsc Status,Z ; Результат декремента =0 или не =0 ?
goto $ ; Если =0, то "СТОП-МАШИНА" (заданное
; количество строк прокручено).
; Если не=0, то программа исполняется
; далее (прокрутка продолжается).
;---------------------------------------------------------------
; ПП подготовки к вертикальному смещению "кадра" на одну строку.
;---------------------------------------------------------------
decf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки - 1).
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
bsf Line,6 ; Обеспечение дальнейшего выполнения
; инструкции "Display StartLine".
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).

;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................

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


инкремента, а команда декремента, и бит №6 регистра Line "принудительно"
устанавливается в ноль.
Вопрос: "Почему"?
Ответ: потому, что после декремента числа 1100 0000, имеет место быть число
1011 1111, и так далее.
Как видите, в бите №6 устанавливается 0, который "убивает" инструкцию "Display
StartLine".
Именно для "нейтрализации" этой "бяки" и нужна команда bsf Line,6.
Визуальный результат работы программ 12864_a.asm и 12864_b.asm такой же, какой и
изображен на "вышележащих" фото, но только прокрутка останавливается на середине
"кадра".

3. Прокрутка вверх/вниз на заданное количество полных сдвигов "кадра".


8
a) прокрутка вверх на заданное количество полных сдвигов "кадра"
Программа называется 12864_10.asm (прилагается).
..................................
..................................
;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы портов В и С
clrf TrisC ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.

movlw b'11000000' ; Запись, в регистр выбора строки, инструкции


movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).

clrf Flag ; Сброс указателя полного сдвига "кадра".

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


movwf N_KADR ; полных сдвигов.
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
..................................
;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ ПРОКРУЧИВАНИЯ В ПРЕДЕЛАХ N-"КАДРОВ" (N задается в ПП START).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Определение наличия или отсутствия полного сдвига "кадра".
;-----------------------------------------------------------

9
btfss Flag,0 ; Полный сдвиг "кадра" был или нет?
goto ADR_INCF ; Если нет, то производится вертикальное
; смещение "кадра" на одну строку.
; Если да, то программа исполняется далее.
;---------------------------------------------------------------
; Анализ содержимого регистра количества полных сдвигов N_KADR.
;---------------------------------------------------------------
clrf Flag ; Сброс указателя полного сдвига кадров (для
; обеспечения дальнейшей прокрутки в случае,
; если прокручены не все "кадры").
decf N_KADR,F ; N_KADR - 1 = ...
btfsc Status,Z ; Результат декремента =0 или не =0 ?
goto $ ; Если =0, то "СТОП-МАШИНА" (заданное
; количество "кадров" прокручено).
; Если не=0, то программа исполняется
; далее (прокрутка продолжается).
;---------------------------------------------------------------
; ПП подготовки к вертикальному смещению "кадра" на одну строку.
;---------------------------------------------------------------
ADR_INCF incf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки + 1).
btfsc Line,6 ; Line=0 (текущий "кадр" прокрутился)
; или не=0 (текущий "кадр" не прокрутился)?
goto $+4 ; Если не=0, то обход следующих 3-х команд.
; Если=0, то программа исполняется далее.
bsf Line,6 ; Обеспечение дальнейшего выполнения
bsf Line,7 ; инструкции "Display StartLine".
bsf Flag,0 ; Установка признака полного сдвига "кадра"
; (для обеспечения дальнейшей остановки
; прокручивания).
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).

;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................

В этом случае, регистр N_STROK "трансформируется" в регистр N_KADR.


Так как нужен критерий окончания прокрутки, "привязанный" к последнему (из
назначенного количества) кадру, то "в эксплуатацию вводится" регистр Flag.
Уже из его названия должно быть понятно, что речь идет о флаге, который
поднимается сразу же после прокрутки текущего "кадра".
"Роль" этого флага выполняет бит №0 регистра Flag.
Остальные его биты - "по барабану".
Если бит №0 регистра Flag в нуле, то это свидетельствует о том, что текущий "кадр"
полностью еще не прокручен.
Если бит №0 регистра Flag в единице, то это свидетельствует о том, что текущий
"кадр" полностью прокручен.
В ПП START, бит №0 регистра Flag сбрасывается в 0 (clrf Flag), а в регистр
N_KADR "закладывается" нужное число полных сдвигов "кадра".
Это - подготовка к "боевым действиям".
После вывода на индикацию 1-го "кадра", состояние флага опрашивается и
анализируется.
Естественно, что в этом случае, он будет в нуле и произойдет переход в ПП
ADR_INCF.
В ПП ADR_INCF, производится "штатный" инкремент содержимого регистра Line.
Пока кадр полностью не прокручен, в битах №№7 и 6 регистра Line будут единицы,
что и распрекрасно (инструкция Display StartLine - "живее всех живых").

10
Но после полной прокрутки кадра в сторону увеличения числовых значений адресов
строк дисплея, числовые значения битов №№7 и 6 сменятся с 11 на 00 (переход от .
255 к .0).
Для начала, сию "бяку" нужно обнаружить.
Вот Вам и смысл применения команды btfsc Line,6.
Вопрос: "А 7-й бит куда подевался"?
Ответ в виде вопроса на вопрос: а на кой ляд им заморачиваться, если биты №№ 7
и 6 сбрасываются в 0 "оптом"?
Достаточно "просканировать" состояния любого из этих битов, а оставшийся "выбросить
на помойку".
В данном случае, "сканируются" состояния бита №6.
В результате этих немудреных умозаключений, процедура анализа наличия или
отсутствия полной прокрутки "кадра" "весит" всего одну бит-ориентированную команду.
Проще просто не бывает.
Если бит №6 регистра Line в нуле, то делается вывод о том, что текущий кадр
прокручен (об этом - позже).
Если бит №6 регистра Line в единице, то делается вывод о том, что текущий кадр не
прокручен и его нужно "крутить" дальше.
В этом случае, происходит переход (goto $+4) на команду включения 1-го кристалла,
а затем - на начало "нового" цикла вывода на индикацию следующего "кадра" ("на
колу мочало, начинаем все с начала").
Теперь предположим, что "свершилась" полная прокрутка "кадра".
Значит, в бите №6 регистра Line установится 0.
В этом случае, для обеспечения дальнейшей "живучести" инструкции "Display
StartLine", нужно "принудительно" выставить нули в битах №№ 6 и 7 регистра Line
(bsf Line,6 и bsf Line,7) и установить признак полного сдвига "кадра"
(bsf Flag,0), что и имеет место быть.
Далее - "штатное" включение 1-го кристалла и дальнейшее "на колу мочало …".
Но далее, в части касающейся работы с регистром Flag, "мочало" имеет специфику.
На следующем "витке" полного цикла программы, единица в бите №0 регистра Flag
будет "засечена" (см. btfss Flag,0).
Это и есть "миссия" бита №0 регистра Flag (его "звездный час").
Проще говоря, единица в бите №0 регистра Flag есть разрешение последующего
декремента содержимого регистра N_KADR.
При этом, переход в ПП ADR_INCF (goto ADR_INCF) обходится до выяснения
"последующих обстоятельств".
Результат этого "выяснения" зависит от анализа (анализ состояния флага Z)
результата декремента содержимого регистра количества полных сдвигов (N_KADR).
Если этот результат не равен 0 (все "кадры" не прокрутились), то имеет место быть
"на колу мочало …" (исполнение ПП ADR_INCF).
Причем, "до победного конца".
"Победный конец" наступит тогда, когда, после декремента, содержимое регистра
N_KADR станет равным 0.
Это свидетельствует о том, что прокрутка заданного количества "кадров" осуществлена.
После этого - "СТОП-МАШИНА" (в виде goto $).

b) прокрутка вниз на заданное количество полных сдвигов "кадра"


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

11
movlw b'11000000' ; Запись, в регистр выбора строки, инструкции
movwf Line ; "Display StartLine" с адресом 1-й строки
; (00h).

clrf Flag ; Сброс указателя полного сдвига "кадра".

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


movwf N_KADR ; полных сдвигов.
;================================================================================
; Инициализация графического модуля.
;================================================================================
..................................
..................................
;-------------------------------------
; Установка текущей строки.
;-------------------------------------
SNOVA movf Line,W ; Выбор адреса строки дисплея, с которой
; начнется формирование картинки "кадра"
; (инструкция "Display StartLine").
movwf PortC ; Вывод команды выбора адреса строки
; на линии DB7...DB0.
call STROB ; Строб ("запуск в работу").
;---> Возврат по стеку из ПП STROB
;################################################################################
; РАБОТА С ЛЕВЫМ (1-м) КРИСТАЛЛОМ.
;################################################################################
..................................
..................................
goto WR_16 ;
;================================================================================
; ЗАДЕРЖКА (0,3 сек.)
;================================================================================
movlw .153 ;
movwf Reg_1 ;
movlw .134 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


goto $-1 ; 3-байтный
decfsz Reg_2,F ; вычитающий
goto $-3 ; счетчик.
decfsz Reg_3,F ;
goto $-5 ;
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; ВАРИАНТ ПРОКРУЧИВАНИЯ В ПРЕДЕЛАХ N-"КАДРОВ" (N задается в ПП START).
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Определение наличия или отсутствия полного сдвига "кадра".
;-----------------------------------------------------------
btfss Flag,0 ; Полный сдвиг "кадра" был или нет?
goto ADR_DECF ; Если нет, то производится вертикальное
; смещение "кадра" на одну строку.
; Если да, то программа исполняется далее.
;---------------------------------------------------------------
; Анализ содержимого регистра количества полных сдвигов N_KADR.
;---------------------------------------------------------------
clrf Flag ; Сброс указателя полного сдвига кадров (для
; обеспечения дальнейшей прокрутки в случае,
; если прокручены не все "кадры").
decf N_KADR,F ; N_KADR - 1 = ...
btfsc Status,Z ; Результат декремента =0 или не =0 ?
goto $ ; Если =0, то "СТОП-МАШИНА" (заданное
; количество "кадров" прокручено).
; Если не=0, то программа исполняется
; далее (прокрутка продолжается).
12
;---------------------------------------------------------------
; ПП подготовки к вертикальному смещению "кадра" на одну строку.
;---------------------------------------------------------------
ADR_DECF decf Line,F ; Подготовка к вертикальному смещению
; "кадра" на одну строку (адрес строки - 1).
movf Line,W ;
sublw .192 ; .192 - Line = ...
btfss Status,Z ; Результат вычитания =0 или не=0 ?
goto $+2 ; Если не=0, то обход следующей команды.
; Если=0, то программа исполняется далее.
bsf Flag,0 ; Установка признака полного сдвига "кадра"
; (для обеспечения дальнейшей остановки
; прокручивания).
bsf PortB,E1 ; Включение 1-го кристалла
; (2-й кристалл включен ранее).
bsf Line,6 ; Обеспечение дальнейшего выполнения
; инструкции "Display StartLine".
goto SNOVA ; Переход на следующий цикл вывода данных на
; индикацию (с "новым" адресом строки).

;********************************************************************************
; Таблицы данных, предназначенных для записи.
;********************************************************************************
..................................
..................................

В данном случае, имеет место быть не инкремент содержимого регистра Line, а


декремент.
Если начать минусовать от числа 1100 0000, то следующим будет число 1011 1111 (и
т.д. С нулем в бите №6).
Значит, перед командой goto SNOVA нужно озаботиться выставлением единицы в бите
№6 регистра Line, что и имеет место быть (bsf Line,6).
Иначе, инструкция "Display StartLine" "даст дуба".
В бите №7 регистра Line, единицу выставлять не нужно, так как в случае декремента
(напоминаю про число 64), она будет "торчать" в нем постоянно.
Если "провернуть это дельце", то на входе в ПП ADR_DECF, будет иметь место быть
точно такой же диапазон цифр, как и в случае инкремента (от .192 до .255), только
направление счета изменится на противоположное (по направлению от .255 к .192).
Следовательно, критерием полной прокрутки "кадра" будет число 1100 0000 (.192).
Вот Вам и ответ на вопрос, откуда взялась процедура анализа содержимого регистра
Line на предмет соответствия или нет числу .192 (см. выше. Выделено красным
цветом)?
Остальное - без изменений (по отношению к предыдущему случаю).

4. Прокрутка вверх/вниз вышеперечисленного, но только в пределах 1-го или 2-го


кристаллов.
Ранее, на момент исполнения инструкции "Display StartLine", оба кристалла были
включены.
Не составляет труда догадаться о том, что если, на момент исполнения инструкции
"Display StartLine", будет выключен один из кристаллов, то прокрутка будет
производиться только в том кристалле, который включен.
В том кристалле, который будет выключен, прокрутки производиться не будет.
В нем просто-напросто зафиксируется "половинка материнского кадра", выведенная на
индикацию на первом "витке" полного цикла программы.
При этом, ничего, кроме соответствующих манипуляций с включением/выключением
кристаллов, не требуется.
Я не стал полномасштабно "размножать" соответствующие программы под все
рассмотренные случаи, но для случая непрерывной прокрутки вниз, "взял грех на
душу".
Программа, в которой прокручивается содержимое 2-го кристалла (содержимое 1-го
кристалла не прокручивается), называется 12864_8.asm (прилагается).

13
Программа, в которой прокручивается содержимое 1-го кристалла (содержимое 2-го
кристалла не прокручивается), называется 12864_9.asm (прилагается).
Ниже Вы видите фото, которые иллюстрируют сказанное:

На этих фото,
осуществляется
прокрутка
содержимого 2-го
кристалла.

На этих фото,
осуществляется
прокрутка
содержимого 1-го
кристалла.

Примечание: инструкцию "Display StartLine" можно использовать не только для


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

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

14