Особенности работы с дисплеем lph9157-2

Разбираемся с LCD экраном LPH9157-2 от Siemens C75-ME75


Внятной документации на этот экран я не нашел поэтому пришлось разбираться с тем что есть и экспериментировать. В качестве управляющего устройства я использовал Raspberry PI. Так-же была написана программа позволяющая превратить этот экран в мини-монитор.

Описание

Данный дисплей имеет разрешение 135 x 176 пикселей и даёт возможность работать с тремя цветовыми палитрами 16(6-5-6), 12(4-4-4) и 8(3-3-2) бит.

Распиновка и подключение

Как можно заметить экран управляется через интерфейс SPI (контакты CS/CLK/DAT(MOSI)), предположительно это лишь половина интерфейса так как отсутствует контакт MISO, следовательно писать данные в экран мы можем, а вот читать — нет(здесь следует упомянуть что SPI может работать в двунаправленном режиме с использованием одного провода (MIMO) но так как отсутствует какие либо команды чтения данных из экрана будем считать что этот режим экраном не используется).

И перед тем как переходить непосредственно к управлению экраном надо бы этот экран к чему-нибудь подключить. В моём случае это будет Raspberry Pi. Контакты SPI экрана подключены к соответствующим им контактам SPI «малины», RS и RST к GPIO_17 и GPIO_27 соответственно. Данное подключение актуально для RPI Revision-2, если у вас иная модель то названия и номера контактов GPIO могут отличаться.

Заморачиваться с разъёмом подключения экрана я не стал и просто подпаялся к выводам проводом МГТФ. Экран в данном подключении питается от 3.3В, а не от 2.9 как в описании.
Вот так выглядит вся схема в сборе

Команды управления экраном

Экран управляется достаточно просто — путём посылки по SPI команд и данных. Отличить одни от других экрану помогает состояние пина RS где высокий уровень(лог. 1) означает передачу данных, а низкий(лог. 0) передачу команд. При передаче используется тупоконечный(big-ending) порядок байт.

  • CMD_RESET 0x01 — программный сброс
  • CMD_MEMORY_ACCESS_CONTROL 0x36 — установка направления заполнения области дисплея, имеет однобайтовый аргумент 0bVHRXXXXX, где
    V — заполнение по вертикали (0 — сверху-вниз, 1 — снизу-вверх),
    H — заполнение по горизонтали (0 — слева-направо, 1 — справа-налево),
    R — меняются местами строки и столбцы (при этом заполнение остается сверху-вниз, слева-направо))
  • CMD_WAKEUP 0x11 — выход из спящего режима
  • CMD_PALETTE 0x3A — установка цветовой палитры 8(0x02), 12(0x03) и 16(0x05) бит
  • CMD_ENABLE 0x29 — включение дисплея
  • CMD_SET_X 0x2A — задаем область рисования по X
  • CMD_SET_Y 0x2B — задаем область рисования по Y
  • CMD_START_WRITE 0x2C — начало записи в видеопамять

Работа экрана была проверена во всех 3х цветовых режимах но, дабы не захламлять исходник, далее я буду рассматривать только 16-битный. Во всех остальных режимах работа экрана не отличается, за исключением, разве что 12-битного — в нём на 2 пикселя приходится 3 байта, а если нужно вывести лишь одну точку то посылается 2 байта(4 младших бита последнего экраном игнорируются).
Для доступа к GPIO «малины» была использована библиотека bcm2835.

Начальная инициализация GPIO
Несколько вспомогательных функций
Задание области рисования

В результате экспериментов с экраном выяснилось что необязательно задавать область перед выводом каждого кадра, достаточно задать её лишь единожды и послав команду начала записи просто гнать по SPI последовательность кадров непрерывным потоком.

Подготовка к выводу и передача данных

В процессе инициализации экрана обнаружилась досадная вещь — для запуска необходимо передёрнуть RESET экрана, а вот последующие манипуляции данным выводом приводят экран в ступор и он перестаёт реагировать на внешние воздействия. Приходится сбрасывать его по питанию. Это необходимо учесть при разработке программы дабы процедура аппаратного сброса выполнялась лишь единожды.

Инициализация экрана

Это была подготовка, а теперь самое вкусное — попробуем вывести на экран 16-битную картинку. Первый блин как известно — комом, после запуска программы я получил довольно странное изображение, оказалось — неверный порядок байт, после исправления всё заработало.

изображение до и после правок

LCD как монитор

С самого начала экспериментов меня не покидала мысль использовать экран как монитор для «малины», что я и поспешил реализовать.
Идея проста — изображение берётся из /dev/fb0, оно там как раз 16-битное, ресайзится и выдаётся на экран.
Так как результат сжатия картинки 1024×768 => 176×132 малоинформативен, для фреймбуфера было установлено разрешение 320×240, это можно сделать правкой config.txt на FAT разделе «малиновой» флешки.

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

параметры:
-i — первичная инициализация (дёргаем хардварный reset)
-s — включить сглаживание
-d — динамический fps (одинаковые кадры пропускаются — экономит CPU)

Особенности работы с дисплеем LPH9157-2

В далёком 2005 году телефоны Siemens C75 и ME75 били рекорды популярности в бюджетном секторе благодаря привлекательному внешнему виду и демократичной цене.

Привлекал внимание и TFT-дисплейчик, имеющий разрешение 132×176 пикселей и палитру в 65536 цветов.

И вот, благодаря своей былой популярности, найти такие телефоны даже спустя 7-8 лет не представляет труда, и сегодня я поделюсь своими наработками, которые могут помочь использовать дисплеи данных телефонов в своих конструкциях.

Скажу сразу – данный дисплей мне очень понравился – миниатюрный, яркий и красочный, поэтому было решено продумать библиотеку для работы с ним по максимуму, т.к. при разработке своих устройств, из пары десятков индикаторов от различных старых телефонов, предпочтение отдаю именно ему.

В телефонах Siemens C75 и ME75 можно обнаружить два типа применяемых индикаторов — LPH9157-2 (с зелёным текстолитом) и некий ALPS (по крайней мере, под таким именем он фигурирует в Internet-ресурсах). Данный индикатор имеет жёлтый текстолит. В моей коллекции такой присутствует только в единичном экземпляре, поэтому написание библиотеки для работы с ним (увы!) в мои ближайшие планы пока не входит.

Дисплеи LPH9157-2 и ALPS:

Распиновка дисплея LPH9157-2:

1. CS – Chip Select. При установке в «0» контроллер дисплея принимает информацию;
2. RESET – вывод для сброса контроллера;
3. RS – вывод для определения типа передаваемых данных («0» — команда, «1» — данные);
4. SYNC – вывод для синхронизации с VGA-камерой (нам он не нужен);
5. CLK – вывод тактового сигнала для передачи данных;
6. DAT – вывод передачи данных;
7. 2,9V – к источнику питания;
8. GND – общий провод (земля);
9. VBOOST – вывод анодов светодиодов подсветки;
​10. LIGHT DISP – вывод катодов светодиодов подсветки (к GND).

Схема подключения дисплея:

Резистор R7 подбирается с учётом необходимой яркости подсветки.

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

Оба варианта печатных плат для согласования дисплея с контроллером прилагаются в архиве.

Дисплей LPH9157-2 поддерживает три цветовые палитры: 256 цветов (8 бит на пиксель), 4096 (12 бит на пиксель) и 65536 цветов (16 бит на пиксель), в библиотеке же реализовано 2 палитры — 256 и 65536 цветов. Хотя работа с 8-ми битной палитрой предпочтительнее при небольшой частоте работы контроллера, в данном дисплее цвета в этом случае получаются очень бледными.

Datasheet на контроллер для дисплея LPH9157-2 найти не удалось, однако на глаза попался пример инициализации с подробным описанием команд, что уже было достаточно для начала экспериментов. Из команд инициализации особый интерес представляет команда Memory Access Control (36h), т.к. она позволяет задавать, с помощью следующего за ней байта данных, направление заполнения области дисплея.

В этом байте данных нас интересуют старшие 3 бита: 0bVHRXXXXX, где V – отвечает за направление заполнения по вертикали (0 — сверху-вниз, 1 — снизу-вверх), H — заполнение по горизонтали (0 — слева-направо, 1 — справа-налево), R – позволяет менять местами строки и столбцы.

Как видно из рисунка, вместе с изменением направления заполнения области дисплея, меняется и начальная позиция осей x и y.

Этого уже достаточно, чтобы при выводе текстовой информации обеспечивать программным образом поворот текста на 90º, 180º и 270º.

А почему же тогда, для правильного отображения текста, при его повороте на 90º, и 270º, не использовать возможность поменять строки и столбцы местами, чего можно добиться, устанавливая бит R в «1»?

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

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

При выводе символа, функцией Send_Symbol (задаётся цвет символа и цвет фона) предварительно задаётся та область экрана, где будет отображён один байт из пяти, формирующих изображение (в библиотеке используется шрифт 5х8 пикселей). Изображение символа с помощью функции Send_Symbol_Shadow (без задаваемого цвета фона) – попиксельное.

С целью отображения на дисплее большого объёма текстовой информации, в библиотеке я использовал шрифт 5х8 пикселей, который, при увеличении масштаба изображения, немного напоминает такое течение в изобразительном искусстве, как кубизм. Вы можете использовать любой другой шрифт большего размера , для этого вам необходимо переработать функции Send_Symbol и Send_Symbol_Shadow под себя и учесть ширину символа в функциях LCD_Puts, LCD_Putsf, LCD_Puts_Shadow и LCD_Putsf_Shadow.

Также, при использовании библиотеки, следует иметь ввиду, что при запуске дисплея, начало адреса осей X и Y – левый верхний угол, а при изменении направления вывода текста или изображения (90º, 180º, 270º), осью X всегда будет считаться сторона над верхней частью выводимого текста или изображения.

Библиотека (для CodeVisionAVR) работы с LPH9157-2 содержит следующие функции (приведены только пользовательские функции!):

1. void LCD_init ()

2. void Put_Pixel (char x, char y, unsigned int color)

Функция вывода точки (пикселя). x и y – координаты экрана, где будет отображён пиксель цветом color.

3. void LCD_Putchar (char symbol, char x, char y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода одного символа ASCII-кода. Данная функция рассчитана на вывод символов размером 5х8 пикселей, библиотека которых находится в файле Symbols.h. symbol – выводимый на экран символ в ASCII-кодировке; x и y – начальная координата вывода символа; t_color – цвет пикселя; b_color – цвет фона; переменные zoom_width и zoom_height увеличивают символ на экране в указанное число раз; rot – угол поворота текста (0º , 90º, 180º, 270º).

4. void LCD_Putchar_Shadow (char symbol, char x, char y, int t_color, char zoom_width, char zoom_height, int rot)

Читайте также  Соединительные клеммы для электрической проводки

То же, что и 3, только без цвета фона.

5. void LCD_Puts(char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной в ram-памяти микроконтроллера. В отличие от библиотеки для LPH8731-3C, для вывода строки задаётся не номер строки и столбца, на которые предполагаемо разбит экран, а адреса начальных пикселей x и y.

6. void LCD_Puts_Shadow (char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 5, только без цвета фона.

7. void LCD_Putsf(flash char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной во flash-памяти микроконтроллера.

8. void LCD_Putsf_Shadow (flash char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 7, только без цвета фона.

9. void LCD_FillScreen (unsigned int color)

Функция заливки экрана цветом color.

10. void LCD_Output_image (char x, char y, char width, char height, flash char *img, int rot)

Функция вывода картинки. x и y начальная позиция выводимого на экран изображения; width и height – ширина и высота изображения (в пикселях); *img – указатель на массив данных, составляющих изображение; rot – угол поворота изображения (0º , 90º, 180º, 270º). Данная функция предполагает, что массив данных изображения расположен во flash-памяти микроконтроллера. Для преобразования необходимого вам изображения в массив, содержащий цвет пикселей, можно воспользоваться программами Image2Lcd или Nokia Image Creator, которые несложно найти на просторах интернета. Единственное требование – направление вывода массива изображения должно выполняться слева-направо, сверху-вниз! При использовании 16-ти битной палитры, при преобразовании изображения в массив типа char, обязательно старший байт должен идти первым!

11. void LCD_DrawLine (char x1, char y1, char x2, char y2, int color)

Нарисовать линию. x1 и y1 – начальная позиция линии; x2 и y2 – конечная позиция линии.

12. void LCD_DrawRect (char x1, char y1, char width, char height, char size, int color)

Нарисовать рамку. size — толщина рамки.

13. void LCD_FillRect (char x1, char y1, char width, char height, int color);

14. void LCD_DrawCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать окружность. rad – радиус окружности в пикселях.

15. void LCD_FillCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать круг, заполненный цветом color.

16. void LCD_DrawTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Нарисовать контуры треугольника.

17. void LCD_FillTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Нарисовать треугольник, заполненный цветом color.

В самом начале библиотеки, е сли объявлен макрос _8_BIT_COLOR , то цветовая палитра дисплея будет составлять 256 цветов, иначе — 65536 цветов. Макрос _GEOMETRICAL позволяет использовать функции вывода линии, рамки, прямоугольника, окружности, круга и треугольника.

Особенности работы с дисплеем LPH9157-2

В далёком 2005 году телефоны Siemens C75 и ME75 били рекорды популярности в бюджетном секторе благодаря привлекательному внешнему виду и демократичной цене.

Привлекал внимание и TFT-дисплейчик, имеющий разрешение 132×176 пикселей и палитру в 65536 цветов.

И вот, благодаря своей былой популярности, найти такие телефоны даже спустя 7-8 лет не представляет труда, и сегодня я поделюсь своими наработками, которые могут помочь использовать дисплеи данных телефонов в своих конструкциях.

Скажу сразу – данный дисплей мне очень понравился – миниатюрный, яркий и красочный, поэтому было решено продумать библиотеку для работы с ним по максимуму, т.к. при разработке своих устройств, из пары десятков индикаторов от различных старых телефонов, предпочтение отдаю именно ему.

В телефонах Siemens C75 и ME75 можно обнаружить два типа применяемых индикаторов — LPH9157-2 (с зелёным текстолитом) и некий ALPS (по крайней мере, под таким именем он фигурирует в Internet-ресурсах). Данный индикатор имеет жёлтый текстолит. В моей коллекции такой присутствует лишь в единичном экземпляре, поэтому написание библиотеки для работы с ним (увы!) в мои ближайшие планы пока не входит.

Дисплеи LPH9157-2 и ALPS:

Распиновка дисплея LPH9157-2:

1. CS – Chip Select. При установке в «0» контроллер дисплея принимает информацию;
2. RESET – вывод для сброса контроллера;
3. RS – вывод для определения типа передаваемых данных («0» — команда, «1» — данные);
4. SYNC – вывод для синхронизации с VGA-камерой (нам он не нужен);
5. CLK – вывод тактового сигнала для передачи данных;
6. DAT – вывод передачи данных;
7. 2,9V – к источнику питания;
8. GND – общий провод (земля);
9. VBOOST – вывод анодов светодиодов подсветки;
​10. LIGHT DISP – вывод катодов светодиодов подсветки (к GND).

Схема подключения дисплея:

Резистор R7 подбирается с учётом необходимой яркости подсветки.

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

Оба варианта печатных плат для согласования дисплея с контроллером прилагаются в архиве.

Дисплей LPH9157-2 поддерживает три цветовые палитры: 256 цветов (8 бит на пиксель), 4096 (12 бит на пиксель) и 65536 цветов (16 бит на пиксель), в библиотеке же реализовано 2 палитры — 256 и 65536 цветов. Хотя работа с 8-ми битной палитрой предпочтительнее при небольшой частоте работы контроллера, в данном дисплее цвета в этом случае получаются очень бледными.

Datasheet на контроллер для дисплея LPH9157-2 найти не удалось, однако на глаза попался пример инициализации с подробным описанием команд, что уже было достаточно для начала экспериментов. Из команд инициализации особый интерес представляет команда Memory Access Control (36h), т.к. она позволяет задавать, с помощью следующего за ней байта данных, направление заполнения области дисплея.

В этом байте данных нас интересуют старшие 3 бита: 0bVHRXXXXX, где V – отвечает за направление заполнения по вертикали (0 — сверху-вниз, 1 — снизу-вверх), H — заполнение по горизонтали (0 — слева-направо, 1 — справа-налево), R – позволяет менять местами строки и столбцы.

Как видно из рисунка, вместе с изменением направления заполнения области дисплея, меняется и начальная позиция осей x и y.

Этого уже достаточно, чтобы при выводе текстовой информации обеспечивать программным образом поворот текста на 90º, 180º и 270º.

А почему же тогда, для правильного отображения текста, при его повороте на 90º, и 270º, не использовать возможность поменять строки и столбцы местами, чего можно добиться, устанавливая бит R в «1»?

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

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

При выводе символа, функцией Send_Symbol (задаётся цвет символа и цвет фона) предварительно задаётся та область экрана, где будет отображён один байт из пяти, формирующих изображение (в библиотеке используется шрифт 5х8 пикселей). Изображение символа с помощью функции Send_Symbol_Shadow (без задаваемого цвета фона) – попиксельное.

С целью отображения на дисплее большого объёма текстовой информации, в библиотеке я использовал шрифт 5х8 пикселей, который, при увеличении масштаба изображения, немного напоминает такое течение в изобразительном искусстве, как кубизм. Вы можете использовать любой другой шрифт большего размера , для этого вам необходимо переработать функции Send_Symbol и Send_Symbol_Shadow под себя и учесть ширину символа в функциях LCD_Puts, LCD_Putsf, LCD_Puts_Shadow и LCD_Putsf_Shadow.

//===============================================================
// Функция прорисовки символа на дисплее
//===============================================================
void Send_Symbol (char symbol, char x, char y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)
<
unsigned char temp_symbol, a, b, zw, zh, mask;

if (symbol>127) symbol-=64; //Убираем отсутствующую часть таблицы ASCII
for ( a = 0; a > 8) ); Send_to_lcd( DAT, t_color );
#endif
>
else
<
#ifdef _8_BIT_COLOR //(8-ми битовая цветовая палитра (256 цветов))
Send_to_lcd( DAT, b_color ); //Данные — задаём цвет пикселя
#else //(16-ти битовая цветовая палитра (65536 цветов))
Send_to_lcd( DAT, (b_color >> 8) ); Send_to_lcd( DAT, b_color );
#endif
>
zh—;
>
mask LPH9157-2 содержит следующие функции (приведены лишь пользовательские функции!):

1. void LCD_init ()

2. void Put_Pixel (char x, char y, unsigned int color)

Функция вывода точки (пикселя). x и y – координаты экрана, где будет отображён пиксель цветом color.

3. void LCD_Putchar (char symbol, char x, char y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода одного символа ASCII-кода. Данная функция рассчитана на вывод символов размером 5х8 пикселей, библиотека которых находится в файле Symbols.h. symbol – выводимый на экран символ в ASCII-кодировке; x и y – начальная координата вывода символа; t_color – цвет пикселя; b_color – цвет фона; переменные zoom_width и zoom_height увеличивают символ на экране в указанное число раз; rot – угол поворота текста (0º , 90º, 180º, 270º).

4. void LCD_Putchar_Shadow (char symbol, char x, char y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 3, лишь без цвета фона.

5. void LCD_Puts(char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной в ram-памяти микроконтроллера. В отличие от библиотеки для LPH8731-3C, для вывода строки задаётся не номер строки и столбца, на которые предполагаемо разбит экран, а адреса начальных пикселей x и y.

6. void LCD_Puts_Shadow (char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 5, лишь без цвета фона.

7. void LCD_Putsf(flash char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной во flash-памяти микроконтроллера.

8. void LCD_Putsf_Shadow (flash char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 7, лишь без цвета фона.

9. void LCD_FillScreen (unsigned int color)

Функция заливки экрана цветом color.

10. void LCD_Output_image (char x, char y, char width, char height, flash char *img, int rot)

Функция вывода картинки. x и y начальная позиция выводимого на экран изображения; width и height – ширина и высота изображения (в пикселях); *img – указатель на массив данных, составляющих изображение; rot – угол поворота изображения (0º , 90º, 180º, 270º). Данная функция предполагает, что массив данных изображения расположен во flash-памяти микроконтроллера. Для преобразования необходимого вам изображения в массив, содержащий цвет пикселей, можно воспользоваться программами Image2Lcd или Nokia Image Creator, которые несложно найти на просторах интернета. Единственное требование – направление вывода массива изображения должно выполняться слева-направо, сверху-вниз! При использовании 16-ти битной палитры, при преобразовании изображения в массив типа char, обязательно старший байт должен идти первым!

Читайте также  Как делать проводку в бане?

11. void LCD_DrawLine (char x1, char y1, char x2, char y2, int color)

Нарисовать линию. x1 и y1 – начальная позиция линии; x2 и y2 – конечная позиция линии.

12. void LCD_DrawRect (char x1, char y1, char width, char height, char size, int color)

Нарисовать рамку. size — толщина рамки.

13. void LCD_FillRect (char x1, char y1, char width, char height, int color);

14. void LCD_DrawCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать окружность. rad – радиус окружности в пикселях.

15. void LCD_FillCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать круг, заполненный цветом color.

16. void LCD_DrawTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Нарисовать контуры треугольника.

17. void LCD_FillTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Нарисовать треугольник, заполненный цветом color.

В самом начале библиотеки, если объявлен макрос _8_BIT_COLOR, то цветовая палитра дисплея будет составлять 256 цветов, иначе — 65536 цветов. Макрос _GEOMETRICAL позволяет использовать функции вывода линии, рамки, прямоугольника, окружности, круга и треугольника.

Особенности работы с дисплеем lph9157-2

В далёком 2005 году телефоны Siemens C75 и ME75 били рекорды популярности в бюджетном секторе благодаря привлекательному внешнему виду и демократичной цене.

Привлекал внимание и TFT-дисплейчик, имеющий разрешение 132×176 пикселей и палитру в 65536 цветов.

И вот, благодаря своей былой популярности, найти такие телефоны даже спустя 7-8 лет не представляет труда, и сегодня я поделюсь своими наработками, которые могут помочь использовать дисплеи данных телефонов в своих конструкциях.

Скажу сразу – данный дисплей мне очень понравился – миниатюрный, яркий и красочный, поэтому было решено продумать библиотеку для работы с ним по максимуму, т.к. при разработке своих устройств, из пары десятков индикаторов от различных старых телефонов, предпочтение отдаю именно ему.

В телефонах Siemens C75 и ME75 можно обнаружить два типа применяемых индикаторов — LPH9157-2 (с зелёным текстолитом) и некий ALPS (по крайней мере, под таким именем он фигурирует в Internet-ресурсах). Данный индикатор имеет жёлтый текстолит. В моей коллекции такой присутствует только в единичном экземпляре, поэтому написание библиотеки для работы с ним (увы!) в мои ближайшие планы пока не входит.

Распиновка дисплея LPH9157-2:

1. CS – Chip Select. При установке в «0» контроллер дисплея принимает информацию;
2. RESET – вывод для сброса контроллера;
3. RS – вывод для определения типа передаваемых данных («0» — команда, «1» — данные);
4. SYNC – вывод для синхронизации с VGA-камерой (нам он не нужен);
5. CLK – вывод тактового сигнала для передачи данных;
6. DAT – вывод передачи данных;
7. 2,9V – к источнику питания;
8. GND – общий провод (земля);
9. VBOOST – вывод анодов светодиодов подсветки;
​10. LIGHT DISP – вывод катодов светодиодов подсветки (к GND).

Схема подключения дисплея:

Резистор R7 подбирается с учётом необходимой яркости подсветки.

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

Оба варианта печатных плат для согласования дисплея с контроллером прилагаются в архиве.

Дисплей LPH9157-2 поддерживает три цветовые палитры: 256 цветов (8 бит на пиксель), 4096 (12 бит на пиксель) и 65536 цветов (16 бит на пиксель), в библиотеке же реализовано 2 палитры — 256 и 65536 цветов. Хотя работа с 8-ми битной палитрой предпочтительнее при небольшой частоте работы контроллера, в данном дисплее цвета в этом случае получаются очень бледными.

Datasheet на контроллер для дисплея LPH9157-2 найти не удалось, однако на глаза попался пример инициализации с подробным описанием команд, что уже было достаточно для начала экспериментов. Из команд инициализации особый интерес представляет команда Memory Access Control (36h), т.к. она позволяет задавать, с помощью следующего за ней байта данных, направление заполнения области дисплея.

В этом байте данных нас интересуют старшие 3 бита: 0bVHRXXXXX, где V – отвечает за направление заполнения по вертикали (0 — сверху-вниз, 1 — снизу-вверх), H — заполнение по горизонтали (0 — слева-направо, 1 — справа-налево), R – позволяет менять местами строки и столбцы.

Как видно из рисунка, вместе с изменением направления заполнения области дисплея, меняется и начальная позиция осей x и y.

Этого уже достаточно, чтобы при выводе текстовой информации обеспечивать программным образом поворот текста на 90º, 180º и 270º.

А почему же тогда, для правильного отображения текста, при его повороте на 90º, и 270º, не использовать возможность поменять строки и столбцы местами, чего можно добиться, устанавливая бит R в «1»?

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

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

При выводе символа, функцией Send_ Symbol (задаётся цвет символа и цвет фона) предварительно задаётся та область экрана, где будет отображён один байт из пяти, формирующих изображение (в библиотеке используется шрифт 5х8 пикселей). Изображение символа с помощью функции Send_Symbol_Shadow (без задаваемого цвета фона) – попиксельное.

С целью отображения на дисплее большого объёма текстовой информации, в библиотеке я использовал шрифт 5х8 пикселей, который, при увеличении масштаба изображения, немного напоминает такое течение в изобразительном искусстве, как кубизм. Вы можете использовать любой другой шрифт большего размера , для этого вам необходимо переработать функции Send_ Symbol и Send_Symbol_Shadow под себя и учесть ширину символа в функциях LCD_Puts, LCD_Putsf, LCD_Puts_Shadow и LCD_Putsf_Shadow.

Также, при использовании библиотеки, следует иметь ввиду, что при запуске дисплея, начало адреса осей X и Y – левый верхний угол, а при изменении направления вывода текста или изображения (90º, 180º, 270º), осью X всегда будет считаться сторона над верхней частью выводимого текста или изображения.

Библиотека (для CodeVisionAVR) работы с LPH9157-2 содержит следующие функции (приведены только пользовательские функции!):

2. void Put_Pixel (char x, char y, unsigned int color)

Функция вывода точки (пикселя). x и y – координаты экрана, где будет отображён пиксель цветом color.

3. void LCD_Putchar (char symbol, char x, char y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода одного символа ASCII-кода. Данная функция рассчитана на вывод символов размером 5х8 пикселей, библиотека которых находится в файле Symbols.h. symbol – выводимый на экран символ в ASCII-кодировке; x и y – начальная координата вывода символа; t_ color – цвет пикселя; b_ color – цвет фона; переменные zoom_ width и zoom_ height увеличивают символ на экране в указанное число раз; rot – угол поворота текста (0º , 90º, 180º, 270º).

4. void LCD_Putchar_Shadow (char symbol, char x, char y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 3, только без цвета фона.

5. void LCD_Puts(char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной в ram-памяти микроконтроллера. В отличие от библиотеки для LPH8731-3C, для вывода строки задаётся не номер строки и столбца, на которые предполагаемо разбит экран, а адреса начальных пикселей x и y.

6. void LCD_Puts_Shadow (char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 5, только без цвета фона.

7 . void LCD_Putsf(flash char *str, int x, int y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)

Функция вывода строки, расположенной во flash-памяти микроконтроллера.

8. void LCD_Putsf_Shadow (flash char *str, int x, int y, int t_color, char zoom_width, char zoom_height, int rot)

То же, что и 7, только без цвета фона.

9. void LCD_FillScreen (unsigned int color)

Функция заливки экрана цветом color.

10. void LCD_Output_image (char x, char y, char width, char height, flash char *img, int rot)

Функция вывода картинки. x и y начальная позиция выводимого на экран изображения; width и height – ширина и высота изображения (в пикселях); * img – указатель на массив данных, составляющих изображение; rot – угол поворота изображения (0º , 90º, 180º, 270º). Данная функция предполагает, что массив данных изображения расположен во flash-памяти микроконтроллера. Для преобразования необходимого вам изображения в массив, содержащий цвет пикселей, можно воспользоваться программами Image2Lcd или Nokia Image Creator, которые несложно найти на просторах интернета. Единственное требование – направление вывода массива изображения должно выполняться слева-направо, сверху-вниз! При использовании 16-ти битной палитры, при преобразовании изображения в массив типа char, обязательно старший байт должен идти первым!

11. void LCD_DrawLine (char x1, char y1, char x2, char y2, int color)

Нарисовать линию. x1 и y1 – начальная позиция линии; x2 и y2 – конечная позиция линии.

12. void LCD_DrawRect (char x1, char y1, char width, char height, char size, int color)

Нарисовать рамку. size — толщина рамки.

13. void LCD_FillRect (char x1, char y1, char width, char height, int color);

14. void LCD_DrawCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать окружность. rad – радиус окружности в пикселях.

15. void LCD_FillCircle (char xcenter, char ycenter, char rad, int color);

Нарисовать круг, заполненный цветом color.

16. void LCD_DrawTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Нарисовать контуры треугольника.

17. void LCD_FillTriangle (char x1, char y1, char x2, char y2, char x3, char y3, int color)

Читайте также  Замена алюминиевой проводки на медную в квартире

Нарисовать треугольник, заполненный цветом color.

В самом начале библиотеки, е сли объявлен макрос _8_BIT_COLOR , то цветовая палитра дисплея будет составлять 256 цветов, иначе — 65536 цветов. Макрос _GEOMETRICAL позволяет использовать функции вывода линии, рамки, прямоугольника, окружности, круга и треугольника.

Особенности работы с дисплеем lph9157-2

Администратор

Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1

Внятной документации на этот экран я не нашел поэтому пришлось разбираться с тем что есть и экспериментировать. В качестве управляющего устройства я использовал Raspberry PI. Так-же была написана программа позволяющая превратить этот экран в мини-монитор.

Данный дисплей имеет разрешение 135 x 176 пикселей и даёт возможность работать с тремя цветовыми палитрами 16(6-5-6), 12(4-4-4) и 8(3-3-2) бит.

Распиновка и подключение

Тут всё просто, экран питается напряжением 2,9 вольт, подсветка (LED±) запитывается отдельно напряжением примерно 12 вольт(я использовал батарею аккумуляторов соединённую с подсветкой через резистор на 510 Ом).

#
Name
Function

RST
Reset input, active low

CS
Chip select, active low

4
SYNC
External frame synchorization input, unused by default

5
CLK
SPI Clock-in signal (High-to-Low)

6
DATA
SPI Data-in signal (MSB first)

7
VCC
Power supply, normally 2.9V (I tested with 3.3V)

9
LED+
Backlight voltage, approx. 12V (depends on required current)

10
LED-
Backlight common pin

Как можно заметить экран управляется через интерфейс SPI (контакты CS/CLK/DAT(MOSI)), предположительно это лишь половина интерфейса так как отсутствует контакт MISO, следовательно писать данные в экран мы можем, а вот читать — нет(здесь следует упомянуть что SPI может работать в двунаправленном режиме с использованием одного провода (MIMO) но так как отсутствует какие либо команды чтения данных из экрана будем считать что этот режим экраном не используется).

И перед тем как переходить непосредственно к управлению экраном надо бы этот экран к чему-нибудь подключить. В моём случае это будет Raspberry Pi. Контакты SPI экрана подключены к соответствующим им контактам SPI «малины», RS и RST к GPIO_17 и GPIO_27 соответственно. Данное подключение актуально для RPI Revision-2, если у вас иная модель то названия и номера контактов GPIO могут отличаться.

Заморачиваться с разъёмом подключения экрана я не стал и просто подпаялся к выводам проводом МГТФ. Экран в данном подключении питается от 3.3В, а не от 2.9 как в описании.

Вот так выглядит вся схема в сборе

Команды управления экраном

Экран управляется достаточно просто — путём посылки по SPI команд и данных. Отличить одни от других экрану помогает состояние пина RS где высокий уровень(лог. 1) означает передачу данных, а низкий(лог. 0) передачу команд. При передаче используется тупоконечный(big-ending) порядок байт.

  • CMD_RESET 0x01 — программный сброс
  • CMD_MEMORY_ACCESS_CONTROL 0x36 — установка направления заполнения области дисплея, имеет однобайтовый аргумент 0bVHRXXXXX, где

V — заполнение по вертикали (0 — сверху-вниз, 1 — снизу-вверх),

H — заполнение по горизонтали (0 — слева-направо, 1 — справа-налево),

R — меняются местами строки и столбцы (при этом заполнение остается сверху-вниз, слева-направо))

  • CMD_WAKEUP 0x11 — выход из спящего режима
  • CMD_PALETTE 0x3A — установка цветовой палитры 8(0x02), 12(0x03) и 16(0x05) бит
  • CMD_ENABLE 0x29 — включение дисплея
  • CMD_SET_X 0x2A — задаем область рисования по X
  • CMD_SET_Y 0x2B — задаем область рисования по Y
  • CMD_START_WRITE 0x2C — начало записи в видеопамять
  • Работа экрана была проверена во всех 3х цветовых режимах но, дабы не захламлять исходник, далее я буду рассматривать только 16-битный. Во всех остальных режимах работа экрана не отличается, за исключением, разве что 12-битного — в нём на 2 пикселя приходится 3 байта, а если нужно вывести лишь одну точку то посылается 2 байта(4 младших бита последнего экраном игнорируются).

    Для доступа к GPIO «малины» была использована библиотека bcm2835.

    Начальная инициализация GPIO

    int init_gpio()
    <
    if (!bcm2835_init())
    return 0;

    // CPOL = 0, CPHA = 0, Clock idle low, data is clocked in on rising edge, output data (change) on falling edge
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);

    // в телефоне экран работает на частоте SPI в 13 МГц
    // поэтому небольшое превышение по частоте ему не повредит
    // хотя у меня он продолжал работать и при вдвое большей частоте (30 МГц)
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16); /// > 8) | (screen[y][x] 176×132 малоинформативен, для фреймбуфера было установлено разрешение 320×240, это можно сделать правкой config.txt на FAT разделе «малиновой» флешки.

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

    Исходник LPH9157-2_RPI.c#include
    #include
    #include
    #include

    #include
    #include
    #include

    // соответствия контактов GPIO и LCD
    #define LCD_RS RPI_V2_GPIO_P1_11
    #define LCD_RESET RPI_V2_GPIO_P1_13

    #define RS_CMD 0
    #define RS_DATA 1

    #define CMD_RESET 0x01
    #define CMD_MEMORY_ACCESS_CONTROL 0x36 // Memory Access Control
    #define CMD_WAKEUP 0x11 // Выход из спящего режима
    #define CMD_PALETTE 0x3A // Установка цветовой палитры
    #define CMD_ENABLE 0x29 //Включение дисплея

    #define CMD_SET_X 0x2A // задаем область по X
    #define CMD_SET_Y 0x2B // задаем область по Y
    #define CMD_START_WRITE 0x2C // начало записи в память

    #define _8_BIT_COLOR 0x02
    #define _12_BIT_COLOR 0x03
    #define _16_BIT_COLOR 0x05

    #define SCREEN_WIDTH 132
    #define SCREEN_HEIGHT 176

    int init_gpio()
    <
    if (!bcm2835_init())
    return 0;

    bcm2835_spi_begin();
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); /// CPOL = 0, CPHA = 0, Clock idle low,
    /// data is clocked in on rising edge,
    /// output data (change) on falling edge
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16); /// = 0) && (fb_x + 1 = 0) && (fb_y + 1 > 1) + ((add_px & 0xf7de) >> 1);
    /// ^thank you habr => http://habr.ru/p/128773/
    >
    >
    >
    screen[y][SCREEN_WIDTH — 1 — x] = (px > 8);
    >

    /// calc fps
    frame_cnt++;
    if(frame_cnt >= 100)
    <
    clock_gettime(CLOCK_MONOTONIC, &ts2);

    float allsec = (ts2.tv_sec — ts1.tv_sec) + (ts2.tv_nsec — ts1.tv_nsec) / 1000000000.0;
    float fps = frame_cnt / allsec;

    printf(«%f FPSn», fps);

    frame_cnt = 0;
    clock_gettime(CLOCK_MONOTONIC, &ts1);
    >

    munmap(fb_screenshot, scr_sz);
    close(fd_scr);
    close_gpio();

    $ gcc -o lcd LPH9157-2_RPI.c -lbcm2835 -lrt -std=gnu99

    $ sudo ./lcd -i
    pi@raspberrypi

    -i — первичная инициализация (дёргаем хардварный reset)

    -s — включить сглаживание

    -d — динамический fps (одинаковые кадры пропускаются — экономит CPU)

    Текстовый экран 8×2: инструкция по подключению и примеры использования

    Текстовый дисплей 8×2 пригодится для вывода показаний датчиков, отображения простых меню, подсказок и приветствий.

    Видеообзор

    Примеры работы для Arduino

    В качестве примера подключим дисплей к управляющей плате Arduino Uno.

    Подключение к Arduino

    Вывод Обозначение Пин Arduino Uno
    1 GND GND
    2 VCC 5V
    3 VO GND
    4 RS 12
    5 R/W GND
    6 E 11
    7 DB0
    8 DB1
    9 DB2
    10 DB3
    11 DB4 5
    12 DB5 4
    13 DB6 3
    14 DB7 2

    Для упрощения работы с LCD-дисплеем используйте встроенную библиотеку Liquid Crystal. В ней вы найдёте примеры кода с подробными комментариями.

    Вывод текста

    Для вывода первой программы приветствия, воспользуйтесь кодом вроде этого:

    Кирилица

    Существует два способа вывода кирилицы на текстовые дисплеи:

    Рассмотрим оба способа более подробно.

    Таблица знакогенератора

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

    Для вывода символа на дисплей необходимо передать его номер в шестнадцатеричной системе из таблицы знакогенератора.

    Так букве Я соответствует код B1 в шестнадцатеричной системе. Чтобы передать на экран строку «Яndex», необходимо в явном виде с помощью последовательности x## встроить в строку код символа:

    Вы можете смешивать в одной строке обычные символы и явные коды как угодно. Единственный нюанс в том, что после того, как компилятор в строке видит последовательность x , он считывает за ним все символы, которые могут являться разрядами шестнадцатеричной системы даже если их больше двух. Из-за этого нельзя использовать символы из диапазона 0-9 и A-F следом за двузначным кодом символа, иначе на дисплее отобразится неправильная информация. Чтобы обойти этот момент, можно использовать тот факт, что две строки записанные рядом склеиваются.

    Сравните две строки кода для вывода надписи «Яeee»:

    Используя полученную информацию выведем на дисплей сообщение «Привет, Амперка!»:

    Переключение страниц знакогенератора

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

    Дисплей не может одновременно отображать символы разных страниц.

    Рассмотрим пример, в котором одна и та же строка будет отображаться по-разному — в зависимости от выбранной страницы.

    Полную таблицу символов с кодами можно найти в документации к экрану.

    Использование библиотеки LiquidCrystalRus

    Совсем не обязательно мучатся со знакогенератором, чтобы вывести русский символ. Для решения проблемы скачайте и установите библиотеку LiquidCrystalRus.

    Это копия оригинальной библиотеки LiquidCrystal с добавлением русского языка. Добавленный в библиотеку код трансформирует русские символы UTF8 в правильные коды для текстового экрана.

    В качестве примера выведем фразу «Привет, Амперка» на дисплей.

    Примеры работы для Espruino

    В качестве примера подключим дисплей к управляющей плате Iskra JS.

    Подключение к Iskra JS

    Вывод Обозначение Пин Iskra JS
    1 GND GND
    2 VCC 5V
    3 VO GND
    4 RS P12
    5 R/W GND
    6 E P11
    7 DB0
    8 DB1
    9 DB2
    10 DB3
    11 DB4 P5
    12 DB5 P4
    13 DB6 P3
    14 DB7 P2

    Для работы с LCD-дисплеем из среды Espruino существует библиотека HD44780.

    Вывод текста

    Для вывода программы приветствия, воспользуйтесь скриптом:

    Кирилица

    Вывод кирилицы на дисплей с помощью платформы Iskra JS доступен через встроенную в дисплей таблицу знакогенератора.

    Таблица знакогенератора

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

    Для вывода символа на дисплей необходимо передать его номер в шестнадцатеричной системе из таблицы знакогенератора.

    Так букве Я соответствует код B1 в шестнадцатеричной системе. Чтобы передать на экран строку «Яndex», необходимо в явном виде с помощью последовательности x## встроить в строку код символа:

    Вы можете смешивать в одной строке обычные символы и явные коды как угодно. Единственный нюанс в том, что после того, как компилятор в строке видит последовательность x , он считывает за ним все символы, которые могут являться разрядами шестнадцатеричной системы даже если их больше двух. Из-за этого нельзя использовать символы из диапазона 0–9 и A–F следом за двузначным кодом символа, иначе на дисплее отобразится неправильная информация. Чтобы обойти этот момент, можно использовать тот факт, что две строки записанные рядом склеиваются.

    Сравните две строки кода для вывода надписи «Яeee»:

    Используя полученную информацию выведем на дисплей сообщение «Привет, Амперка!»:

    Переключение страниц знакогенератора

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

    Дисплей не может одновременно отображать символы разных страниц.

    Рассмотрим пример, в котором одна и та же строка будет отображаться по-разному — в зависимости от выбранной страницы.

    Полную таблицу символов с кодами можно найти в документации к экрану.

    Комнатный термометр

    Дисплей удобен для отображения показаний модулей и сенсоров. Сделаем задатки «Умного Дома», а именно «комнатный термометр».