1602 дисплей даташит. Подключение LCD к Ардуино плате

Что является неотъемлемой частью большого количества электронных девайсов? Конечно, средства индикации и графического вывода данных. Пользователю всегда удобнее и приятнее когда результат работы «умной коробочки» можно увидеть визуально. Поэтому сегодня мы подключим к STM32 дисплей для вывода текста и цифр. Героем наших экспериментов станет довольно-таки популярный дисплей от Winstar’а. Вот кстати в комментариях появилось важное уточнение, что методика в принципе одинакова для всех дисплеев на базе HD44780. Спасибо JekaKey за важное дополнение)

Для начала дисплей надо собственно подключить к контроллеру. Скачиваем даташит и ищем распиновку WH1602. Вот смотрите:

Как вы уже поняли, дисплей WH1602 имеет 16 выводов. Рассмотрим каждый в отдельности…

Пины Vss, Vdd и K нужно подключать к земле и к питанию, то есть прямо так, как указано в таблице, тут без сюрпризов и даже нечего обсуждать)

Вывод под номером 3 служит для регулировки контрастности – если подадим туда +5В, то не увидим абсолютно ничего, а если закоротим вывод на землю, то будем любоваться двумя рядами черных квадратов 😉 Естественно, это нас не устраивает, поэтому туда надо повесить потенциометр (резистор с переменным сопротивлением) для регулировки контрастности. Самая лучшая видимость символов обеспечивается напряжением 0.5-0.7 В на этом выводе дисплея.

Пин RS – это уже вывод, которым мы сами будем управлять при помощи микроконтроллера. Низкий уровень напряжения (0) на этом выводе означает, что сейчас последует команда, высокий уровень (1) – значит сейчас будут данные для записи в память дисплея.

Пин R/W – тут понятно, либо мы читаем данные (флаг занятости дисплея, например), в этом случае на этом выводе 1, либо записываем команду/данные в дисплей, тогда тут у нас 0.

DB7 – DB0 – шина данных, и этим все сказано)

Пин E – так называемый Enable signal. Нужен он вот для чего. Чтобы работать с дисплеем – записывать данные или подавать команду – нам надо выдать на этот вывод положительный импульс. То есть, процедура будет выглядеть следующим образом:

  1. На пины RS, R/W, DB7 – DB0 – нужные сигналы, соответствующие нашей команде.
  2. Подаем единицу на вывод E.
  3. Ждемс (по даташиту – не менее 150 нс)
  4. Подаем на вывод E низкий уровень (0).

На ножку A/Vee надо сунуть 4.2 В для питания подсветки дисплея.

Вот так вот происходит общение с дисплеем WH1602.

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

Тут описаны все команды и сигналы, которые должны быть на соответствующих выводах WH1602 для каждой конкретной команды. Вот хотим мы например, очистить дисплей, смотрим в таблицу, и вот она нужная команда! Clear Display!

Подаем на выводы RS, R/W, DB7, DB6, DB5, DB4, DB3, DB2, DB1 нули, а на ножку DB0 – единицу. Готово, что дальше? Верно, единицу на пин E, затем ожидаем некоторое время и снова опускаем E в ноль. Все, дисплей очищен 😉 Только перед выполнением следующей команды необходимо выдержать паузу, указанную в даташите для каждой команды. Более эффективным будет опрос флага занятости, как только он сбросился в 0 – можно работать дальше. Для чтения этого флага тоже есть специальная команда, так что с этим все понятно) Идем дальше…

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

Получаем в свое распоряжение 2 файла, MT_WH1602.c и MT_WH1602.h. Отрываем второй, тут нам надо произвести выбор выводов и используемого контроллера.

Дисплей у меня, кстати, подключен так:

RS – PC2
R/W – PB10
E – PB14
DB7 – PD2
DB6 – PC12
DB5 – PA8
DB4 – PA10
DB3 – PA15
DB2 – PD11
DB1 – PA3
DB0 – PA5

Открываем файл MT_WH1602.h:

#define PLATFORM (STM32F10x)

Далее выбираем выводы микроконтроллера, к которым у нас подключен дисплей. Только сначала зададим, какие порты у нас задействованы. Вот при моем подключении у меня используются GPIOA, GPIOB, GPIOC и GPIOD, пишем:

Аналогично для других ножек микроконтроллера.

С настройкой покончили, продолжаем) Для вызова команд, приведенных в начале статьи в файле MT_WH1602.c содержатся следующие функции (названы они по названию команд, так что тут, думаю, все понятно):

void MT_WH1602_ClearDisplay(void ) ; void MT_WH1602_ReturnHome(void ) ; void MT_WH1602_EntryModeSet (bool IDaddress, bool shift) ; void MT_WH1602_DisplayOnOff (bool Dbit, bool Cbit, bool Bbit) ; void MT_WH1602_CursorOrDisplayShift (bool SCbit, bool RLbit) ; void MT_WH1602_FunctionSet (bool DLbit, bool Nbit, bool Fbit) ; void MT_WH1602_SetCGRAMAddress (uint8_t address) ; void MT_WH1602_SetDDRAMAddress (uint8_t address) ; bool MT_WH1602_ReadBusy(void ) ; void MT_WH1602_WriteData(uint8_t data) ;

Для некоторых команд нам нужно передать в функцию параметры, вот, например:

void MT_WH1602_DisplayOnOff (bool Dbit, bool Cbit, bool Bbit) ;

Смотрим в таблицу команд:

Видим, что командой Display ON/OFF не только включать/выключать дисплей, но также активировать/деактивировать курсор и мигание курсора. В даташите эти биты команды обозначены как D,C и B, их то мы и передаем в качестве параметров в функцию. Если нам нужно включить дисплей и курсор, но отключить мигание курсора, вызываем команду следующим образом:

MT_WH1602_DisplayOnOff(1, 1, 0);

В общем, все просто 😉

Короче, создаем новый проект, добавляем библиотеку для работы с дисплеем WH1602, создаем пустой.c файл и начинаем заполнять его кодом:

// Подключаем файл библиотеки #include "MT_WH1602.h" /*******************************************************************/ int main(void ) { // Вызываем функцию инициализации, без этого никуда=) () ; // Теперь надо произвести начальную конфигурацию дисплея // Документация и интернет рекомендуют делать так;) MT_WH1602_FunctionSet(1 , 0 , 0 ) ; MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1 , 0 , 0 ) ; MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1 , 0 , 0 ) ; MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1 , 1 , 1 ) ; MT_WH1602_Delay(1000 ) ; MT_WH1602_DisplayOnOff(1 , 0 , 0 ) ; MT_WH1602_Delay(1000 ) ; MT_WH1602_ClearDisplay() ; MT_WH1602_Delay(2000 ) ; // Я тут значения задержки для примера взял первые пришедшие в голову) // Вообще нужно проверять флаг занятости дисплея // Давайте теперь выведем что-нибудь на дисплей, например название нашего сайта MT_WH1602_WriteData(0x6D ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x69 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x63 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x72 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x6F ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x74 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x65 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x63 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x68 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x6E ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x69 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x63 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x73 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x2E ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x72 ) ; MT_WH1602_Delay(100 ) ; MT_WH1602_WriteData(0x75 ) ; MT_WH1602_Delay(100 ) ; while (1 ) { __NOP() ; } } /*******************************************************************/

Готово, проверяем)


Как видите, все работает правильно)

Кстати я как то упустил из виду вопрос о том, что же писать в дисплей, чтобы вывести тот или иной символ. Вот табличка из даташита:

Так вот, чтобы определить какое значение записать в память дисплея, нужно для конкретного символа взять числа, написанные сверху и слева в этой таблице. Например, символ “А”. Смотрим – этому символу соответствует колонка 0100 (0х4) и строка 0001 (0х1). Получается, что для вывода символа “А” нужно записать в дисплей значение 0х41.

Вот теперь вроде все =) Разобрались мы с подключением и работой дисплея WH1602, так что до скорого!

P.S. Я при работе с библиотекой не тестировал функцию чтения флага занятости, так что, если вдруг что-то будет работать не так, как надо, пишите, будем разбираться)

Некоторое время лежал без дела вот такой дисплей.


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

Итак, начнём.
Первое что надо сделать - это найти распиновку, то есть какой контакт за что отвечает, второе - найти название контроллера, который управляет дисплеем, для этого скачиваем даташит на данный LCD и открываем его на первой странице.


Контакты считаются слева направо, первый отмечен красной стрелочкой. Напряжение питание равно 5 вольтам, управляющий контроллер S6A0069 или аналогичный, например, ks0066U .

Для чего мы искали название управляющего контроллера? Дело в том, что в даташите на дисплей есть временные задержки(timing diagram), описана система команд, но нет банальной инициализации, а без неё никуда.
Далее, открываем вторую страницу и видим таблицу, в которой написано какой контакт за, что отвечает.


DB7…DB0 – шина данных/адреса.

R/W - определяет что будем делать, считывать(R/W=1) или записывать(R/W=0)

R/S – определяет, что будем слать команду(RS=0) или данные(RS=1)

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

LED± – управление подсветкой.

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

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



Оказывается, таких инструкций целых две, для 8-битного и 4-битного режима. Что ж это за режимы такие? Данные режимы определяют по скольки проводкам будут передаваться данные: по четырём, либо по восьми. Давайте рассмотрим передачу по 4 проводам , в таком случае дисплей будет работать медленнее, но зато мы сэкономим 4 вывода микроконтроллера, да и реализация восьмибитного режима не намного отличается.

Схема подключения информационных выглядит следующим образом.


Контрастность можно регулировать включив потенциометр между выводами питания.

Хотелось бы обратить внимание, что во время инициализации R/S и R/W всегда равны нулю, то есть мы будем слать команды .

При инициализации можно настроить:

  • N - количество отображаемых строк
  • C - включить или выключить курсор
  • B - сделать курсор мигающим
  • I/D - увеличивать или уменьшать значение счётчика адреса
  • SH - двигать окошко дисплея
Два последние пункта рассмотрим подробнее.
На картинке ниже показано по какому адресу надо писать данные чтобы они отобразились в определённой позиции, например, если мы хотим вывести символ на первой позиции второй строки , то мы должны писать по адресу 0х40.


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

Кстати, память в которую мы пишем, называется DDRAM , все что мы запишем в эту память выведется на дисплей, ещё есть CGROM , в которой хранится таблица знакогенератора.


Эту таблицу нельзя изменить, но из неё можно брать уже готовые символы. Ещё один вид памяти это CGRAM , она то же представляет собой таблицу знакогенератора, но символы в этой таблице мы рисуем сами.


Теперь пару слов о движении экрана, дело в том что обычно на дисплее мы видим не всю DDRAM, а лишь определённую часть, как показано на картинке ниже.


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

С теорией закончили переходим к практике.
Картина общения с LCD дисплеем в 4-битном режиме выглядит следующим образом.


Данные шлются байтами, но так, как у нас 4-битный режим, то для того чтобы отправить байт надо сделать 2 посылки, старшим битом вперёд. На картинке первая посылка обозначена D7(старшая тетрада), вторая D3(младшая тетрада). Перед следующей посылкой мы должны проверить флаг занятости и если он не установлен снова можно слать, если установлен ждём, пока контроллер, управляющий LCD закончит свои дела.

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


Для отправки надо по 8-битной шине:
  • R/W установить в 0
  • выдаём код команды/данные в шину
  • задержка 2us
  • опускаем строб Е

Операция чтения реализуется аналогично:

  • убедиться, что управляющий контроллер свободен
  • R/W установить в 1
  • поднимаем строб E(в этот момент LCD выдаст данные в шину)
  • задержка 2us
  • читаем то что выдал LCD
  • опускаем строб Е
Откуда взялась задержка 2us?

Выше таймингов есть таблица в которой написано чему равны задержки изображённые на графике, так вот длительность стробирующего импульса - tw должна быть равна 230nS или 450nS в зависимости от напряжения питания, мы взяли чуть с запасом. Почему мы учли только эту задержку? Потому что значение остальных задержек очень мало.

Для отправки по 4-битной шине:

  • убедиться, что управляющий контроллер свободен
  • установить RS в 0(команда) или 1(данные), в зависимости оттого что будем слать
  • R/W установить в 0
  • поднимаем строб E(устанавливаем в 1)
  • выдаём старшую тетраду в шину
  • задержка 2us
  • опускаем строб Е
  • задержка 1us
  • поднимаем строб E(устанавливаем в 1)
  • выдаём младшую тетраду в шину
  • задержка 2us
  • опускаем строб Е

Для чтения по 4-битной шине:

  • убедиться, что управляющий контроллер свободен
  • порт данных на вход с подтяжкой
  • установить RS в 0(команда) или 1(данные), в зависимости оттого что будем читать
  • R/W установить в 1
  • поднимаем строб E(устанавливаем в 1)
  • задержка 2us
  • читаем старшую тетраду
  • опускаем строб Е
  • задержка 1us
  • поднимаем строб E(устанавливаем в 1)
  • задержка 2us
  • читаем младшую тетраду
  • опускаем строб Е

Поднятие строба и вывод команды/данных в шину, можно поменять местами. Теперь не составит труда инициализировать дисплей. Для упрощения инициализации, мы заменим чтение флага занятости задержкой, а работу с флагом рассмотрим позже.
Надо отметить, что при инициализации в 4-битном режиме используются 4-битные команды, а после инициализации 8-битная система команд, поэтому для инициализации мы реализуем отдельную функцию отправки команд void Write_Init_Command(uint8_t data) .
//Код инициализации для Atmega16 #define F_CPU 8000000UL #define LCD_PORT PORTA #define LCD_DDR DDRA #define LCD_PIN PINA #define DATA_BUS 0XF0 #define RS 0 #define RW 1 #define E 2 #include #include void Write_Init_Command(uint8_t data) { //ножки по которым передаются команды/данные на выход LCD_DDR |= DATA_BUS; //будем слать команду LCD_PORT &= ~(1<Весело мигающий курсор, свидетельствует о том, что инициализация прошла успешно. В

LCD дисплеи от компании Winstar уже на протяжении нескольких лет являются неотъемлемой частью современной электронной продукции, и не только на российском рынке. Они дешевы, очень распространены (не видел магазинов, где их не было бы), их разнообразие предоставляет разработчику выбирать подходящий в зависимости от эксплуатационных условий. Их различие заключается в диапазонах рабочих температур, количеством строк для отображения информации, количеством знакомест в строке, стандартными из которых являются значения 8, 12, 16, 20, 24 и 40 символов на одну строку, так же различаются размерами символа, его разрешением, размерами самого дисплея и т.д. Winstar выпускает не только буквенно-цифровые знакосинтезирующие LCD-модули, но и графические. Те, в свою очередь, тоже имеют различные параметры, что предоставляет пользователю возможность выбирать подходящий исходя из поставленной задачи.

Многие начинающие радиолюбители, только-только начавшие осваивать цифровую технику, микроконтроллеры, рано или поздно столкнутся с проблемой, связанной с подключением и управлением данного дисплея. Немного упростив ситуацию с даташитом на дисплей WH1602B, я старался описать процесс подключения и управления модулем максимально просто для понимания.

Стандартно дисплей WH1602B выглядит так:

16 выводных линий, из которых 11 – линии управления, расположены в ряд с шагом 2,54мм, что позволяет разработчику напрямую подпаять шлейф или поставить разъем, и отвести шлейф к плате управления, в зависимости от конструкции конечного устройства.

Далеко не редким является дисплей с боковым расположением контактов.

В зависимости от конструктива радиоэлектронного устройства разработчик может использовать любой тип расположения выводов – различия между программными обеспечениями совершенно нет.
Модули могут комплектоваться задней подсветкой экрана, причем тип источника подсветки у разных модулей различен. В некоторых дисплеях используется электролюминесцентная подсветка, обеспечивающая равномерное распределение свечения по всей отображаемой поверхности экрана. Главным недостатком дисплея с таким типом подсветки является, пожалуй, одно: для питания такого дисплея нужен переменный ток высокого напряжения. У светодиодных подсветок недостатков практически нет, модули с применением светодиодной подсветки могут использоваться в приложениях, работающих при широких диапазонах температур. Производитель дает широкий выбор в плане цвета подсветки – поскольку светодиодные матрицы можно установить практически любого цвета.

Существенным недостатком дисплеев WH1602B является ток потребления, поэтому применять данный тип дисплеев в устройствах с автономным питанием совершенно невыгодно.

Дисплеи линейки WH построены на базе специализированного контроллера LCD-модулей HD44780, который как раз и разрабатывался для управления знакосинтезирующими ЖК-панелями.

С небольшим описанием, пожалуй, стоит закончить, и приступить к практической части. Нумерация выводов дисплея, если смотреть на него сверху (т.е. как мы смотрим на него при чтении информации), идет начиная с самого крайнего левого вывода. Это вывод 1.

Подключение 1602:

Итак распиновка 1602 :
1) GND – общий провод
2) Vcc – напряжение питания +5В
3) V0 – контрастность
4) RS – линия выбора регистра
5) RW – линия выбора направления передачи данных (чтение или запись)
6) E – линия синхронизации
7) DB0 – 14) DB7 – линии шины данных
15) A – анод подсветки (подключаем сюда +5В через резистор 100Ом)
16) К – катод подсветки (подключаем к общему проводу)

Дисплей может работать в 2 режимах: в режиме 8-битной передачи данных, когда данные передаются группами по 8 бит (при этом обеспечивается максимальная скорость взаимодействия с дисплеем), и в режиме 4-битной передачи, когда 8-битные данные разбиваются на две группы по четыре разряда и последовательно передаются по четырем старшим линиям данных DB4-DB7.

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

Мы рассмотрим процесс инициализации дисплея WH1602B в 8-битном режиме с использованием управляющей платы, основанной на микроконтроллере Attiny2313.

Итак, какие действия необходимо выполнить для надежного процесса инициализации :
1) Включить питание дисплея
2) Выдержать паузу 20мс
3) Выдать команду 00110000 при RS=0 RW=0
4) Выдержать паузу не менее 40мкс
5) Выдать команду 00110000 при RS=0 RW=0
6) Выдержать паузу не менее 40мкс
7) Выдать команду 00110000 при RS=0 RW=0
8) Выдержать паузу не менее 40мкс
9) Выдать команду 00111000 при RS=0 RW=0
10) Выдержать паузу не менее 40мкс
11) Выдать команду 00001000 при RS=0 RW=0
12) Выдержать паузу не менее 40мкс
13) Выдать команду 00000001 при RS=0 RW=0
14) Выдержать паузу не менее 1,5мс
15) Выдать команду 00000110 при RS=0 RW=0.

Поясню: RS – как отмечалось выше – линия выбора регистра (0 – адресуется регистр команд, в который мы записываем команды отключения дисплея, сдвига строки, установление курсора и т.д.; 1 – адресуется внутренняя память, куда будет записываться байт и отображаться на дисплее).

RW – линия выбора направления передачи данных (0 – запись в дисплей, 1 – чтение данных из дисплея).
После выдачи данных на линию данных DB0-DB7 и установки значений на линиях RS, RW, необходимо эти данные защелкнуть – для этого нужно установить линию E в 1, и, затем, снова сбросить в исходное положение – в 0.

Подключаем PD0 микроконтроллера к линии RS LCD, вывод PD1 микроконтроллера к RW дисплея, ну а PD2 – соответственно к линии Е дисплея, а линии шины данных DB0-DB7 к соответствующим линиям порта B микроконтроллера. Сам дисплей подключаем согласно схеме вверху.

Теперь дело за программной частью:

Include "tn2313def.inc" ; Attiny2313, 1 MHz clock .cseg .org 0 rjmp reset ;******************************************************************** ;Стандартный переход к инициализированной части программы reset: ldi r16, low (RAMEND) ; Инициализация стека МК out SPL, r16 rcall lcd_init ; Инициализация дисплея;Здесь мы инициализировали стек микроконтроллера и перешли к инициализации LCD-модуля;******************************************************************** lcd_init: ldi r16, 0b10000000 ; сбрасываем все подтягивающие резисторы out MCUCR, r16 ldi r16, 0b11111111 ; Настройка порта B out ddrb, r16 ldi r16, 0b00000111 ; Настройка порта D out ddrd, r16 ;Настраиваем линии портов ввода/вывода: сбрасываем подтягивающие резисторы и определяем;PB0-PB7, PD0-PD2 как линии вывода данных;******************************************************************** ;Исходя из вышеуказанной процедуры инициализации выполняем операции: ldi r16, 0b00000000 ; Адресация IR ldi r17, 0b00110000 ; Установка разрядности Data line rcall delay_20000mks ; Пауза перед инициализацией lcd rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ldi r17, 0b00111000 ; Установка параметров lcd rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ldi r17, 0b00001000 ; Выключение дисплея rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ldi r17, 0b00000001 ; Очистка дисплея rcall write_lcd ; Запись данных в lcd rcall delay_1500mks ; Задержка перед выполнением операций с lcd ldi r17, 0b00000110 ; Установка режима ввода данных rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ret ; Выход из подпрограммы;******************************************************************** delay_20000mks: ldi r18, 0b10110010 ; Ввод переменной задержки ldi r19, 0b00000101 ; Настройка предделителя rjmp init_delay delay_1500mks: ldi r18, 0b11111010 ; Ввод переменной задержки ldi r19, 0b00000101 ; Настройка предделителя rjmp init_delay delay_40mks: ldi r18, 0b11011000 ; Ввод переменной задержки ldi r19, 0b00000010 ; Настройка предделителя init_delay: out TCNT0, r18 ; Инициализация TCNT0 out TCCR0B, r19 ; Старт T0 test_TIFR: in r18, TIFR ; Чтение TIFR sbrs r18, 1 ; Переход, если "Переполнение T0" rjmp test_TIFR ; Бесконечная проверка TOV0 ldi r20, 0b00000000 ; Остановка T0 out TCCR0B, r20 ldi r20, 0b00000010 ; Загрузка TOV0>>0 out TIFR, r21 ret ; Выход из подпрограммы;******************************************************************** write_lcd: out portd, r16 ; Установка значения линии RS out portb, r17 ; Вывод байта данных DB0-DB7 nop ; Защита от шумов на линии стробирования sbi portd, 2 ; E>>1 nop ; Защита от шумов на линии стробирования cbi portd, 2 ; E>>0 nop ; Защита от шумов на линии стробирования ret ; Выход из подпрограммы;******************************************************************** user_write_IR: ldi r16, 0b00000000 ; Адресация IR rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ret ; Выход из подпрограммы;******************************************************************** user_write_DR: ldi r16, 0b00000001 ; Адресация DR rcall write_lcd ; Запись данных в lcd rcall delay_40mks ; Задержка перед выполнением операций с lcd ret ; Выход из подпрограммы;******************************************************************** lcd_clear: ldi r16, 0b00000000 ; Адресация IR ldi r17, 0b00000001 ; Очистка дисплея rcall write_lcd ; Запись данных в lcd rcall delay_1500mks ; Задержка перед выполнением операций с lcd ret ; Выход из подпрограммы;********************************************************************

Как пользоваться данным кодом. Для занесения символа на экран необходимо записать байт, соответствующий коду этого символа, в регистр R17. В регистр 17 заносим 0х1 – если хотим записать символ на экран, или сбрасываем в 0х0, если хотим записать какую-то команду в регистр команд LCD дисплея.

Мной были предусмотрены подпрограммы, которые вызывает пользователь:
user_write_IR – запись команды в регистр команды LCD;
user_write_DR – запись данных для отображения на LCD;
lcd_clear – подпрограмма/команда, вызов которой осуществляет очистку дисплея.

Как работать с вызовом подпрограмм:

Ldi r17, 0x24; Символ с кодом 0x24 rcall user_write_DR; запись символа на отображение ldi r17, 0x2; команда 0х2 rcall user_write_IR; записываем в регистр.

Отмечу, что при использовании подпрограммы lcd_clear предварительная запись в R17 не требуется.
Где писать свой код? Вот здесь:

Reset: ldi r16, low (RAMEND) ; Инициализация стека МК out SPL, r16 rcall lcd_init ; Инициализация дисплея;ВАШ КОД!!! Например: Ldi r17, 0xC; Включаем изображение ldi r17, 0x24; Символ с кодом 0x24 rcall user_write_DR; запись символа на отображение

Добавлю, что в последнее время появились данные модули с платой последовательного преобразователя, позволяющие подключать LCD дисплеи 1602 по 4-х проводной схеме и работающими по I 2 C-интерфейсу. Т.о. немного упрощается подключение и экономятся выводы контроллера. Модуль можно приобрести отдельно и подключить к уже имеющемуся LCD 1602.

Скачать исходники и прошивку вы можете ниже

Приехал Arduino Nano, приехал кит, в котором макетка (бредборд), и LCD-дисплей. На дисплее на плате написано - 1602А, ниже - QAPASS. Начал ваять первое устройство, и конечно же, захотелось выводить информацию на дисплей, а не мигать светодиодами.

Гугл помог, рассказал, что это символьный дисплей; если не извращаться, то доступны скорее всего символы ASCII - цифры, латиница, что-то из базовых символов.

Запустить дисплей помогли следующие материалы: Driving a character type LCD from a PC printer port ; How to connect Arduino with a character LCD ; Pwm Servo Driver Motor Control PDF .

Дисплей достаточно распространенный, и для него уже понапридумывали шилдов - есть варианты с SPI вроде, и/или с I2C, и интернет полон рецептами для этих случаев. Но у меня был в наличии только оригинальный дисплей 16x2, и ардуинка, к которой хотелось его прицепить.

У дисплея есть режим работы и передачи данных полубайтами, по 4 бита, при этом младшие разряды шины не используются. Подключение только половины шины данных много где описано, и я не стал разбираться, как подключить дисплей и работать с ним по 8ми линиям. Меня вполне устроило, что и так работает.

Хорошее описание дисплеев данного типа я нашел тут - http://greathard.ucoz.com/44780_rus.pdf . А тут (http://arduino.ru/forum/programmirovanie/lcd-i2c-partizanit#comment-40748) - пример задания знакогенератора.

Подключение

У меня дисплей поставлялся с нераспаянными контактами. С начала хотел припаять шлейф, обрезал 16 проводов с дюпонами, зачистил. А потом покопался в ките, и нашел гребенку дюпонов для пайки на плату. Оттуда и отломал 16 контактов и припаял их.
Выглядел (до пайки контактов) мой дисплей примерно так:

Сперва я подключил контакт 15 (A) на +5В, 16 (K) на землю, и убедился, что подсветка работает. Вообще, правильно подключать катод на землю через резистор 220Ом, что я потом и сделал.

Затем подключил землю (1) и питание (2). Arduino может питаться от USB, от стабилизированного напряжения 5В и от нестабилизированного 6-12В, автоматически выбирается наибольшее напряжение. Сейчас ардуинка запитана от USB, и я думал, где там вытащить 5 Вольт. Оказалось, что 5В есть на контакте ардуины, куда подключаются внешние стабилизированные 5В. Вернее, там оказалось 4.7В, но мне хватило.

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

Затем подключаем потенциометр контраста (пин 3 V0). Один из крайних выводов потенциометра бросаем на землю, второй - на +5В, средний - на пин 3 дисплея. Рекомендуется потенциометр 10К. У меня был 50К из кита, сначала я использовал его. Регулировка была только на одном краю, весьма тонко приходилось ловить нужный контраст. Затем в другом ките нашел аналогичный на 5К, и поставил его. Настройка растянулась от одного края до половины оборота. Видимо, можно и еще меньше взять потенциометр. 10К наверно рекомендуют, чтобы схема поменьше потребляла. Да, пришлось немного попаять, припаял к выводам потенциометров проводки с дюпонами.

Тестовый скетч

Тестовый скетч берем в примерах от Ардуино студии - "C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\ex amples\HelloWorld\HelloWorld.ino", только нужно поменять контакты на наши - LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

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

// include the library code: #include // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 6, 5, 4, 3, 2); void setup() { // set up the LCD"s number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("hello, world!"); } void loop() { // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(0, 1); // print the number of seconds since reset: lcd.print(millis() / 1000); }

Получается что-то вроде этого:

Кстати, дисплей, который попал ко мне в руки, без подсветки не работает. В смысле, работает, но практически ничего не видно.

Контакты дисплея 1602A

# контакта Наименование Как подключать
1 VSS GND
2 VDD +5V
3 V0 Контраст - на средний вывод потенциометра
4 RS (Register select) D7 Arduino
5 R/W (Read or write) GND
6 E (Enable signal) D6 Arduino
7-14 D0-D7 D0-D3 - не подключены; D4-D7 - подключены к контактам D5-D2 Ардуино
15 A Анод подсветки, подключается к +5В
16 K Катод подсветки, подключается к земле через резистор 220Ом

Символьный дисплей LCD1602 с голубой подсветкой - жидкокристаллический дисплей (Liquid Crystal Display) экран которого способен отображать одновременно до 32 символов (16 столбцов, 02 строки). Подключение к осуществляется по синхронному 8-битному параллельному интерфейсу. Примеры работы с символьными дисплеями описаны в разделе .

Характеристики

  • Тип выводимой информации: символьный.
  • Язык в ПЗУ дисплея: латиница, японский.
  • Возможность загрузки собственных символов: есть.
  • Формат выводимой информации: 16×02 символов;
  • Тип дисплея: LCD.
  • Технология дисплея: STN.
  • Угол обзора: 180°.
  • Тип подсветки: LED.
  • Цвет подсветки: синий.
  • Цвет символов: белый.
  • Контроллер: HD44780.
  • Интерфейс: синхронный, 8-битный, параллельный.
  • Напряжение питания 5 В.
  • Рабочая температура: -20 ... +70 °С.
  • Температура хранения -30 ... +80 °С.
  • Габариты: 80x36 мм.

Подключение

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

Шина данных дисплея состоит из 8 линий (D0-D7), но если подключить только старшие 4 линии (D4-D7), как это показано на рисунке, это не снижает скорость работы дисплея. Для удобства мы подключили выводы D4-D7 дисплея к одноимённым выводам D4-D7 . Вы можете подключать выводы D0-D7, E и RS дисплея, к любым выводам , указав их в скетче при объявлении объекта библиотеки.

№: Дисплей: Arduino: Назначение:
16 K (LED-) GND Катод (минус) LED (светодиодной) подсветки.
15 A (LED+) 5V Анод (плюс) LED (светодиодной) подсветки.
14...7 D7 ...D0 (DB7...DB0) Любые Шина данных (Data Bus) состоящая из 8 линий. В приведённой схеме используются только старшие 4 линии, т.к. это не влияет на скорость работы дисплея.
6 E Любой Сигнал разрешения (Enable).
5 RW GND Выбор направления (Read / Write) передачи данных: «1» - чтение из дисплея / «0» - запись в дисплей. Вывод подключен к GND, т.к. данные только записываются в дисплей.
4 RS Любой Выбор регистра (Register Selection) получателя информации: «1» - регистр данных / «0» - регистр инструкций.
3 V0 (VEE)
Установка контрастности дисплея: 0 ... +5 В постоянного тока.
2 VDD (VCC) 5V Питание логики дисплея: +5 В постоянного тока.
1 VSS (GND) GND Общий вывод питания (земля).

Питание

Напряжение питания логики дисплея 5 В постоянного тока подаётся на выводы VDD (VCC) и VSS (GND) дисплея.

Напряжение питания подсветки 5 В постоянного тока подаётся на выводы A (Анод - Anode) и K (Катод - Cathode) дисплея.

Потенциал для установки контрастности 0 ... +5 В постоянного тока подаётся на вывод V0 дисплея.

Подробнее о дисплее

Символьный дисплей построен на базе ЖК дисплея типа STN (Super Twisted Nematic) под управлением контроллера HD44780 и имеет синхронный параллельный 8-битный интерфейс. Дисплей оснащён светодиодной подсветкой синего цвета и способен одновременно отображать до 32 символов (16 столбцов, 02 строки) от чего и произошло название дисплея: LCD1602. Контроллер HD44780 имеет ПЗУ в которой хранятся цифры, символы латиницы и некоторые иероглифы японского языка, для их отображения на дисплее. Отсутствующие символы, в т.ч. и символы кириллицы, можно загружать в память ОЗУ контроллера, для вывода на дисплей надписей на Русском языке или нестандартных символов (например «смайликов»).

Если к выводам дисплея подключить то можно преобразовать его синхронный 8-битный параллельный интерфейс в шину I2C (превратив дисплей из LCD1602 в