Easyelectronics.ru

Электроника для всех
Текущее время: 23 сен 2020, 09:36

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Программный интерфейс дисплея.
СообщениеДобавлено: 22 мар 2016, 10:21 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Я хочу поделиться наработками по интерфейсу ЖК дисплея. Конечно, в процессе обучения программированию каждый изобретает свой «велосипед», но такого интерфейса я нигде не видел. Поэтому, читайте и дополняйте своими наработками.

Началось это тогда, когда цветной ЖК дисплей от 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. Его легко сократить или дополнить своими командами по мере потребностей.
Ниже прилагаю текст парсера. Он несколько упрощён, убрана инициализация дисплея и инициализация структуры lcd.
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 23 мар 2016, 10:49 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Да, 79 просмотров и ни одного ответа. Это никому не интересно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 23 мар 2016, 13:40 
Старожил
Аватара пользователя

Зарегистрирован: 23 янв 2012, 00:31
Сообщения: 1799
Откуда: Новокузнецк
Я так и не понял для чего это нужно. Вроде как текстовый интерфейс внутри контроллера для управления дисплеем, а именно вывода примитивов. Не проще ли было сделать набор функций, реализующих это, и вызывать их из пользовательской программы.
Для меня больший интерес представляет библиотека пользовательского интерфейса. Аналог emWin, но полегче.

_________________
elisey.su


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 23 мар 2016, 15:10 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Для чего это нужно - поясню на примере.
Например, мне нужно отображать системное состояние зелёным цветом шрифтом высотой 10 пикселей в первой строчке экрана
А также мне нужно вывести меню шрифтом высотой 18 пикселей белого цвета во вторую строчку экрана. Размер меню 4 строки, активная строка подсвечивается инверсией.
Также мне хочется обвести всё это рамочками, например оранжевого цвета.
Как это выглядит обычно? Как-то так:
Код:
Псевдокод:
// это первая строка с параметрами
set_fonts (font_10);
set_color (green, black);
set_origin (0, 0);
lcd_print (first_parameter);
set_origin (50, 0);
lcd_print (second_parameter);

// это меню
set_fonts (font_18);
set_color (white, black);
set_origin (0, 20);
lcd_print (first_row_menu);
set_origin (0, 40);
set_color (black, white);   // инверсия второй строки
lcd_print (second_row_menu);
set_origin (0, 60);
set_color (white, black);   // отменить инверсию
lcd_print (third_row_menu);

// теперь рамочки
set_color (orange, black);
square (0, 0, 180, 20);
square (0, 20, 180, 80);

Даже писать устал.

А при использовании данного парсера достаточно сделать так:
Код:
севдокод:
// это первая строка с параметрами
lcd_print ("~2J~10m~32;1m~40;0m~0;0Hfirst_parameter~50;0Hsecond_parameter");

// это меню
lcd_print ("~18m~37;1m~0;20Hfirst_row_menu~0;40H~7msecond_row_menu~27m~0;40third_row_menu");

// рамочки
lcd_print ("~62;1m~0;0;180;20s~0;20;180;80s");


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 23 мар 2016, 22:23 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2061
А чем не подходят escape последовательности от VT100 наприрмер. Таких протоколов 100500 уже лет как 30. Очередной велосипед.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 23 мар 2016, 22:37 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Вообще-то это они и есть. Плюс немного графики.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 24 мар 2016, 17:38 
Старожил
Аватара пользователя

Зарегистрирован: 23 янв 2012, 00:31
Сообщения: 1799
Откуда: Новокузнецк
SOVA писал(а):
А также мне нужно вывести меню шрифтом высотой 18 пикселей белого цвета во вторую строчку экрана. Размер меню 4 строки, активная строка подсвечивается инверсией.
Также мне хочется обвести всё это рамочками, например оранжевого цвета.
Как это выглядит обычно? Как-то так:

Ну это не совсем честное сравнение. В пером случае отрисовка низкоуровневыми примитивами, а во втором уже работа с графическими объектами. Если первый случай вывести на уровень выше, то получится что-то типа:
Код:
label_print(0,0,font_10, green, black, first_parametr);
label_print(50,0,font_10, green, black, second_parametr);

for (int i=0; i<4; i++)   {
   label_print(0, (i*20) + 20, font_18, white, green, row_menu[i]);
}

square (0, 0, 180, 20, orange, black);
square (0, 20, 180, 80, orange, black);

Но опять же можно пойти еще выше в сторону объектов, и сделать что-то типа виджетов. Тогда мы просто объявляем объекты типа label, rectangle, задаем им параметры и отправляем их в соответствующее окно. А низкоуровневая библиотека уже сама будет периодически отрисовывать эти объекты, перерисовывать буквы и т.д.
Но все равно, смысл я понял, весьма интересно, для некоторых случаев очень хорошо подойдет, когда нужно передавать данные для отрисовки куда-либо по сети. Я вспомнил свой один проект, где для передачи данных на удаленный дисплей, управляемый другим МК, сделал систему команд, но вашим способом это было бы проще и изящнее.
Но в пределах одного МК имхо оверхед.

_________________
elisey.su


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Программный интерфейс дисплея.
СообщениеДобавлено: 24 мар 2016, 20:59 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Мне надоело изменять программу при изменении текста, размера и места вывода. Вот и подумал об ESC последовательностях.
В общем, напишу меню для прибора, там будет видно, насколько это удобно.
P.S. на этом принципе даже видео делают. :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB