Подключение и работа с дисплеем WH1602. LCD WH1602B компании Winstar Lcd 1602 подключение к ардуино uno

При сборке своего металлоискателя у меня на руках оказался LCD дисплей 1602, построенный на контроллера HD44780. Решил не упустить возможность и подключить его к своему китайскому аналогу Arduino UNO.

Вот такой дисплей 1602 будем сегодня подключать к Arduino.

Цифры «1602» говорят о том, что дисплей состоит из 2-х строк, по 16 символов. Это довольно распространённый экран, с применением которого народ конструирует часы, тестеры и прочие гаджеты. Дисплей бывает с зелёной и голубой подсветкой.

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

Подключать дисплей 1602 к Arduino будем через 4-битный вариант параллельного интерфейса. Существует вариант и 8-битного интерфейса, но при нём задействуется больше проводов, а выигрыша в этом мы не увидим.

Кроме дисплея и Arduino, нам понадобятся провода и переменный резистор на 10кОм. Резистор подойдёт любой марки, лишь бы был необходимого номинала.

Питание на дисплей подаётся через 1-й (VSS) и 2-й (VDD) выводы. К выводам 15 (А) и 16 (K) - подаётся питание на подсветку дисплея. Поскольку для питания и подсветки используется одно напряжение +5В, запитаем их от пинов Arduino «5V» и «GND» . Главное не перепутать полярность, иначе можно спалить электронику дисплея.

3-й вывод (V0) подключаем к ножке переменного резистора, им будем управлять контрастностью дисплея. Резистор можно не использовать, а вывод «V0» подключить к GND . В таком случае контрастность будет максимальной и не будет возможности её плавной регулировки.

5-й вывод (RW) используется для чтения с дисплея либо для записи в него. Поскольку мы будем только писать в дисплей, соединим этот вывод с землёй (GND) .

Выводы: 4-й (RS) , 6-й (E) , 11-й (D4) , 12-й (D5) , 13-й (D6) , 14-й (D7) подключаем к цифровым пинам Arduino. Не обязательно использовать пины те же что и у меня, можно подключить к любым цифровым, главное затем правильно их выставить в скетче.

Моя подключённая Ардуина, осталось соединить её с компьютером через USB и залить скетч.

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

В Arduino IDE выбираем «Файл» - «Образцы» - «LiquidCrystal» - «HelloWorld» .

Давайте посмотрим на код скетча.

В строке «LiquidCrystal lcd» , в скобках, выставлены цифровые пины, которые задействованы на Arduino. Пины выставляются в такой последовательности: RS, E, DB4, DB5, DB6, DB7 . Если вы задействовали другие цифровые пины, при подключении дисплея, впишите их в нужной последовательности в скобках.

В строке «lcd.print("hello, world!");» выводится приветствие на дисплей, по-умолчанию это надпись «hello, world!» , её можно поменять на любую свою, пишем на латинице.

Загружаем скетч в Arduino и вот результат. Вместо «hello, world!» я вписал свой сайт. Строкой ниже, таймер производит отсчёт времени.

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


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

Что является неотъемлемой частью большого количества электронных девайсов? Конечно, средства индикации и графического вывода данных. Пользователю всегда удобнее и приятнее когда результат работы «умной коробочки» можно увидеть визуально. Поэтому сегодня мы подключим к 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 дисплеем фирмы Winstar на контроллере HD44780. Следует сразу отметить, что аналогов данного дисплея великое множество и прошивка будет работать со всеми ними. Также была проверена работа данного кода с графическими и символьными OLED дисплеями.

Начнем, как и обычно, с постановки задачи. Необходимо подключить дисплей по 4х-битной шине к отладочной плате STM32F4 и вывести на него любой текст.

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

Схема подключения показана на рисунке ниже.

Следует отметить один очень важный момент: 1 вывод - "+5В" и 2 - "GND", на многих дисплеях поменяны местами, поэтому прежде чем подключить дисплей, прочитайте даташит. Неправильное подключение может привести к выходу дисплея из строя.

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

Теперь перейдем к прошивке. Выполним ее в виде отдельной библиотеки, чтобы в дальнейшем упростить подключение дисплея в других проектах - добавляете файл в проект и используете. Библиотеку назовем lcd.h. В библиотеке содержится следующий код:

//---Переопределяем порты для подключения дисплея, для удобства---// #define LCM_OUT GPIOB->ODR #define LCM_PIN_RS GPIO_Pin_0 // PB0 #define LCM_PIN_EN GPIO_Pin_1 // PB1 #define LCM_PIN_D7 GPIO_Pin_7 // PB7 #define LCM_PIN_D6 GPIO_Pin_6 // PB6 #define LCM_PIN_D5 GPIO_Pin_5 // PB5 #define LCM_PIN_D4 GPIO_Pin_4 // PB4 #define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4)) GPIO_InitTypeDef GPIO_InitStructure; //---Функция задержки---// void delay(int a) { int i = 0; int f = 0; while(f < a) { while(i<60) {i++;} f++; } } //---Нужная функция для работы с дисплеем, по сути "дергаем ножкой" EN---// void PulseLCD() { LCM_OUT &= ~LCM_PIN_EN; delay(220); LCM_OUT |= LCM_PIN_EN; delay(220); LCM_OUT &= (~LCM_PIN_EN); delay(220); } //---Отсылка байта в дисплей---// void SendByte(char ByteToSend, int IsData) { LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= (ByteToSend & 0xF0); if (IsData == 1) LCM_OUT |= LCM_PIN_RS; else LCM_OUT &= ~LCM_PIN_RS; PulseLCD(); LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= ((ByteToSend & 0x0F) << 4); if (IsData == 1) LCM_OUT |= LCM_PIN_RS; else LCM_OUT &= ~LCM_PIN_RS; PulseLCD(); } //---Установка позиции курсора---// void Cursor(char Row, char Col) { char address; if (Row == 0) address = 0; else address = 0x40; address |= Col; SendByte(0x80 | address, 0); } //---Очистка дисплея---// void ClearLCDScreen() { SendByte(0x01, 0); SendByte(0x02, 0); } //---Инициализация дисплея---// void InitializeLCD(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); LCM_OUT &= ~(LCM_PIN_MASK); delay(32000); delay(32000); delay(32000); LCM_OUT &= ~LCM_PIN_RS; LCM_OUT &= ~LCM_PIN_EN; LCM_OUT = 0x20; PulseLCD(); SendByte(0x28, 0); SendByte(0x0E, 0); SendByte(0x06, 0); } //---Печать строки---// void PrintStr(char *Text) { char *c; c = Text; while ((c != 0) && (*c != 0)) { SendByte(*c, 1); c++; } }

Пройдемся по основным функциям библиотеки:

InitializeLCD() - инициализация дисплея, необходимо выполнять при старте программы.

InitializeLCD(); //Инициализация дисплея

ClearLCDScree n ( ) - очистка памяти дисплея.

ClearLCDScreen(); //Очистка памяти дисплея

Curso r (№ строки, № столбца) - установка позиции курсора, отсчет начинается с нулевой строки и нулевого столбца.

Cursor(0,2); //Установка курсора, 0-ая строка, 2-ой столбец

PrintStr(текст ) - написание строки на дисплее.

PrintStr("сайт");

SendByte( байт, режим) - если коротко, то эта функция отправляет байт в дисплей. Если параметр «режим» равен «1», то на дисплее появится символ, а если «0» - то байт будет принят дисплеем в режиме настройки. Например очистка дисплея, установка курсора или выбор типа курсора.

SendByte(0b00001100, 0); //Курсор выключен

С библиотекой закончили. Теперь пора запускать дисплей. Для этого в основном файле main.c надо написать следующий код:

#include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "lcd.h" int main(void) { InitializeLCD(); //Инициализация дисплея ClearLCDScreen(); //Очистка дисплея от мусора Cursor(0,2); //Установка курсора PrintStr("Specially for"); //Написание текста Cursor(1,4); PrintStr("сайт"); while(1) { } }

Д умаю по комментариям все понятно. Теперь остается скомпилировать код и прошить плату. Делаем рестарт и наслаждаемся написанным.

Приехал 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Ом