Страницы

вторник, 22 марта 2016 г.

Программный интерфейс дисплея



Интерфейс дисплея.

Я хочу поделиться наработками по интерфейсу ЖК дисплея. Конечно, в процессе обучения программированию каждый изобретает свой «велосипед», но такого интерфейса я нигде не видел. Поэтому, читайте и дополняйте своими наработками.
Началось это тогда, когда цветной ЖК дисплей от Nokia 1616 стал стоить дешевле четырёх разрядного семисегментного индикатора. Использовать пять ножек вместо двенадцати, и выводить гораздо больше информации с более высоким качеством стало просто выгодно. Поэтому тогда я запилил простейшую библиотеку для STM8. В три килобайта поместились упакованный шрифт высотой 20 пикселей (только заглавные латинские буквы) и немного подпрограмм для вывода текста и примитивной графики. В дальнейшем я стал использовать этот дисплей для проектов на STM32. Ограничения памяти отпали, но мне не хватало функциональности. Для того, чтобы вывести несколько сообщений в разных местах дисплея разным шрифтом приходилось вызывать кучку подпрограмм. А изменение порядка вывода или цвета текста выливалось в переписывание программы. "Это не наш метод".
Тогда я взял за основу расширенный набор команд дисплея VT100, добавил поддержку управляющих кодов и простейших графических примитивов и получил свой интерфейс дисплея. Преимущество его в том, что абсолютно все команды записаны в текстовой строке, и для вывода на дисплей достаточно вывести эту строку на печать. Также не важно, выводишь ли ты всю строку сразу, или передаёшь её по частям или даже посимвольно, результат будет одинаков.
Принцип очень прост. В кодах символов существует специальный управляющий символ, который определяет начало управляющей последовательности. В VT100 это последовательность ESC и [ - CSI. У меня – символ '~' (для простой печати в строке). Если мне нужно напечатать этот символ, я пишу его дважды – ”~~”. После управляющего символа идёт перечень аргументов, затем символ команды. Парсер строки разбирает эту последовательность и передаёт управление подпрограммам. Всё просто. Теперь каждое выводимое текстовое сообщение становится самостоятельным объектом. Оно может содержать в себе команды позиционирования, выбора шрифта, цвета фона и текста, выводить несколько сообщений за один раз или рисовать фигуры на экране, даже полностью очищать экран. Изменение места вывода, текста, шрифта или цвета выливаются в переписывание строки, а не в изменение алгоритма программы.
Работа над интерфейсом продолжается, сейчас реализованы не все команды, некоторые пока просто заглушки. Но он работает, и очень эффективно. Вот перечень команд:
Управляющие последовательности
ESC = '~'
Печать "~"                                        "~~"
Сброс экрана                                  "~m"
Установить границы окна         "~Y1;Y2;X1;X2L" Y1-верх, Y2-низ X1-лево, X2-право в пикселях
Позиция курсора                           "~Y;XH" Y-строка X-столбец в пикселях
Очистка экрана              "~NJ" N=0 до конца экрана N=1 до начала экрана N=2 весь экран N=3 окно
Очистка строки                              "~NK"   N=0 до конца строки N=1 до начала N=2 вся строка
Курсор вверх                                  "~YA" Y-количество строк
Курсор вниз                                     "~YB" Y-количество строк
Курсор вправо                                               "~XC" X-количество символов
Курсор влево                                  "~XD" X-количество символов
Новая строка                                   "~YE" Y-количество новых строк
Курсор скрыть/отобразить      "~NO" N=0 скрыть N=1 отобразить
Инверсия текста вкл                   "~7m"
Установить шрифт                        "~Nm"   N=10-19 10 - шрифт основной 11-19 - дополнительные
Инверсия текста выкл                                "~27m"
Цвет текста                                      "~N;Mm" N=30-39(цвет) M=0-1(яркость)
Цвет фона                                         "~N;Mm" N=40-49(цвет) M=0-1(яркость)
Управление границей окна     "~Nm"   N=51 граница 1 пиксель, N=52 2 пикселя, N=54 нет границы
Цвет фигур                                       "~N;Mm" N=50-59(цвет) M=0-1(яркость)
Цвет фона         фигур                   "~N;Mm" N=60-69(цвет) M=0-1(яркость)
Сдвинуть окно вверх                  "~NS" N строк
Сдвинуть окно вниз                     "~NT" N строк
Графические фигуры:
Линия                                                 "~X1;Y1;X2;Y2l"                X1,Y1 - старт X2,Y2 - финиш
круг                                                      "~X;Y;R;Fc"         X,Y - центр окружности R - радиус F - признак круга
прямоугольник незакрашенный          "~X1;Y1;W;Hs"  X1,Y1 - угол 1 W – ширина H - высота
прямоугольник закрашенный               "~X1;Y1;W;Hq" X1,Y1 - угол 1 W – ширина H - высота
пиксель                                             "~X;Yp"                                               X,Y - координаты
Управляющие коды:
\b           0x08      BS, забой
\t            0x09      Горизонтальная табуляция
\n           0x0A      Новая строка, перевод строки
\v           0x0B      Вертикальная табуляция
\f            0x0C      Новая страница, перевод страницы
\r            0x0D      Возврат каретки
цвет: 0-Black, 1-Red, 2-Green, 3-Yellow, 4-Blue, 5-Magenta, 6-Cyan, 7-White, 8-пользовательский, 9- по умолчанию
Конечно, здесь тоже есть свои подводные камни. Например, я пока не придумал, как делать фоновый вывод большого изображения без прерывания основной программы. Основная программа представляет собой суперцикл. Пока просто обрабатываю посимвольно. Буду рад предложениям по улучшению.
Сам парсер представляет собой конечный автомат с длинным switch-case. Его легко сократить или дополнить своими командами по мере потребностей.
Ниже прилагаю текст парсера.

2 комментария:

  1. Код зручно розміщувати в системі контролю версій https://github.com/
    Або на http://pastebin.com/
    В такому разі буде зручна підсвітка синтаксису.

    ОтветитьУдалить