Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

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

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

Привлекал внимание и TFT-дисплейчик, имеющий разрешение 132x176 пикселей и палитру в 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 подбирается с учётом необходимой яркости подсветки.

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

DSCN0022(1).jpgDSCN0023.jpg

DSCN0043.jpgDSCN0057.jpg

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

LPH9157-2 рис1.jpgLPH9157-2 рис2(1).jpg

Дисплей 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 – позволяет менять местами строки и столбцы.

Рис1(1).jpg

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

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

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

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

Рис2(1).jpg

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

При выводе символа, функцией 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 < 5; a++) //Перебираю 5 байт, составляющих символ
 {
   temp_symbol = font_5x8[symbol-32][a];
   zw = 0;
   while(zw != zoom_width) //Вывод байта выполняется zw раз
   {   
   mask=0x01;  
   switch(rot) //Предварительно задаём область дисплея, где будет выводиться 1 байт из 5, формирующих символ
   {
   case 0: case 180: SetArea( x+zw, x+zw, y, y+(zoom_height*8)-1 ); break;
   case 90: case 270: SetArea( x, x+(zoom_height*8)-1, y+zw, y+zw ); break;   
   }
   LCD_RS = 1; //Передаются данные    
   for ( b = 0; b < 8; b++ ) //Цикл перебирания 8 бит байта
   {   
   zh = zoom_height; //в zoom_height раз увеличится высота символа
   while(zh != 0) //Вывод пикселя выполняется z раз
   {
   if (temp_symbol&mask)
   {
   #ifdef _8_BIT_COLOR //(8-ми битовая цветовая палитра (256 цветов))
   Send_to_lcd( DAT, t_color ); //Данные - задаём цвет пикселя
   #else    //(16-ти битовая цветовая палитра (65536 цветов))
   Send_to_lcd( DAT, (t_color >> 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<<=1; //Смещаю содержимое mask на 1 бит влево;   
   }
   zw++;
   }
 switch(rot)
 {
   case 0: case 180: x=x+zoom_width; break; //Получить адрес начального пикселя по оси x для вывода очередного байта
   case 90: case 270: y=y+zoom_width; break; //Получить адрес начального пикселя по оси y для вывода очередного байта   
 }   
 }
} 

//===============================================================
// Функция вывода одного символа ASCII-кода (из файла Symbols.h)
//===============================================================
void LCD_Putchar(char symbol, char x, char y, int t_color, int b_color, char zoom_width, char zoom_height, int rot)
{
   unsigned char m;
   if(zoom_width == 0)   zoom_width = 1;
   if(zoom_height == 0) zoom_height = 1;
   switch (rot)
   {
   case 0:  //Начальный адрес осей Х и У - левый верхний угол дисплея   
   Send_Symbol( symbol, x, y, t_color, b_color, zoom_width, zoom_height, rot);
    break;
   //================================
   case 90:
   m=y; y=x; x=m;
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x40); //Начальный адрес осей Х и У - правый верхний угол дисплея
   Send_Symbol( symbol, x, y, t_color, b_color, zoom_width, zoom_height, rot);
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x00);
   break;
   //================================
   case 180:   
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0xC0); //Начальный адрес осей Х и У - правый нижний угол дисплея
   Send_Symbol( symbol, x, y, t_color, b_color, zoom_width, zoom_height, rot);
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x00);
    break;
   //================================
    case 270:
   m=y; y=x; x=m;
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x80); //Начальный адрес осей Х и У - левый нижний угол дисплея  
   Send_Symbol( symbol, x, y, t_color, b_color, zoom_width, zoom_height, rot);
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x00);
   break;
   //================================
    default:
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x00); //Начальный адрес осей Х и У - левый верхний угол дисплея  
   Send_Symbol( symbol, x, y, t_color, b_color, zoom_width, zoom_height, rot);
   Send_to_lcd(CMD, 0x36);
   Send_to_lcd(DAT, 0x00);
   //================================  
   };  
}

Также, при использовании библиотеки, следует иметь ввиду, что при запуске дисплея, начало адреса осей 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 позволяет использовать функции вывода линии, рамки, прямоугольника, окружности, круга и треугольника.

Изобра�%Изобра�%

Прикрепленные файлы:

Теги:

Опубликована: 16.06.2013 0 1
Я собрал 0 3
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 4.9 Проголосовало: 3 чел.

Комментарии (33) | Я собрал (0) | Подписаться

0
Evgeniy #
А Вы не пробовали подключать дисплей от Siemens S75? Там экран с параллельным интерфейсом. Схем подключения в интернете я не находил...
Ответить
0

[Автор]
Igoryosha #
Не видел в этом нужды,. т.к. это требует большего количества ног контроллера, а я в основном работаю с Tiny и Mega8.
Ответить
0
while(1) #
Спасибо за отличную статью! Как я понимаю использован программный SPI? То есть можно выводы ЖК вешать на любые ноги контроллера?
Ответить
0

[Автор]
Igoryosha #
Да! В самом начале файла-библиотеки есть макросы, в которых назначаются выводы порта. Один нюанс - конфигурировать эти порты на выход вы должны вручную!
Ответить
0
while(1) #
дисплей от Siemens S75
Так они же вроде одинаковые? Судя по внешнему виду.
Ответить
0

[Автор]
Igoryosha #
Нет, там стоит дисплей LPH8924, у него 8-ми разрядная шина данных (параллельная).
Ответить
0
while(1) #
Igoryosha вы как начинали писать библиотеку для ЖК экрана? Просто хочу сам научиться писать библиотеки к разным устройствам экраны, АЦП внешние, память, датчики и др.
Ответить
0

[Автор]
Igoryosha #
Это уже дело небольшого опыта. Обычно изучаю всю информацию (datasheet, исходники других разработчиков, если есть), прорабатываю алгоритм программы и отрабатываю свой код на отладочной плате или в PROTEUS
Отредактирован 18.06.2013 16:17
Ответить
0
Алексей #
А у вас есть модель данного дисплея для протеуса?
Ответить
0
Максим #
А к PIC прилаживать его не пробовали? Как инициализировать его в протоне?
Ответить
0

[Автор]
Igoryosha #
Увы! С PIC я никогда не работал и их особенностей не знаю.
Ответить
0
hustas #
Спасибо за библиотеку. Но есть проблемка. Не получается выводить ни символы, ни строки. Дисплей инициализируется, заливка нужным цветом происходит, геометрия рисуется, а вот символы, ни в какую. Может я неправильно строки формирую, или переменные не так описываю? В чем может бить проблема? Дайте, пожалуйста, кусок кода вывода, например, "HELLO WORLD". Заранее спасибо.
Ответить
0

[Автор]
Igoryosha #
Хм... Например так: LCD_Putsf_Shadow("HELLO WORLD", 0, 0, BLUE, 1, 1, 0);
Ответить
0
hustas #
Отвечаю сам себе. С символами и строками разобрался. Все работает. НО, функция Send_Symbol_Shadow при повороте на 90 и 270 зеркалит символ. Функция LCD_Puts_Shadow не зарисовывает остаток от прошлого символа. Допустим, включили счетчик от 0 и до ..., пока, он досчитает до ста, на дисплее будет один и два прямоугольника размером шрифта и цветом шрифта. Как исправить? Буду мучить библиотеку. Пока все, если еще чего найду, напишу.
Ответить
0

[Автор]
Igoryosha #
Send_Symbol_Shadow - это "рабочая" фунция, а для вывода отдельного символа предусмотрены функциии LCD_Putchar_Shadow или LCD_Putchar! В них уже предусмотрена возможность поворота символа на 90, 180 и 270 градусов. Это раз... Во-вторых, функция Send_Symbol_Shadow печатает символы БЕЗ ИЗМЕНЕНИЯ ЦВЕТА ФОНА, т.е. пропечатывает только пиксели, формирующие символ. Поэтому, в Вашем примере счётчика нужно использовать функцию LCD_Putsf, - она позволяет задавать нужный Вам цвет фона, т.е. изменять всю ячейку 5*8, предназначенную для формирования символа!
Ответить
0
hustas #
Спасибо. Разобрался. Все работает как надо. Все рисуется и поворачивается. Еще раз спасибо за библиотеку.
Ответить
0
Serg #
Спасибо, очень интересная библиотека. Пригодилась для дисплея от CX75 (LPH8924-1). Главное, инициализация подошла, поменял вывод байта на параллельный интерфейс и можно сказать - всё заработало. Мне кажется было-бы интереснее, сделать переменную "rot"-угол поворота - глобальной, ну типа один раз указал, и "забыл", а не указывать этот параметр в каждой команде, хотя, это можно сделать и в верхнем ПО. Добавил еще функции рисования линии и точки с параметром rot, что-бы и графику выводить в той-же системе координат, что и текст.
Ответить
0

[Автор]
Igoryosha #
Хм. Переменная "rot"-угол поворота - глобальная?! Хорошая идея, даже не подумал! Что называется - нет предела совершенству!
Ответить
0
Yuri #
Уважаемый Serg, какие изменения в библиотеке вы сделали для LPH8924?
Ответить
0
Алексей #
Как переделать вашу библиотеку под аппаратный SPI на Arduino Uno?
Ответить
0

[Автор]
Igoryosha #
С Ардуино не работаю, особенностей его программирования не знаю, а на "обычном" СИ:
#else // _USE_SOFT_SPI
//==================================
// Аппаратный SPI
//==================================
void Send_spi(unsigned char data)
{
//Частота сигнала SCK: Fкварца/16
SPCR = (1 сдвиг влево SPE)|(1 сдвиг влево MSTR)|(1 сдвиг влево SPR0);
SPDR = data;
while(!(SPSR & (1 сдвиг влево SPIF)));
SPCR = 0;
}

#endif // _USE_SOFT_SPI
Ответить
0
Павел #
Спасибо, все работает. Портировал на pic за 1 час, почти без изменений завелось!
Ответить
0
Вася #
Нормально ли перенесет дисплей питание в 3,3 вольта? Или обязательно нужны резисторные делители и напряжение питания в 2,9 вольта? Извините за глупый вопрос, но не очень хочется экспериментировать и сжечь дисплей.
Ответить
0

[Автор]
Igoryosha #
В принципе, будет работать и при 3.3 В, но вот насколько долго, не скажу. Лучше всё-таки придерживаться нормированного значения!
Ответить
0
Вася #
Понял. Спасибо. А в своих устройствах вы везде используете делители и питание в 5 вольт? Некоторые МК могут спокойно работать и при 2,9 вольта. Подключали ли вы его на прямую к портам ? Если да, то какой стабилизатор вы использовали для питания всей схемы? Нашел стабы на 2,5 вольта, но на 2,9 нет. Вроде есть и на 3 вольта. К чему я все это. Просто хочу максимально упростить схему и разводку платы. Конечно пару резисторов не очень утяжелят устройство, но все же...
Ответить
0

[Автор]
Igoryosha #
Вы можете в своих разработках применить линейные стабилизаторы серии LD1117. У этой серии широкая номенклатура напряжений, и есть напряжение стабилизации 2,85 В.
Ответить
0
Вася #
Спасибо за помощь. На следующей неделе буду испытывать в железе.
Ответить
0
DIM #
Выложите пожалуйста схему и библиотеку под LPH8924
Ответить
0
Александр #
Здравствуйте, есть у меня старый Siemens CX75. хочу заюзать от него lcd, но не могу найти на него(на его контроллер никакого даташита). Не могу еще понять CX75, M75, S75 там одни и теже lcd или же нет? Если кто что знает, пиши буду благодарен за инфотрмацию.
Ответить
0
DIM #
На CX75 как раз и стоит LPH8924. В нем параллельный интерфейс. Выше кто-то смог подключить, но как это сделал не описал
Ответить
0
Андрей #
Здравствуйте. Вместо clk (pin5) на lph8924-1 выведен gnd. Но есть pin12 - read, и pin13 - write. Посхеме из телефона read подтянут к питанию через 100КОм.
Правильно я понимаю что вместо дрыганья clk, нужно просто дрыгать точно также write, а байт данных сразу выставить в какой нибудь порт?
(Ну вот никто не хочет делится)
Ответить
0
skadi #
Перепилил под ардуину наскоро
https://github.com/skadiexe/LPH9157-2-display-arduino-library
Ответить
0
azq2 #
Делал недавно для STM32, работает с параллельным lph8924.
https://github.com/Azq2/stm32-lcd-lph8924-1
Низкоуровневая либа.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Мультиметр Mastech MS8239C FM-модуль RDA5807M
вверх