8-битный дисплейный модуль и адаптер ASCII-клавиатуры

 

 

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

Данный дисплейный модуль разработан для использования с любыми восьмибитными контроллерами и компьютерами, а также может подключаться к LPT-порту любого компьютера как дополнительное отображающее устройство. Модуль обеспечивает вывод информации на обычный телевизор, обеспечиваются режимы 80х25, 40х25, 80х12, 40х12, блочная графика 100х160 совместно с любым текстовым режимом (из готовых блоков, аналогично видеовыводу NES/Famocom), а также микс из текстовых режимов и графики (построчно).

    В качестве основы дисплейного модуля взята конструкция Гранта Сирла, которая, в свою очередь, является модификацией схемы Дэрила Риктора. В нашем случае модуль был адаптирован для подключения к параллельной шине данных, что позволяет подключать его к любым восьмибитным конструкциям (к тому же "ЮТ-88"), обращаясь к нему как к устройству ввода/вывода или как к ячейке памяти.

    Основой схемы является однокристальный микроконтроллер Atmega328. В помощь ему подключён сдвиговый регистр отображаемого символа D9 (чтобы убрать известный в подобных конструкциях джиттер первой строки формируемого изображения при невысокой тактовой частоте). Вместо ИР10 возможно применение ИР9, но в этом случае можно получить неравномерные по ширине точки на экране.

    Общение дисплейного модуля с управляющим контроллером осуществляется через два регистра - выводимого символа D7 и занятости модуля D4.3. Кратко общение с модулем можно рассмотреть на графике:

 

 

    Алгоритм работы триггера D15.1 и микроконтроллера D8 полностью взят из оригинальной схемы. Это позволило простым способом определить занятость микроконтроллера с помощью сумматора по модулю 2 D4.3 - если уровни выходов триггера и микроконтроллерa не совпадают, то получаем занятость дисплейного узла (высокий уровень на выводе 8 D4.3). Программно общение с дисплейным узлом достаточно просто:

- проверяем занятость узла. Для этого устанавливаем (/CS0=0)&(A0=1)&(/IORD=0). Если при этом D1=0, то контроллер занят. В цикле проверяем, пока D1 не станет равен единице;

- если D1=1, то устанавливая (/CS0=0)&(/IORW=0) записываем выводимый байт в регистр D7.

Как видно, общение контроллера с дисплейным модулем по своему алгоритму полностью совпадает с общением с привычным UART'ом (разве что инициализация не нужна), что позволяет очень просто адаптировать подпрограммы работы последовательного порта под работу с дисплейным модулем. Разумеется, что раз мы применили для связи с шиной элемент 155ЛА8, то линии шины данных должны быть притянуты к +5 через резисторы (показано на рисутке).

Если модуль применяется, к примеру, с контроллером на процессоре 6502 или как ячейка памяти, то сигналы /IORD и /IOWR заменяются соответственно на /RD и /WR.

Желающие собрать данный дисплейный узел могут использовать для проверки оригинальную прошивку. Если интересует возможность вывода кириллицы в альтернативной кодировке (практически полностью совпадает с СР866), то используйте кириллическую прошивку. В части установки фьюзов необходимо обратить внимание на следующее:

- используется внешний генератор, т.е. CKSEL=0000;

- SUT=01;

- No watchdog timer;

- No clock divider;

- JTAG disabled;

- OCD disabled;

- No boot program.

Описание всех команд для работы с модулем можно взять из оригинального описания Гранта Сирла.

Поскольку мощности встроенного генератора Атмеги не хватает для синхронизации дополнительных микросхем серий 555/1533 (у нас это ИР10 и ТМ2, о которой чуть ниже), то используется внешний генератор, собранный по схеме, аналогичной применяемой в оригинальной приставке NES/Famicom. Конденсатор 75 пФ в базовой цепи транзистора облегчает запуск генератора, а конденсатор 20 пФ в коллекторной цепи дополнительно стабилизирует генерацию. Далее тактовые импульсы подаются на согласующий каскад, с которого далее сигнал подаётся на микроконтроллер, выходной регистр и делитель частоты. Разумеется, генератор на рассыпухе возможно заменить на однокорпусный осциллятор (при его наличии).

В описанном выше варианте адаптер выдаёт видеосигнал в формате PAL, жирный шрифт, 80 символов в строке. Если вам нужны иные стартовые наcтройки, то запасаемся резистором 10 кОм, один его вывод подключаем к массе, второй вывод - в соответствии с таблицей:

Режим Вывод Atmega328 через резистор 10 кОм на "массу"
NTSC 13
40 символов в строке 6
Нормальные (не жирные) символы 4
Двойная высота символов 5

Режим будет настроен автоматически после перезапуска адаптера. Разумеется, что мы можем переключать размеры символом во время работы адаптера, см. оригинальное описание  или ниже.

В голубом прямоугольнике показан узел получения тактовых импульсов для процессора подключаемого контроллера частотой 4 МГц. Если ваш контроллер имеет собственное тактирование, либо вы решили не экономить на кварцах, то ТМ2 можно не ставить.

Рассмотрим работу адаптера расширенной ASCII-клавиатуры. Блок состоит из нескольких частей. На элементе D5.2 собран триггер нажатого символа. При запуске контроллера он сбрасывается сигналом RES, устанавливая на выходе Q "ноль".

На микросхеме D1 собран буфер символов. Каждый введённый с клавиатуры символ записывается в него по фронту инвертированного (через элемент D4.2) импульса /КР (Key Pressed). Задняя часть этого импульса устанавливает триггер нажатого символа D5.2 в "единицу", сигнализируя, что некая клавиша была нажата и в буфере находится её код. Также активируется выход прерывания /INT, указывая внешнему контроллеру, что была нажата клавиша. Таким образом импульс /КР используется "полностью", обеспечивая предварительную запись информации перед выдачей прерывания.

Контроллер сначала опрашивает триггер нажатого символа, при этом (CS1=0)&(IORD=0)&(A0=1). Если на шине D0=1, то никакая клавиша не нажималась (с момента последнего опроса). Если D0=0, то в буфере D1 есть код нажатой клавиши и требуется его опросить.

При опросе буфера кода клавиши, (CS1=0)&(IORD=0)&(A0=0), код символа выдаётся на шину данных, а также происходит сброс триггера нажатого символа (Q=0) и сброс сигнала прерывания /INT.

Как видно, общение контроллера с блоком согласования клавиатуры по своему алгоритму полностью совпадает с общением с привычным UART'ом (разве что инициализация не нужна), что позволяет очень просто адаптировать подпрограммы работы последовательного порта под работу с клавиатурой. Также процессор контроллера обращается к адаптеру только в случае нажатия клавиши, не тратя время на бездумное сканирование клавиатуры.

Если лень делать клавиатуру из отдельных кнопок, можно подключить внешний адаптер PS/2-ASCII, ссылки на подобные конструкции легко найти в Сети.

 

Описанный видеоконтроллер, совместно с адаптером клавиатуры, собран на небольшой макетной плате.

 

 

Большой разъём справа - системный, для подключения к процессорной плате, малый - для подключения ASCII-клавиатуры.

 

Для подключения описанного модуля к LPT-порту персонального компьютера для вывода информации на отдельный дисплей достаточно выполнить следующее:

- подключить входы D7 к шине данных LPT;

- подключить выход /STROBE ко всем входам D2.3;

- подключить вход /BUSY к выходу 8 D4.3.

 

Несколько картинок, показывающих семь из восьми текстовых режимов. Разумеется, что во время работы мы можем свободно построчно их использовать.

 

80 символов в строке, нормальный шрифт (25 строк на экран)

 

80 символов в строке, жирный шрифт

 

40 символов в строке, нормальный шрифт

 

40 символов в строке, жирный шрифт

 

40 символов в строке, жирный шрифт, двойная высота (12 строк на экран)

 

40 символов в строке, нормальный, двойная высота - нет фото.

 

80 символов в строке, жирный шрифт, двойная высота

 

80 символов в строке, нормальный шрифт, двойная высота

 

Управляющие коды.

Для красивого вывода символов на экран приходится применять управляющие видеоадаптером коды. Список приведён ниже:

Hex (Decimal) и их действие
01 (01) - Курсор в позицию 0,0 (Home)
02 (02) - Определение типа курсора (второй байт определяет его вид или 00 для выключения)
03 (03) - Курсор мигает
04 (04) - курсор не мигает
05 (05) - Установка пикселей графики (следующие два байта = x,y)
06 (06) - Сброс пикселей графики (следующие два байта = x,y)
08 (08) - Стирание символа влево (Backspace)
09 (09) - Табуляция
0A (11) - Переход на следующую строку (Linefeed)
0C (12) - Очистка экрана
0D (13) - Возврат каретки
0E (14) - Установить курсор на колонку 0 до 79 (второй байт - номер колонки) или 0 до 39 для 40 символов в строке
0F (15) - Установить курсор на строку 0 до 24 (второй байт - номер строки)
10 (16) - Стереть к началу строки
11 (17) - Стереть до конца строки
12 (18) - Стереть к началу экрана
13 (19) - Стереть до конца экрана
14 (20) - Прокрутить вверх
15 (21) - Прокрутить вниз
16 (22) - Прокрутить влево
17 (23) - Прокрутить вправо
18 (24) - Установить атрибуты шрифта (ниже подробно описано)
1A (26) - Считать следующий байт как символ (чтобы отобразить коды от 1 до 31)
1B (27) - ESC - резервировано для управляющих последовательностей
1C (28) - Курсор вправо
1D (29) - Курсор влево
1E (30) - Курсор вверх
1F (31) - Курсор вниз
20 (32) - 7E (126) - Стандартные ASCII коды, отображаемые на экране
7F (127) - Delete
80 (128) - FF (255) - Расширенные ASCII коды (альтернативная кодировка)
 

Атрибуты шрифта

    Установка атрибутов шрифта возможна только для одной строки. Невозможно использовать разные шрифты на одной строке. Основные виды шрифтов показаны на фото выше.
Для установки нужного шрифта необходимо запрограммировать управляющие биты:

7 6 5 4 3 2 1 0
Графика - - - - Двойная высота Жирный 80 символов

    Таким образом, шрифт жирный, 80 символов, нормальной высоты программируется как 0000011В или 03Н, нормальные 40 символов - 00000000В или 00Н. Для установки шрифта посылаем на видеоадаптер код 18Н и затем выбранный выше код, т.е для жирного 80-символьного шрифта нормальной высоты посылаем 18Н и 03Н. Если строка заполнена полностью и произошёл перенос символов на новую строку, шрифт не изменится. Курсор автоматически изменит свой вид при установке на строки с разными шрифтами. При очистке экрана установленные атрибуты шрифта также сохраняются.

    Для шрифта двойной высоты позиционирование курсора необходимо производить по верхней части шрифта (первой линии). Позиционирование курсора по нижней линии может привести к непредсказуемым результатам.

Графика

    Поддерживается пиксельная графика 160x100 точек. Для этого существуют две функции. При получении команды установки или сброса пикселя, координаты X/Y определяют, на какой строке будет использован графический режим. Это делается автоматически и нет необходимости указывать применение графического режима. Если на этой строке был текст, то строка очищается от текста. Координаты пикселей могут быть X = 0-159, Y = 0-99. Для установки пикселя отправьте команды 05Н, X, Y в виде трёх байт. Для сброса пикселя отправьте 06Н, X, Y.

    Также в графической режиме возможно использование блочной графики 2х4. Каждому биту определено своё место в блоке, как это видно из рисунка:

0

1

2

3

4

5

6

7

    Для рисования блока позиционируем курсор (команды 0ЕН ххН, 0FH xxH), устанавливаем атрибуты графики (18Н 80Н) и отправляем нужный байт для отрисовки требуемых пикселей в блоке; к примеру, для пикселей 0,4,5 и 7 мы должны отправить байт 10110001В или B1Н, итого 7 байт.

    При работе в графическом режиме рекомендуется отключать курсор (команда 02Н 00Н), дабы он не мигал на фоне графики.

 

 

На главную/Index