Программирование графических LCD модулей на основе KS0108/KS0107 контроллера

Дата публикации 3 янв 2009

Программирование графических LCD модулей на основе KS0108/KS0107 контроллера — Архив WASM.RU

Введение

В предыдущей статье мы разобрали программирование знакосинтезирующих ЖКИ модулей, но не всегда бывает достаточно их возможностей. К примеру нам нужно вывести загрузку CPU в динамике, то есть как график, ну или статистику использования файла подкачки, конечно ничто не мешает определить 8 символов псевдографики, в знакосинтезирующем дисплее (от пустого до полностью заполненного), и выводить их как гистограмму в две строки, ну или нам нужно вывести простую анимацию, тут уже знакосинтезирующие ЖКИ бессильны. Но стоит заметить - во многих областях использовать графические ЖКИ нецелесообразно, к примеру, вы делаете бортовой компьютер для вашего авто. Тут конечно можно поставить и «графику», но это в значительной степени усложнит вашу программу и потребует от вашего микроконтроллера значительной мощности (программирование ЖКИ модулей с использованием микроконтроллеров рассмотрим в будущих статьях), а ведь у контроллера есть и другие более важные дела кроме рисования окошек и картинок. В общем, возможности графических модулей куда шире, чем у знакосинтезирующих, да и нет проблем с выводом родной кириллицы :smile3:.

Оборудование

Графические дисплеи в общем случае различаются разрешением от 122x32 до 320x240, типом контроллера/драйвера, интерфейсом, который бывает – параллельным, SPI последовательным, I2C последовательным, и USB - последний, как правило, встречается в дисплеях некой конторы Crystal Fontz, но они не представляют особого интереса - так как в поставке идёт уже готовая 5.25” заглушка с дисплеем и распаянным USB ну и программа для работы с ним, это как то не по дзенски. Поэтому мы рассмотрим ЖКИ с параллельным интерфейсом и в следующих статьях сами подружим их и с SPI, и с I2C, и т. д. ну и конечно запрограммируем всё это дело. Отдельного разговора заслуживают дисплеи «изъятые» из нерабочих сотовых телефонов, пейджеров, музыкальных центров у них, как правило, очень большой разброс по параметрам, типам интерфейсов, инструкциям управления. Но, тем не менее, информация, изложенная в статье, справедлива и для них, так как показывает общий принцип работы с подобными устройствами, сейчас отмечу лишь - что эти ЖКИ обычно используются контроллер с последовательным интерфейсом вроде I2C или SPI, хотя встречаются и с параллельным. Помимо всего этого дисплеи различаются типом подсветки, чаще всего она светодиодная, но выпускаются ЖКИ и с электролюминесцентной, и с подсветкой лампой холодного катода – лично я советую использовать светодиодную, так как не нужно никаких инверторов напряжения (DC-DC преобразователей) да и срок службы у светодиодов значительно больший.

Ну-с начнём. Как всегда нам нужен паяльник, припой, канифоль, прямые руки в кол-ве 2 шт. и собственно сам ЖКИ и IDE шлейф и DB-25M разъём. Типов графических модулей по сравнению со знакосинтезирующими выпускается значительно больше, тут как было с HD44780 - одного рецепта нет. Я расскажу о самом принципе пайки и написания программ для этих модулей на примере модуля тайваньской фирмы Winstar WG12864A, он выполнен на довольно распространённом контроллере Samsung KS0108/KS0107, имеет гребёнку в 20 контактов соответственно параллельный интерфейс, и светодиодную подсветку. Рассмотрим структурную схему. На входе, как и у HD44780 регистр-защёлка и так же защёлкивает по спаду, кстати, важно помнить, что эти дисплеи, как правило, не имеют поддержки 4х битного интерфейса. Далее следует два контроллера-драйвера дисплея. Сам ЖКИ имеет разрешение 128x64, каждый контроллер обслуживает область 64x64, это важно учитывать при написании программ, то есть если Вам попался дисплей с разрешением 64x64, программа немного упростится. Сам контроллер имеет всего 4 команды. Пока контроллер занят обработкой команды или выводит столбец на дисплей, установлен busy флаг, его можно считать с интерфейса см. таблицу инструкций, впрочем, его использование совсем не обязательно.

Итак, а для неизвестных индикаторов, в общем случае, алгоритм сводится к следующему:

  1. Добыть ЖКИ.
  2. Найти и скачать полное техническое описание на сам дисплей и его контроллер.
  3. Внимательно изучить диаграммы управляющих напряжений.
  4. Спаять переходник к LPT/COM порту ПК.
  5. Написать управляющую программу для PC (или МК).

Так дисплей лежит перед нами, принцип его работы мы знаем, попробуем теперь что-нибудь вывести на него, но сначала надо его подключить к LPT порту.

Рассмотрим разводку данного ЖКИ (Winstar WG12864A)

Номер контакта

Назначение

1 GND

Земля -

2 VCC

Напряжение питания 3 или 5 вольт

3 VSS

Контраст

4 RS

Команда/данные

5 R/W

Чтение/запись (замкнуть на GND)

6 E

Строб (защёлкивание по спаду)

7:14 Data bus

Шина данных

15 CS1

Выбор 1 ого контроллера

16 CS2

Выбор 2 ого контроллера

17 /RST

Сброс (не используется)

18 VEE

Выход отриц. напряжения (подать на вход регулировки контраста)

19 LED +

Подсветка + 4.2 в.

20 LED -

Подсветка -

Соответствие линий ЖКИ и LPT

LCD

LPT

4 RS

16 init

5 R/W

GND

6 E

1 /strobe

7:14 Data bus

2:9 Data

15 CS1

14

16 CS2

17

Как видно из таблицы принцип работы с дисплеем мало изменился, то есть соединение такое же, как и в случае с HD44780, но добавились две управляющие линии выбора чипов, их подпаиваем к оставшимся выходам LPT – 14, 17 соответственно, разводка LPT есть в предыдущей статье, на этом останавливаться не будем.

Теперь поговорим о пайке. Собственно я рекомендую делать так: берём старую нерабочую мать (думаю такая у каждого найдётся) выпаиваем контакты IDE интерфейса в количестве 20 штук, и припаиваем их к гребёнке ЖКИ, ну и пластиковую рамку тоже можно одеть для красоты, в общем, должно получиться как на картинке.



Теперь берём IDE шлейф с одной стороны отрезаем гнездо и подпаиваем к LPT разъёму согласно разводке, соединяем 3 и 18 проводок и не забываем про питание –, + (к молексу или USB) и подсветку. Красный провод шлейфа при этом должен соответствовать 1 (GND) контакту гребёнки ЖКИ - это избавит Вас от многих проблем. Теперь можно не париться, что крепление дисплея к проводу или шлейфу ненадёжно, и таким образом не нужно каждый раз перепаивать это дело, если Вы хотите ЖКИ использовать в другом устройстве.

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

Программирование

Хорошо всё спаяли, подключаем ЖКИ модуль к компу, подключили питание и… ничего… Всё нормально - графические ЖКИ ничего не выводят после подачи напряжения. Пишем софт для ЖКИ.

Система команд ЖКИ Winstar WG12864A

Команда

RS

RW

D7

D6

D5

D4

D3

D2

D1

D0

Описание

LCD ON/OFF

0

0

0

0

1

1

1

1

1

on

Включить ЖКИ, on – 1

Set address

0

0

0

1

X address

Установка X адреса, в X счётчике

Set page (Y address)

0

0

1

0

1

1

1

Page

Выбор страницы

Display start line

0

0

1

1

Display start line

Начало дисплея

Status read

0

1

B

U

S

Y

0

On/

off

R

E

S

E

T

0

0

0

0

Чтение статуса, BUSY – 1/0 - занят/готов, on/off – 1/0 - включен/выключен, RESET – 1/0 – был сброшен/нормальный режим

Write display data

1

0

Data

Запись данных в дисплей, автоматическое увеличение адреса RAM после каждой записи

Read display data

1

1

Data

Чтение данных из дисплея


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

Код:

Код (Text):
  1.  
  2. procedure OutCmd(cmd: byte; cs: byte);
  3. begin
  4.  OutPort($37A, 0 or cs); // E=1, RS=0, CS - выбор чипа
  5.  OutPort($378, cmd);
  6.  OutPort($37A, 1 or cs); // E=0, RS=0, CS - выбор чипа
  7. end;
  8.  
  9. procedure OutData(data: byte; cs: byte);
  10. begin
  11.  OutPort($37A, 0 or cs or 4); // E=1, RS=1, CS - выбор чипа
  12.  OutPort($378, data);
  13.  OutPort($37A, 1 or cs or 4); // E=0, RS=1, CS - выбор чипа
  14. end;

Вот тут всё довольно просто, дисплейчик уже может нас понять, теперь как и с HD44780 надо его проинициализировать – тут всё очень просто достаточно подать команду LCD_ON и всё (не забываем что для каждого контроллера отдельно).

Код:

Код (Text):
  1.  
  2. procedure InitLCD();
  3. begin
  4.  OutCmd(LCD_ON or p_on, CHIP1); // включить
  5.  OutCmd(LCD_ON or p_on, CHIP2);
  6.  sleep(1);
  7.  FillChar(buffer, 1024, 0);
  8.  RenderLCD(); // очистка
  9. end;

Вот и всё. Это было очень просто, теперь вывод самой графики. Дисплей как я уже говорил, поделён на два логических участка 64x64, помимо этого каждая область 64x64 (а их может быть и 3, и 4 – 256x64 к примеру), поделена на 8 страниц по 8x64 пикселей, каждый байт выведенный в дисплей отображается как столбец 8 пикселей, как следствие - вывели 64 байта - переключаем страницу, ещё 64 и снова переключение, после того как вывели 8 страниц переключаем контроллер и заново – эта схема довольно простая, главное понять принцип.

Код выводящий буфер (только для 128x64, ks0108 совместимого LCD).

Код:

Код (Text):
  1.  
  2. procedure RenderLCD();
  3. var page, x: dword; data: byte;
  4. begin
  5.  for page:=0 to 7 do
  6.  begin
  7.   OutCmd(LCD_SET_PAGE or page, CHIP1);
  8.   sleep(5);
  9.   OutCmd(LCD_SET_ADDRESS, CHIP1);
  10.   sleep(5);
  11.   OutCmd(LCD_START_X, CHIP1);
  12.   sleep(5);
  13.   for x:=0 to 63 do
  14.   begin
  15.    if invert then data:=not buffer[page, x] else data:=buffer[page, x];
  16.    OutData(data, CHIP1);
  17.    Delay();
  18.   end;
  19.  end;
  20.  
  21.  for page:=0 to 7 do
  22.  begin
  23.   OutCmd(LCD_SET_PAGE or page, CHIP2);
  24.   sleep(5);
  25.   OutCmd(LCD_SET_ADDRESS, CHIP2);
  26.   sleep(5);
  27.   OutCmd(LCD_START_X, CHIP2);
  28.   sleep(5);
  29.   for x:=0 to 63 do
  30.   begin
  31.    if invert then data:=not buffer[page, x+64] else data:=buffer[page, x+64];
  32.    OutData(data, CHIP2);
  33.    Delay();
  34.   end;
  35.  end;
  36. end;

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

Код:

procedure ConvBMP2LCD();

Код (Text):
  1.  
  2. procedure ConvBMP2LCD();
  3. var page, x, y: dword; data: byte;
  4. begin
  5.  for page:=0 to 7 do
  6.  begin
  7.   for x:=0 to 127 do
  8.   begin
  9.    data:=0;
  10.    for y:=0 to 7 do if BMP.Canvas.Pixels[x, (page*8)+y]=0 then data:=data or (1 shl y);
  11.    buffer[page, x]:=data;
  12.   end;
  13.  end;
  14. end;
  15.  

Просто пробегаем по столбцам изображения, записывая в буфер байты в нужном порядке. Так теперь можем рисовать в битмап нужное нам изображение и выводить на ЖКИ.


Заключение

Вот и всё что касается основ программирования графических ЖКИ. В статье мы рассмотрели программирование наиболее распространённого ЖКИ на основе KS0108/KS0107 и совместимых, так же стоит отметить, что в дикой природе встречаются ЖКИ модули с разрешением до 320x240 (обычно в КПК встраивали) у них свои особенности программирования. Например, разделение адресного пространства – на вывод в графическом режиме, и текстовый, ну и соответствующие режимы – текстовый режим с псевдографикой и полноценно графический. К ЖКИ модулям выпускаются различные опции, такие как накладываемые touch screen’ы, подогрев и т. д. правда, в розничной сети, к сожалению, этого не встречал.

А в плане встраивания в компьютер я бы ещё посоветовал подпаять к LPT пару кнопок и между записями в ЖКИ опрашивать их (чтобы перевести LPT в режим чтения надо установить 5 бит регистра 37A), ну и добавить к управляющей программе вывод меню управляемого этими кнопками.

Позже мы рассмотрим подключение ЖКИ через микроконтроллер к RS 232, а так же если попадётся ЖКИ с интерфейсом I2C. Сорцы драйвера и программы как всегда в аттаче.

Файлы к статье:

Замечания, предложения, критику на exp10der[at]mail[dot]ru.

Гринёв Роман aka Exp10der.

© Exp10der

0 4.148
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532