Подключение графического жк-дисплея 128х64 ks0108 к at89c52

Графический экран WG12864B (и ему подобные на ks0107/ks0108)

Когда-то товарищ рассказал нам как с знакосинтезирующим lcd экраном, а также обучил его русской речи и даже основам графики – нарисовал несколько значков. Вот только примитивные значки это максимум, что можно получить от символьных дисплеев — и то с некоторым трудом, без проблем только буковки-циферки, строчные-заглавные. А хочется картинок.

Размеров, шрифтов разных, курсивов, там, менюшек модных. Для этого придумали графические дисплеи. Они, как и символьные, формируют изображение зажигая/гася точки-пиксели. Кстати, как-то мы обошли вниманием в прошлый раз тот факт, что работать с точечками напрямую было бы очень уныло — никаких выводов не напасёшься (80х16 точек у символьного и 128х64 у графического).

Но добрые китайские духи электроники позаботились о нас и снабдили эти девайсы собственными контроллерами. Для символьных экранов стандартный контроллер HD44780 (ks0066) а для графических — ks0107 (ks0108). В случае WG12864B их там целых два — на на правую и левую часть экрана.

Это потому что ks0108 может обеспечить вывод только на 64х64точки, вот и получился двухядерный дисплей=) Общаться с контроллерами дисплея предстоит по:

DB0-DB7 — шине данных

R/W — указывая, передаём — 0 (или читаем — 1)
D/I — данные — 1 (или команду — 0)
CS1, CS2 — какому контроллеру
E – и проталкивая каждое действие синхроимпульсом Также есть:

RST — сброс(резет)

Vdd — питание 5В
GND — земля
Vo — контраст
Vee — источник отрицательного напряжения для контраста(если экран инверсный)
A — анод и
K — катод светодиода подсветки

Поиграемся с , вот его распиновка:

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

Напрасно, кстати — падение на светодиодах подсветки, как гласит , не более 4.6 вольт, и впихивая туда все 5, рискуем их пожечь безвозвратно.

В ИДЕ-шку не включена библиотека для работы с графическими дисплеями, а на плейграунде лежит старая версия, поэтому берём , или у .
Подключаем согласно описанию (GLCD_Documentation.pdf лежит в папке glcddoc, можно взять или почитать ), наш дисплей — “Panel A”(в доке ошибка, см далее, юзайте эту схему, она правильная)
Удивляясь столь извращённому методу разбрасывания проводов по дуине, читаем чуть внимательней и узнаём, что совсем не обязательно именно так плести этот клубокможно поменять расположение линий поправив glcdconfigks0108_Arduino.h. То есть можем расположить эти 13 выводов в произвольном порядке, оставляя свободными именно те пины (… все 7, ни в чём себе не отказывайте, ага=), которые понадобятся нам для подключения всего остального.

Но мы так делать не будем, а просто побыстрей закинем в arduino-xxxhardwarelibraries папку glcd из скачанного архива. Запустим ИДЕ-шку и выбрав File->Exampes->glcd>ks0108example, трясущимися руками зальём всё это дело в плату. Залилось, включилось, крутим контраст… и что-то фигово видно=

Меряем питание и узнаём что наш экран ужасно прожорлив=) Просело аж до 4.2 В. Подключаем внешнее питание.Чтозаужоснах! Экран перепутался пополам= Тут самое время вспомнить, что у нас именно два контроллера и запись в них осуществляется по очереди, посредством выбора одного из них еденичкой на линии CS1 или CS2. Они-то у нас и перепутались… как-то, а точнее положение их не соответствует, предложенной автором распиновке= Меняем местами.Так гораздо лучше=) Симпатично, можно позаливать ещё примеры. Там есть «игра» жизнь, с ужасной скоростью прокручиваемые шрифты и бегущие таймеры, всем своим видом показывающие не высокую скорость обновления данного дисплея=) Часы мне так и не удалось скомпилировать — ИДЕ-шка непрерывно ругается на отсутствие библиотек (а при их добавлении сыплет другими ошибками). Особого внимания стоит игра Rocket, добавив потенциометр и бузер можно немного по ностальгировать=) Но пора уже слепить что-нибудь своё, пусть и не столь впечатляющее.

Для этого придётся почитать объёмистое описание этой .

А для более полного краштеста сделаем свой рисунок и свой шрифт=)

Шрифты генерятся утилиткой GLCDFontCreator2, качать , или у .

Запускается жмаканьем на start.bat, вот такой френдли интерфейс.Кнопки Open Font/Save Font — это для внутреннего, понятного только для GLCDFontCreator2, формата шрифтов(рабочие файлы), открывать сами шрифты прога не умеет — ни сконвертированные ею самою в .h ни .ttf=(

Так что жмём NewFont, и уже там импортируем какой-нибудь шрифт из уже установленных у вас в системе.

Стоит сразу как-нибудь осмысленно обозвать своё творение, т.к. именно под этим именем (newFont у меня=) он, впоследствии, будет доступен нашему скетчу. Можно что-нибудь подрисовать.Давим кнопку Export, указывая желаемое имя файла и расположение (да и не забудьте к имени файла дописать “.h”, программа не считает, что это нужно=) Всё это круто, за исключением одной мелочи — русских букв программа не знает=( Если указать диапазон символов помимо стандартного (Start Index и Char Count), то на месте родной кириллицы открытого шрифта видны только пустые шедевры Малевича. Можно попробовать вместо них намалевать чего-нибудь, но мне жутко лень=)

К тому же товарищ уже соответствующие исследования и работы. Правда он пошёл несколько иным путём — не через GLCDFontCreator2 а используя (если с narod.ru что-то случится то файл можно взять у ).

В результате у него получился шрифт его то я и использую=) Так, накреативили шрифты, теперь займёмся картинками. Для этого нам прям в архив с библиотекой засунули папку bitmaps, которая хорошо видна в виде тестового скетча из примеров glcd в Arduino IDE, но почему-то не компилится=)))

А всё дело в том, что там лежит скетч для Processig-а, и даже готовый к запуску файлик glcd/bitmaps/utils/java/glcdMakeBitmap.jar

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

Если картинка смогла прожеваться то в окошке нам об этом сообщат, и даже покажут что получилось, а в папке glcd/bitmaps появится файл «имя_втащеного_файла.h» Теперь нарисуем простенький скетч для проверки всего этого безобразия в действии.#include //подключим библиотеку #include “SystemRus5x7.h” // прицепим шрифты #include “new_Font.h” #include “Gothic.

h” #include “zb.h” // прицепим картинки #include “bender.h” gText LeftTextArea; void setup() { GLCD.Init(); //инициализация } void loop() { GLCD.SelectFont(SystemRus); //выбираем шрифт GLCD.println(“Графические экраны, “); //пишем им GLCD.println(” это жутко прикольно”); delay(2000); GLCD.println(“сюда можно впихнуть “); GLCD.

println(“много текста=)”); delay(2000); GLCD.println(“”); GLCD.println(“И даже разными “); GLCD.println(” шрифтами”); delay(3000); GLCD.ClearScreen(); //очистим экран GLCD.SelectFont(Gothic); //выберем другой шрифт GLCD.CursorToXY(8,5); //установим курсор GLCD.println(“RoboCraft”); //и напишем там чего-нибудь GLCD.SelectFont(new_Font); GLCD.CursorToXY(10,35); GLCD.

println(“WG12864B”); delay(5000); GLCD.ClearScreen(); GLCD.SelectFont(SystemRus); GLCD.CursorToXY(0,25); GLCD.println(” А еще можно выводить”); GLCD.println(” простые картинки”); delay(3000); GLCD.ClearScreen(); GLCD.DrawBitmap(zb, 0, 0); //выведем картинку delay(2000); GLCD.ClearScreen(); GLCD.DrawBitmap(bender, 0, 0); //и ещё одну delay(2000); GLCD.FillRect(GLCD.

CenterX + 12, 0, GLCD.CenterX -22, GLCD.Bottom, WHITE); //сотрём участок картинки GLCD.DrawRoundRect(GLCD.CenterX + 13, 0, 49, GLCD.Bottom, 5); // и нарисуем там “облачко” почти как в комиксах=) delay(200); LeftTextArea.DefineArea(GLCD.CenterX + 15, 3, GLCD.Right-2, GLCD.Bottom-3, SCROLL_UP); // в облачке сделаем текстовую область с прокруткой вверх LeftTextArea.

SelectFont(SystemRus); //выберем шрифт для этой текстовой области LeftTextArea.println(“Работать, жалкие людишки!”);// бендер говорит LeftTextArea.println(” “); delay(2000); LeftTextArea.println(“Слава”); LeftTextArea.println(“робатам!”); LeftTextArea.println(” “); delay(2000); LeftTextArea.println(“Смерть человекам!”); delay(3000); GLCD.

ClearScreen(); }Шрифты и картинки в скетч включаются также как и библиотеки, и жрут немало места(особенно крупные шрифты)Например этот скетч влезет только(как минимум) в плату на базе Atmega328 .
Скетч, шрифты и картинки одним . Видео того, что получилось: Осталось разобраться с менюшками и прикрутить экран к сдвиговым регистрам для экономии ног.

Но это уже совсем другая история=)

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

описания библиотеки GLCD.
Также, пока я собирался выложить эти статьи товарищ а wg1286 говорить по-русски=)

Источник: http://robocraft.ru/blog/arduino/909.html

Работа с графическим дисплеем WG12864 на базе контроллера KS0107

Обычно для вывода информации сигнального дисплея на HD44780 более чем достаточно. Но иногда нужно нарисовать картинку, график или хочется сделать красиво, с модными менюшками. Тут на помощь приходят графические дисплеи.

Одним из самых простых и доступных является дисплей на контроллере KS0107 или аналоге. Например, WG12864A от Winstar. Сам дисплей вполне свободно достается, имеет довольно большой размер (диагональ около 80мм) и разрешение 128х64 пикселя. Монохромный.

Цена вопроса 400-500р.
 

Вот такой вот:

Подключение Управление дисплеем параллельное. Есть шина данных и линии задания направления и вида данных. Это, кстати, один из минусов — требует очень много проводов управления. Занимает почти 16 линий. Но зато и очень прост в работе.

Итак, если взять тот, что у меня WG12864A-TGH-VNW то у него следующая распиновка:

  • Vdd и Vss это питание, оно у него пятивольтовое.
  • Vee — источник отрицательного напряжения. Там примерно минус 5 вольт. Есть не на всех моделях этих дисплеев, у Winstar о наличии такой фенечки говорит буква V в маркировке. WG12864A-TGH-VNW
  • Vo — напряжение регулировки контраста. Туда подается либо 0…5 вольт, либо от -5 до 5, в зависимости от модели и температурного диапазона. Обычно более морозостойкие дисплеи требуют отрицательное напряжение. Схема включения простая:
  • D/I — Данные/команда. Логический уровень на этом выводе определяет предназначение кода на шине данных. 1 — данные, 0 — команда.
  • R/W — Чтение/Запись. Уровень на этой ноге задает тип действия. 1 чтение, 0 запись.
  • Е — Строб, синхронизирующий импульс. Дрыг этой вожжи вверх-вниз проворачивает шестеренки в интерфейсе контроллера.
  • DB0..7 — Шина данных, на которую мы выдаем нужный нам код.
  • CS1 и CS2 — выбор контроллера.
  • RST — сигнал сброса. Ноль на этой линии сбрасывает контроллеры в ноль. Но не сбрасывает видеопамять, только текущую адресацию.
  • A и K — питание светодиодной подсветки. Там, как правило, обычные светодиоды, так что напрямую туда 5 вольт подавать нельзя. Только через ограничительный резистор. Ток потребления подсветки весьма велик, около 200мА, падение напряжения в районе 4 вольт. На пяти вольтовом питании ограничетельный резистор должен быть порядка 5-10 Ом.

 
К контроллеру (ATMega16 на Pinboard) я подключил все следующим образом.

Данные полностью легли на PORTA, а управление на PORTB. В качестве резистора подстройки контраста я взял многооборотный переменник, что так кстати стоит рядом для подобных случаев. Питание подсветки взял с колодки от дисплеяя. Благо там все уже готово, даже управление от транзистора есть 🙂 Правда я ее просто включил.
 

Двое из ларца, одинаковых с лица. Адресация Контроллер CS0107 он может организовать матрицу только 64х64. А у нас в дисплее вдвое большая 128х64. Значит стоят два контроллера. Один отвечает за правую половину экрана, другой за левую.

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

Карта дисплея выглядит так:

Байты укладываются в два контроллера страницами по 64 байта. Всего 8 страниц на контроллер.
 

Так что для того, чтобы выставить точку с координатами на экране, например, Х = 10, Y=61 надо вычислить в каком контроллере она находится. Первый до 63, второй после, если адрес во втором контроллере, то надо вычесть 64 из координаты.

Затем вычислить страницу и номер бита. Страница это Х/8, а номер бита остаток от деления (Х%8). Потом нам надо считать нужный байт из этой страницы (если мы не хотим затронуть остальные точки), выставить в нем наш бит и вернуть байт на место.

 

Протокол обмена Тут все просто, без каких либо изысков. Выставляем на линиях RW, DI что мы хотим сделать, линиями CS1 и CS2 выставляем к кому обращаемся. На шину данных выдаем нужное число и поднимаем-опускаем линию строба.

Опа! Впрочем, есть одна тонкость. Для чтения данных строб нужно дернуть дважды, т.к. предварительно данные должны попасть в регистр-защелку. Для чтения же флага состояния такой изврат не нужен.

Вот примеры временных диаграм для разных режимов.

Чтение

И запись. Причем запись, в отличии от чтения, можно делать сразу в оба контроллера. Конечно одновременно писать данные в контроллер смысла имеет мало, разве что захочишь двойную картику получить 🙂 А вот команды обычно пишут срзау в оба.
 

Временные диаграммы, т.е. сдвиг фронтов между собой по времени может быть разным у разных контроллеров. Где то быстрей, где то медленней. Но в целом 1мкс обычно хватает. В реале обычно меньше. Лучше поглядеть в даташите на конкретный контроллер (не дисплей, в ДШ на дисплей обычно редко есть описание самого контроллера). Там обычно есть таблица вида:

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

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

Только рекомендую читать не пустоту вида 0х00, а что нибудь более веселое залить, например, шахматную доску из пикселей. По очереди 0х55 и 0хАА.
 

 

Система команд.
Она тут простейшая.

Команда D/I R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Назначение
Отображение ВКЛ/ВЫКЛ L L L L H H H H H L/H Управляет вкл/выкл отображения. Не влияет на внутреннее состояние и данные ОЗУ изображения.L: ВЫКЛH: ВКЛ
Установить Адрес L L L H Адрес Y (0 ~ 63) Заносит адрес Y в счётчик адреса Y
Установить Страницу (адрес Х) L L H L H H H Страница (0 ~ 7) Заносит адрес X в регистр адреса X
Начальная Строка Отображения L L H H Начальная строка отображения (0 ~ 63) Скроллинг вверх. На сколько пикселей сдвинуть адресное пространство. При этом уехавшее вверх, за экран, вылезет снизу, словно мы провернули экранную область как барабан
Чтение Состояния L H BUSY L ON/OFF RESET L L L L Чтение состояния.BUSYL: ГотовностьH: Выполняется команда ON/OFFL: Отображение ВКЛH: Отображение ВЫКЛRESETL: Нормальный режимH: Сброс
Запись Данных Изображения H L Данные для записи Записывает данные (DB0:7) в ОЗУ данных изображения. После записи инструкции, адрес Y увеличивается на 1 автоматически.
Чтение Данных Изображения H H Данные для чтения Читает данные (DB0:7) из ОЗУ данных изображения на шину данных. После чтения адрес Y сам увеличивается на 1 автоматически

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

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

У меня ициализация, по командам, выглядит так:
 

  • 0x3F — включить
  • 0x40 — Адрес Y=0
  • 0xB8 — Страница Х=0
  • 0xC0 — Скролл = 0 (т.е. с самого верха)

Ну и потом еще заливка сразу в оба контроллера.
 

Код Итак, приступим к коду. Чтобы было наглядней я все операции с ногами расписал в виде макросов. Заодно будет гораздо проще все перенести на другую архитектуру. Просто написав другие макросы, не правя сам код 🙂 Весь код можно поглядеть в нашей кодосвалке:

lcd_wg128.h

lcd_wg128.c
 

Покажу тут лишь характерные моменты работы с дисплеем.
 

Записью команд и данных занимаются следующие функции:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Пишем команду в выбранный контроллер
void LCD_WR_COM(u08 cmd,u08 CSC)
{ // Поднятие сигналов:
LCD_SET_CMD; // Команда
LCD_SET_W; // Запись
 
ON_CS(CSC); // Выбор чипа
 
LCD_DATA_INS(cmd); // Команду на шину данных
 
NOPS; // Подождем
LCD_PUL_E; // Дрыгнем стробом
NOPS; // Подождем
 
LCD_OFF_CS1; // Выключим
LCD_OFF_CS2; // выбор кристалла
}
 
// Пишем данные в контроллер
void LCD_WR_DATA(u08 cmd, u08 CSC)
{ // Поднятие сигналов
LCD_SET_DAT; // Данные
LCD_SET_W; // Запись
 
ON_CS(CSC); // Выбор чипа
 
LCD_DATA_INS(cmd); // Данные на шину данных
 
NOPS; // Подождем
LCD_PUL_E; // Дрыгнем стробом
NOPS; // Подождем
 
LCD_OFF_CS1; // Выключим выбор
LCD_OFF_CS2; // Чипа.
}
 
// Чтение данных из байта, адрес которого уже должен быть установлен. Надо только выбрать
// контроллер.
u08 LCD_RD_DATA(u08 CSC)
{
u08 outv; // Выставляем линии управления
LCD_SET_DAT; // Данные
LCD_SET_R; // Чтение
 
ON_CS(CSC); // Выбираем чип (только один!)
 
NOPS; // Ждем
LCD_PUL_E; // Дрыг стробом – пустое чтение, активация защелки
NOPS; // Ждем
 
LCD_UP_E; // Строб вверх
NOPS; // Ждем
outv = LCD_DATA_PIN; // Контроллер выдал данные на шину. Читаем их
LCD_DN_E; // Строб вниз
 
LCD_OFF_CS1; // Все свободны!
LCD_OFF_CS2;
 
return outv; // Возвращаем считанное
}

// Пишем команду в выбранный контроллер void LCD_WR_COM(u08 cmd,u08 CSC) { // Поднятие сигналов: LCD_SET_CMD; // Команда LCD_SET_W; // Запись ON_CS(CSC); // Выбор чипа LCD_DATA_INS(cmd); // Команду на шину данных NOPS; // Подождем LCD_PUL_E; // Дрыгнем стробом NOPS; // Подождем LCD_OFF_CS1; // Выключим LCD_OFF_CS2; // выбор кристалла } // Пишем данные в контроллер void LCD_WR_DATA(u08 cmd, u08 CSC) { // Поднятие сигналов LCD_SET_DAT; // Данные LCD_SET_W; // Запись ON_CS(CSC); // Выбор чипа LCD_DATA_INS(cmd); // Данные на шину данных NOPS; // Подождем LCD_PUL_E; // Дрыгнем стробом NOPS; // Подождем LCD_OFF_CS1; // Выключим выбор LCD_OFF_CS2; // Чипа. } // Чтение данных из байта, адрес которого уже должен быть установлен. Надо только выбрать // контроллер. u08 LCD_RD_DATA(u08 CSC) { u08 outv; // Выставляем линии управления LCD_SET_DAT; // Данные LCD_SET_R; // Чтение ON_CS(CSC); // Выбираем чип (только один!) NOPS; // Ждем LCD_PUL_E; // Дрыг стробом – пустое чтение, активация защелки NOPS; // Ждем LCD_UP_E; // Строб вверх NOPS; // Ждем outv = LCD_DATA_PIN; // Контроллер выдал данные на шину. Читаем их LCD_DN_E; // Строб вниз LCD_OFF_CS1; // Все свободны! LCD_OFF_CS2; return outv; // Возвращаем считанное }

Чтение слова состояния делать не стал. Т.к. дисплей работает весьма шустро, что на круг ожидания можно не уходить, а просто подождать несколько тактов. Собственно этих трех функций уже достаточно для работы 🙂 Остальное все свистоперделки и удобства.
 

Вроде заливки экрана:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Заливка экрана
void LCD_FILL(u08 byte)
{ for(u08 i=0; i

Источник: http://easyelectronics.ru/rabota-s-graficheskim-displeem-wg12864-na-baze-kontrollera-ks0107.html

Подключение графического индикатора (KS0108) к PIC микроконтроллеру. Часть 1 – Теория

» Схемы » Интерфейсы · Применение микроконтроллеров

31-01-2012

Использование графического индикатора кардинально меняет внешний вид вашего проекта. Он предоставляет больше свободы при отображении данных, чем символьный ЖК индикатор на базе контроллера HD44780.

В статье мы рассмотрим как подключить графический индикатор на контроллере KS0108 (или совместимом) к микроконтроллеру PIC производства компании Microchip.

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

Выбор микроконтроллера PIC16F887 связан с тем, что приложения с графическим ЖКИ требуют достаточно много ресурсов микроконтроллера (линии ввода/вывода, встроенная память) и данный микроконтроллер имеет 36 линий ввода/вывода и 14 КБайт Flash-памяти.

Графический ЖКИ, который используется в нашем проекте – это модуль WDG0151-TMI монохромного индикатора производства компании Winstar с разрешением 128×64 точки. Он выполнен на базе двух контроллеров NT7108C и NT7107C, которые совместимы с контроллерами Samsung KS0108B и KS0107B.

KS0108B – это 64 канальный точечный драйвер ЖК сегментов. Модуль WDG0151-TMI содержит два таких контроллера, чтобы обеспечить управление 128 сегментами.

С другой стороны контроллер KS0107B (NT7107C) – это 64 канальный драйвер общих линий индикатора, который генерирует временные сигналы для управления двумя сегментными драйверами.

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

Блок-схема модуля Winstar WDG0151-TMI

Нажмите для увеличения

Контроллер NT7107C управляет 64 общими линиями дисплея (COM1 – COM64). Первый контроллер NT7108C управляет левой половиной сегментов (SEG1 – SEG64) дисплея, второй NT7108C – правой половиной сегментов (SEG65 – SEG128).

Доступ к двум половинам дисплея осуществляется индивидуально посредством сигнальных линий Chip Select (CS1, CS2). Каждая половина дисплея представлена 7 горизонтальными страницами памяти, каждая высотой 8 бит (1 Байт).

Начиная с 0 страницы в левoй половине (/CS1=0), если вы передадите 1 байт данных, они будут отображены в первом столбце страницы 0.

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

Для отображения следующих 8 линий необходимо повторить эти операции, но сменив адрес страницы памяти. Общее количество байт, необходимое для отображения одного кадра (128×64 точки), в нашем случае равно 2×64×8 = 1024.

Модуль дисплея Winstar WDG0151-TMI GLCD имеет встроенный генератор отрицательного напряжения для управления контрастностью. Потенциометр регулировки контрастности (обычно 10 кОм) подключается между выводами VEE и VCC. Расположение линий ввода/вывода индикатора не стандартизировано, поэтому необходимо обратиться к технической документации на дисплей при подключении его к микроконтроллеру.

В общем случае количество выводов у графического индикатора 20.

Первые два вывода – выбор контроллера левой или правой части индикатора, активный уровень – низкий, однако существуют индикаторы с высоким активным уровнем (поэтому и понадобится еще раз техническое описание используемого индикатора от производителя).

  С помощью вывода 6 индикатора D/I (Data/Instruction) пользователь указывает, что поступает на шину данных индикатора: данные или команды (инструкции). Управляющие сигналы R/W и E имеют такое же назначение, как и в символьных индикаторах на контроллере HD44780.

Назначение выводов модуля ЖКИ WDG0151-TMI

Номервывода Обозначение Уровень Описание
1 /CS1 Низкий Выбор сегментов 1 – 64
2 /CS2 Низкий Выбор сегментов 65 – 128
3 Vss 0 В Общий («земля»)
4 VDD 5.0 В Напряжение питания
5 Vo переменный Подстройка контрастности
6 D/I или RS Низкий/Высокий Высокий: данные;Низкий: инструкции
7 R/W Низкий/Высокий Высокий: чтение данных;Низкий: запись данных;
8 E Высокий Разрешение записи/чтения
9 – 16 D0 – D7 Низкий/Высокий Шина данных
17 RST Низкий Сброс модуля ЖКИ
18 VEE Выход отрицательногонапряжения
19 A Анод подсветки дисплея
20 K Катод подсветки дисплея

Контроллеры KS0107B и KS0108B не имеют своего знакогенератора, поэтому его функции будет выполнять программа микроконтроллера. Сам ЖКИ поддерживает ряд инструкций, которые приведены ниже в таблице. Необходимо помнить, что вывод RS (D/I) должен быть в высоком состоянии при операциях чтения/записи данных и оставаться в низком состоянии, когда передаются инструкции.

Команда RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Назначение
ДисплейВКЛ/ВЫКЛ L L L L H H H H H L/H Управляет вкл/выкл отображения. Не влияет на внутреннее состояние и данные ОЗУ изображения. L: ВЫКЛH: ВКЛ
Установитьадрес L L L H Адрес Y (0 ~ 63) Заносит адрес Y в счетчик адреса Y
Установить страницу(адрес Х) L L H L H H H Страница (0 ~ 7) Заносит адрес X в регистр адреса X
Начальная строкаотображения L L H H Начальная строкаотображения (0 ~ 63) Указывает данные ОЗУ изображенияотображаемые вверху экрана
Чтениесостояния L H BUSY L ON/OFF RESET L L L L Чтение состояния.BUSY L: ГотовностьH: Выполняется командаON/OFF L: Отображение ВКЛ H: Отображение ВЫКЛRESETL: Нормальный режимH: Сброс
Запись данныхизображения H L Данные для записи Записывает данные (DB0:7) в ОЗУ данных изображения. После записи инструкции, адрес Yувеличивается на 1 автоматически.
Чтение данныхизображения H H Данные для чтения Читает данные (DB0:7) из ОЗУ данныхизображения на шину данных

  Часть 2 – Схема, программа микроконтроллера для инициализации индикатора

Источник: https://www.rlocman.ru/shem/schematics.html?di=113044

Подключение графического LCD дисплея KS0108(WG12864B1) к LPT порту

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}
");let k=document.querySelector(".flat_pm_modal[data-id-modal=\""+a.ID+"\"]");if(-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(k,d):jQuery(k).html(b+d),"px"==a.how.popup.px_s)e.bind(h,()=>{e.scrollTop()>a.how.popup.after&&(e.unbind(h),f.unbind(i),j())}),void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{e.unbind(h),f.unbind(i),j()});else{let b=setTimeout(()=>{f.unbind(i),j()},1e3*a.how.popup.after);void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{clearTimeout(b),f.unbind(i),j()})}f.on("click",".flat_pm_modal .flat_pm_crs",()=>{jQuery.arcticmodal("close")})}if(void 0!==a.how.outgoing){let b,c="0"==a.how.outgoing.indent?"":" style=\"bottom:"+a.how.outgoing.indent+"px\"",e="true"==a.how.outgoing.cross?"":"",f=jQuery(window),g="scroll.out"+a.ID,h=void 0===flatPM_getCookie("flat_out_"+a.ID+"_mb")||"false"!=flatPM_getCookie("flat_out_"+a.ID+"_mb"),i=document.createElement("div"),j=jQuery("body"),k=()=>{void 0!==a.how.outgoing.cookie&&"false"==a.how.outgoing.cookie&&h&&(jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show"),j.on("click",".flat_pm_out[data-id-out=\""+a.ID+"\"] .flat_pm_crs",function(){flatPM_setCookie("flat_out_"+a.ID+"_mb",!1)})),(void 0===a.how.outgoing.cookie||"false"!=a.how.outgoing.cookie)&&jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show")};switch(a.how.outgoing.whence){case"1":b="top";break;case"2":b="bottom";break;case"3":b="left";break;case"4":b="right";}jQuery("body > *").eq(0).before("
"+e+"
");let m=document.querySelector(".flat_pm_out[data-id-out=\""+a.ID+"\"]");-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(m,d):jQuery(m).html(e+d),"px"==a.how.outgoing.px_s?f.bind(g,()=>{f.scrollTop()>a.how.outgoing.after&&(f.unbind(g),k())}):setTimeout(()=>{k()},1e3*a.how.outgoing.after),j.on("click",".flat_pm_out .flat_pm_crs",function(){jQuery(this).parent().removeClass("show").addClass("closed")})}countMode&&(flat_count["block_"+a.ID]={},flat_count["block_"+a.ID].count=1,flat_count["block_"+a.ID].click=0,flat_count["block_"+a.ID].id=a.ID)}catch(a){console.warn(a)}}function flatPM_start(){let a=flat_pm_arr.length;if(0==a)return flat_pm_arr=[],void jQuery(".flat_pm_start, .flat_pm_end").remove();flat_body=flat_body||jQuery("body"),!flat_counter&&countMode&&(flat_counter=!0,flat_body.on("click","[data-flat-id]",function(){let a=jQuery(this),b=a.attr("data-flat-id");flat_count["block_"+b].click++}),flat_body.on("mouseenter","[data-flat-id] iframe",function(){let a=jQuery(this),b=a.closest("[data-flat-id]").attr("data-flat-id");flat_iframe=b}).on("mouseleave","[data-flat-id] iframe",function(){flat_iframe=-1}),jQuery(window).on("beforeunload",()=>{jQuery.isEmptyObject(flat_count)||jQuery.ajax({async:!1,type:"POST",url:ajaxUrlFlatPM,dataType:"json",data:{action:"flat_pm_ajax",data_me:{method:"flat_pm_block_counter",arr:flat_count}}})}).on("blur",()=>{-1!=flat_iframe&&flat_count["block_"+flat_iframe].click++})),flat_userVars.init();for(let b=0;bflat_userVars.textlen||void 0!==a.chapter_sub&&a.chapter_subflat_userVars.titlelen||void 0!==a.title_sub&&a.title_subc&&cc&&c>d&&(b=flatPM_addDays(b,-1)),b>e||cd||c-1!=flat_userVars.referer.indexOf(a))||void 0!==a.referer.referer_disabled&&-1!=a.referer.referer_disabled.findIndex(a=>-1!=flat_userVars.referer.indexOf(a)))&&(c=!0),c||void 0===a.browser||(void 0===a.browser.browser_enabled||-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser))&&(void 0===a.browser.browser_disabled||-1==a.browser.browser_disabled.indexOf(flat_userVars.browser)))){if(c&&void 0!==a.browser&&void 0!==a.browser.browser_enabled&&-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser)&&(c=!1),!c&&(void 0!==a.geo||void 0!==a.role)&&(""==flat_userVars.ccode||""==flat_userVars.country||""==flat_userVars.city||""==flat_userVars.role)){flat_pm_then.push(a),flatPM_setWrap(a),flat_body.hasClass("flat_pm_block_geo_role")||(flat_body.addClass("flat_pm_block_geo_role"),flatPM_ajax("flat_pm_block_geo_role")),c=!0}c||(flatPM_setWrap(a),flatPM_next(a))}}}let b=jQuery(".flatPM_sticky");b.each(function(){let a=jQuery(this),b=a.data("height")||350,c=a.data("top");a.wrap("
");let d=a.parent()[0];flatPM_sticky(this,d,c)}),debugMode||countMode||jQuery("[data-flat-id]:not([data-id-out]):not([data-id-modal])").contents().unwrap(),flat_pm_arr=[],jQuery(".flat_pm_start, .flat_pm_end").remove()}

Всем привет!

Что-то давно я статей не писал: Ну пожалуй начнем. Сегодня на операционном столе у нас дисплей фирмы Wincom Tech с расширением 128*64 точки на базе контроллера KS0108(WG12864B1). Его мне любезно предоставил админ данного портала Roman , за что ему большое спасибо. Сейчас мы этот дисплей подключим к компьютеру по LPT.

Начнем

И так, вот что нам понадобиться:

Сам дисплей

Переменные резисторы на 10К и 100 Ом

постоянный резистор на 6ть Ом 

И кабели:

  1. Для подключения принтера к lpt
  2. для подключения принтера к usb (usb A to usb B)

С расходников и инструментов нам понадобятся:

  1. Паяльник и паяльные принадлежности
  2. Монтажный провод
  3. Кусачки (аКа Бокорезы)
  4. Отвертка
  5. Провод монтажный (любой, желательно тонкий, просто его будет удобнее паять)
  6. Мультиметр
  7. Подставка-держатель (не обязательно, но очень удобно).

Хардваре

И так принципиальная схема и расспиновка нашего дисплея:

 PIN NO.  Symbol  Level Function
1 CS1 H Chip Selection Signal for IC1
2 CS2 H Chip Selection Signal IC2
3 Vss 0V Ground
4 VDD 5.0V Power supply for logic circuit
5 V0 Contrast adjust
6 RS H/L Register select signal
7 R/W H/L  H : Data Read(LCD to MPU) L : Data Write(MPU to LCM)
8 E H/L Enable signal
9 DB0 H/L Data Bus Line
10 DB1 H/L Data Bus Line
11 DB2 H/L Data Bus Line
12 DB3 H/L Data Bus Line
13 DB4 H/L Data Bus Line
14 DB5 H/L Data Bus Line
15 DB6 H/L Data Bus Line
16 DB7 H/L Data Bus Line
17 RST H/L Reset (Active ” Low”)
18 Vout -10V Output for LCD driver circuit
19 A (+) Power supply for BL LED(+5.0v)
20 K (-) Power supply for BL LED(-)

Берем наш принтерный лпт-провод и разбираем крышку. Они легко снимаются с помощью отвертки , достаточно отогнуть 4 защелки по 2 с каждой стороны.

Оставляем только разъем который идет в компьютер, другой отрезаем, он нам не нужен.

Займемся вторым коннектором.

Отрезаем все ненужные провода (не забудьте оставить один провод для питания) У вас должно остаться 15 проводов. Вот что должно у вас получиться

Теперь берем второй кабель (USB) и отрезаем кусок кабеля вместе с разъемом usb A (плоский) такой длинны что бы он дотянулся от Лпт до свободного порта USB.

Зачищаем и видим 4 провода

Нас интересует только питание, скорей всего это красный и черный провод, на всякий случай советую прозвонить. Мы нашли Питание, теперь припаиваем землю к земле на нашем разъеме DB-25 (lpt) а Положительный контакт (5v) к проводу который мы оставили и изолируем его термоусадочной трубкой или изолентой

Следующим шагом припаиваем вот эту кучу проводов к дисплею (следите за расспиновкой)

Должно получиться нечто похожее

Теперь осталось припаять 2 переменных резистора и бросить пару проводов с землей и питанием согласно схемы.Вот так это вышло у меня :

И вот так это выглядит (Ах да куда ж в нашем деле без чая)

Теперь собираем Разъемы воедино.

Выключаем компьютер и подсоединяем наш дисплей (это делается во избежание статического удара и выхода из строя дисплея). Включаем компьютер. Дисплей засветился и все точки стали черными

Это Хорошо , значит все собрано правильно на 35-40 процентов. Если дисплей не загорелся или нету точек, то покрутите резисторы:

Так с Хардваре все: Едем дальше!

SoftWare

Теперь настроем программную реализацию

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

Установка драйверов.

После того как вы скачали архив DLPortIO и распаковали его, переходите в каталог install и запустите файл Install.exe . После завершения инсталляции перезагрузите компьютер.

Непосредственно lcdmonitor

LCDMonitor 3.07.11

Программа уже установлена и ее достаточно просто распаковать. После чего запускаем файл LCDMonitor3

Откроется окно

Переходим в Опции Модули и включаем модуль KS0108

Теперь нажимаем свойства , выбираем адрес порта и время задержки

Во время процесса должно появляться нечто подобное

Теперь точно так же как мы включили Модуль KS0108 включаем остальные, ну например:

Нажимаем Галочку вверху окна: Видим теперь справа появились выбранные модули. Нажимаем на поле посреди окна , оно должно стать зеленым, а потом кликаем на модуль 2 раза для открытия его структуры.

В модуле 4-х строчные часы видим четыре строчки.

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

В поле посредине экрана можно писать не только Модули а и просто текст.

Теперь все готово. Нажимаем предварительный просмотр и на дисплеи появляется:

Все работает? Тогда нажмем на Стрелочку вверху окна и программа свернется, а дисплей начнет отображать информацию.

Теперь осталось только выбрать корпус для дисплея. Но поскольку как известно на вкус и цвет все фломастеры разные, то оставлю этот этап для вас. Могу лишь посоветовать: если вы будете встраивать его в корпус компьютера, например в 5.25 панель, то питание можно взять с Molexа

Достаточно подключить черный и красный провод вместо юсб:

P.S. Так же мне понравилась программа LcdStudio совету попробовать и ее.Скачать можно здесь

На этом Все!!! С вами был MasterNeo.

 

P.S. Файлы:

  • DLPortIO.zip
  • Lcdmonitor3_0_7_11.zip
  • Datasheet (даташит) на WG12864B1

Источник: https://www.modding.kh.ua/articles/159-cd-0108wg12864b1-pt-.html

Подключение графического дисплея МТ12232-А к микроконтроллеру AVR

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

   За преимущества графических дисплеев приходиться платить деньгами и ресурсами микроконтроллера. Как правило графические дисплеи дороже знакосинтезирующих и у них нет знакогенератора и встроенных функций рисования. Поэтому вся работу по выводу текста и рисованию графики приходится выполнять микроконтроллеру. 

   В этой статье мы рассмотрим подключение и работу с графическим дисплеем МТ12232-А. Он выпускается отечественной фирмой МЭЛТ, прост в управлении и является одним из самых доступных по цене. 

   МТ12232-А – это монохромный жидкокристаллический модуль, позволяющий отображать графическое поле 122 х 32 пикселя. Размер одного пикселя 0.44 х 0.44 мм. Напряжение питания 3.3 – 5 Вольт. Потребляемый ток порядка 1.5 мА. Напряжение питания подсветки 4 В при токе в 70 мА. Габаритные размеры дисплея 77 х 38 мм.

   МТ12232-А имеет 8-ми разрядную шину данных, 5 управляющих выводов, выводы питания модуля и выводы питания подсветки. 

   Для подключения МТ12232 к микроконтроллеру понадобится 14 выводов. Теоретически, можно сэкономить 2 вывода, если не использовать вывод сброса дисплея – RESET и не управлять подсветкой. К RESET можно подключить цепочку сброса из резистора и конденсатора, однако на сайте МЭЛТ в рекомендациях по применению жк дисплеев рекомендуется подключать RESET к контроллеру.

   Подключается все довольно банально – напрямую к микроконтроллеру.

 

   Материал по МТ12232 я планировал написать давно, но, как это часто бывает, постоянно не доходили руки.

И вот, сев на днях за статью, я обнаружил, что в даташите на дисплей произошли изменения – 13 вывод МТ12232, который раннее не использовался и был помечен в документации как NC, теперь регулирует контрастность.

Правда, при 5-ти вольтовом питании дисплея, этот резистор не требуется, поэтому мне не пришлось вносить в схему никаких изменений.

   Модуль МТ12232-А имеет в своем составе два независимых контроллера, каждый из которых управляет своей половинкой жидко-кристаллического дисплея. Выбор контроллера осуществляется с помощью сигнала chip select – CS (1 –  контроллер левой половины, 0 – контроллер правой половины). 

   Изображение на дисплее представляет собой содержимое оперативной памяти этих контроллеров. Каждому черному пикселю на дисплее соответствует логическая “1” в ячейке ОЗУ.

ОЗУ имеют размер 88 х 32 и разбиты на 4 страницы размером 80 х 8 бит каждая.

Запись/чтение данных в/из ОЗУ осуществляется побайтно, поэтому для вывода одного пикселя приходится считывать байт ОЗУ, устанавливать нужный бит и записывать байт обратно. 

   На дисплее отображается только 61 байт из 80 для каждой страницы ОЗУ, что довольно странно.

Кроме того, соответствие адресов ячеек ОЗУ и точек дисплея, которое ты можешь посмотреть в даташите, несколько неудобно.

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

   Для МТ12232-А я написал драйвер. Он реализует низкоуровневые функции обмена данными между микроконтроллером и дисплеем, функции инициализации, функции вывода текста и простой графики, как то рисование линий, окружностей и прямоугольников. 

   В конце статьи присоединены архивы проектов для компиляторов IAR, GCC и CodeVision, оттуда можно взять драйвер. Это два файла – lcd_graph_lib.c и  lcd_graph_lib.h

    Чтобы подключить драйвер к своему проекту нужно:

– скопировать хедер и сишный файл в папку проекта,

– включить хедер файл в main.c

       #include “lcd_graph_lib.h”

– настроить заголовочный файл

     задать частоту тактирования мк, порты и выводы, к которым подключен дисплей

  Черновую работу по обмену данными между микроконтроллером и дисплеем реализуют четыре функции:

void LCDG_SendCom(unsigned char data)   //функция записи команд

void LCDG_SendData(unsigned char data)  //функция записи данных

unsigned char LCDG_ReadData(void)         //функция чтения данных

void LCDG_WaitFLAG_BUSY(void)             //функция ожидания флага занятости  

   Последняя функция используется исключительно внутри драйвера.

   При любом обмене с модулем  МТ12232-А микроконтроллер должен выбирать один из двух контроллеров. Для этого используются макросы:

#define SelectLeftChip()   SetBit(PORT_LCD_CON, CS)

#define SelectRightChip()   ClearBit(PORT_LCD_CON, CS)

   Запись/чтение данных в контроллер модуля MT12232-A требует предварительной установки страницы ОЗУ и адреса внутри нее. Делается это с помощью команд Set Page и Set Adress, формат которых ты можешь посмотреть в документации. 

   Процедуру чтения данных нужно выполнять дважды. Первое чтение – холостое, второе – рабочее. Этот момент описан в рекомендациях на сайте МЭЛТ.

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

Примеры:

//подача команды

SelectLeftChip();

LCDG_SendCom(COM_CLEAR_RMW);

//запись данных

SelectLeftChip();

LCDG_SendCom(page);

LCDG_SendCom(adress);

LCDG_SendData(0);

//чтение данных

SelectLeftChip();

LCDG_WaitFLAG_BUSY();

LCDG_SendCom(realPage);

LCDG_SendCom(realAdr);

LCDG_ReadData();

currentData = LCDG_ReadData(); 

   Их две – инициализация портов микроконтроллера и инициализация двух контроллеров  модуля MT12232-A. Инициализация модуля представляет собой подачу последовательности команд, которая описана в документации. 

void LCDG_InitPort(void);     //инициализация портов                           

void LCDG_InitLcd(void);      //инициализация модуля

   Также к инициализации я отношу функции очистки дисплея.

void LCDG_ClrDisp(unsigned char x1, unsigned char x2);   //очищает дисплей от x1 до x2
#define LCDG_ClrAllDisp() LCDG_ClrDisp(0, 122)            //полная очистка дисплея

x1 и x2 – координаты по оси х, которые могут принимать значения от 0 до 122

   Знакогенератор представляет собой набор функций, реализующих вывод текста на дисплей МТ12232-А. 

   Текст можно выводить в фиксированные знакоместа и строки. Знакомест 20 штук, они задаются с помощью массива PlaceArray[] (смотри сишный файл). Количество строк соответствует количеству страниц ОЗУ, то есть их 4. Почему я не стал делать вывод текста в произвольном месте? Потому что такая реализация была бы более тяжеловесной в плане объема и скорости выполнения кода.  

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

  Текст можно выводить побуквенно, или передавая функциям указатель на строку. Также можно инвертировать цвет фона. Что может быть использовано для выделения слов, например в пуктах меню. 

//функции знакогенератора

//устанавливает флаг инверсии – текст будет белым, а фон темным 

void LCDG_SetInv(unsigned char flag);     

//выводит один символ в знакоместо                   

void  LCDG_SendSymbol(unsigned char xPos, unsigned char yPos, unsigned char data);   

//выводит строку из ОЗУ

void LCDG_SendString(unsigned char xPos, unsigned char yPos, char * string);    

//выводит строку из флэш     

void LCDG_SendStringFl(unsigned char xPos, unsigned char yPos, char __flash* string);    

где xPos и yPos – координаты знакоместа, которые могут принимать значения 0-19 и 0-3 соответственно

Примеры:

//устанавливаем белый фон и выводим букву

LCDG_SetInv(0);

LCDG_SendSymbol(10, 0, 'a');

//выводим строку из ОЗУ

LCDG_SendString(0, 0, “ChipEnable.Ru”);    

//выводим строку из флэш памяти (IAR)

__flash char text[] = “chipenable.ru”;

….

LCDG_SendStringFl(0, 1, text);

   При выводе строки из ОЗУ требуется меньше писанины, однако ты должен понимать, компилятор все равно определяет эту строку во флэш память микроконтроллера AVR,  просто в самом начале программы она будет подгружаться в ОЗУ. 

 

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

   Вывод пикселя (и соответственно остальной графики) может производиться по одному из трех методов – AND, OR, XOR. Это позволяет, например, накладывать одно изображение на другое.

Если пиксел не установлен, то вывод по методу:

AND – сбрасывает его, то есть ничего не меняет

OR –  устанавливает его

XOR – инвертирует его, то есть устанавливает

Если пиксел установлен, то вывод по методу:

AND – сбрасывает его

OR – устанавливает его, то есть ничего не меняет

XOR -инвертирует его, то есть сбрасывает

   Метод вывода задается с помощью макроопределений и фунции.

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

   Вывод графики может производиться в любую область экрана. Координаты x и y могут принимать значения 0 – 121 и 0 – 31 соответственно. 

//методы вывода на экран

#define MET_AND  0

#define MET_OR   1

#define MET_XOR  2

#define FILL_OFF 0  //заполнения нет

#define FILL_ON  1  //заполнение есть

//графические функции

//устанавливает метод вывода пикселов на экран 

void LCDG_SetMethod(unsigned char met);    

//отображает один пиксел на дисплее                                             

void LCDG_PutPixel(unsigned char XPos, unsigned char YPos); 

//рисует линию
//(x1, y1) и (x2, y2) координаты начала и конца линии                          

void LCDG_DrawLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2); 

//рисует окружность
 //(x,y) – координаты центра окружности 

void LCDG_DrawCircle(unsigned char x,unsigned char y,unsigned char r);   

//рисует прямоугольник с заполнением или без него  
//(x1, y1) и (x2, y2) координаты верхней и нижней вершины    

void LCDG_DrawRect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char

Надеюсь представленный материал облегчит тебе освоение графического модуля MT12232, да и других графических дисплеев.

MT12232-IAR
MT12232-WA
MT12232-CV
datasheet MT12232-A

Источник: http://chipenable.ru/index.php/item/103

Подключение графического дисплея 128х64

Наконец-то дошли руки до дисплея, заказанного еще в августе прошлого года.
Преимуществом дисплеев этого типа является поддержка двух протоколов передачи данных – параллельного и последовательного. За выбор отвечает 15-й пин – PSB. На плате устройства 20 выводов:

Обозн. Назначение
1 VSS Масса питания (0 В)
2 VDD Питание логики (+5 В)
3 V0 Регулировка контраста
4 RS
5 R/W
6 E
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 PSB
16 NC
17 Rst
18 Vout
19 A Питание подсветки (+5 В)
20 K Питание подсветки (0 В)

Управление дисплеем по последовательному интерфейсу

При подаче на вывод PSB низкого уровня дисплей находится в режиме последовательной передачи данных (только запись). В этом режиме необходимо использовать вывод CS. CS=H разрешает передачу данных. CS=L приводит к сбросу счетчика последовательных данных, прекращению передачи данных и очистке буфера данных.

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

Он содержит 5 последовательных “1”, за которыми следует “0”, бит RS (register select bit) и снова “0”. В свою очередь, байт команды/данных должен быть разделен на 2 группы. Первая группа – старший ниббл (DB7-DB4) со следующими за ним 4 последовательными “0”.

Вторая группа – младший ниббл (DB3-DB0) со следующими за ним 4 последовательными “0”. Эту последовательность иллюстрирует следующая диаграмма:

Итак, чтобы управлять дисплеем через последовательный интерфейс, необходимо, кроме питания на контроллер и экран, выполнить соединение с пинами:

4 RS CS: сигнал выбора чипа H: разрешить передачу данных

L: сбросить счетчик последовательных данных

5 R/W SID – ввод данных в контроллер дисплея
6 E SCLK – тактирование последовательной передачи данных
15 PSB L на этой ноге активирует последовательный интерфейс, а H – параллельный

Немного дополнительной информации, собранной ранее – здесь.

Пример управления графическим дисплеем по последовательному интерфейсу найден здесь.

Еще одна программа, вроде бы коммуницирующая с исследуемым дисплеем,  – 12864c5.rar.

Ссылка на сайт, где рассматривается управление дисплеем (в т.ч. и по последовательному интерфейсу) с тем же контроллером ST7920 – тыц.

И еще одна ссылка – управление дисплеем с контроллером ST7920 с использованием библиотеки U8glib. Может быть, это то самое, что требуется для оживления дисплея?

Пример управления дисплеем в параллельном режиме на ccsinfo.com.

Обсуждение проблемы инициализации на avrfreaks.net.

Успешное подключение дисплея с параллельной 4-битовой передачей данных описано на сайте tutorial.cytron.com.my.

12.01.13: —————————————–

Если верить сайту en.pic16.com, для инициализации дисплея необходимо дернуть ножку RESET вниз, потом вверх и выдать последовательность команд 0×30, 0×01, 0×06, 0x0c:
void lcd_init() { rst=0; //reset LCD delay(); rst=1; //LCD normal work. nop(); psb=1; //8 bit as parrallel.

send_i(0x30); //basic operation instruction send_i(0x01); //off display send_i(0x06); //set the cursor's moving direction.

send_i(0x0c); //on display,off cursor,off blink }
Много разных ссылок по вопросам работы с монохромным дисплеем 128×64 содержится на этой страничке

На сайте ccsinfo.com приведена библиотека для управления дисплеем по 8-битовой шине. Стоит попробовать ее, чтобы подтвердить/опровергнуть возможность работы с имеющимся дисплеем. Ну или библиотеку из песочницы Arduino.

Какие проблемы могут возникать при подключении этого дисплея в параллельном режиме и как их можно побороть, описано на сайте avr-praxis.de/forum.

А на mikrocontroller.net пользователь Peter делится своим опытом обуздания SPI-интерфейса.

Источник: http://mcu8.ru/wp-gull/mylinks/2013/01/07/podklyuchenie-graficheskogo-displeya-128h64/