Работа с символьным ЖК индикатором wh1602 на AVR

Учебный курс. Подключение lcd к микроконтроллеру. Получение первых результатов.

29/10/2009 – 21:00    За все время увлечения электроникой мне довелось пользоваться ЖКД  от нескольких производителей – DataVision, WINSTAR, Uniworld Technology Corp. Они отличались типом контроллера, количеством выводов и длинною строк, но при этом все имели одинаковую схему подключения, систему команд и обслуживались одной и той же программой со стороны микроконтроллера. Поэтому, хотя речь сейчас пойдет о дисплее WH0802A фирмы WINSTAR,  все ниже сказанное применимо к символьным ЖК-дисплеям и других фирм.    WH0802A – двухстрочный символьный дисплей на 8 знакомест со встроенным управляющим контроллером KS0066.    Разбираем назначение выводов дисплея. image image     Это типовая схема включения символьных LCD. Схему управления подсветкой дисплея мы задействовать не будем, но я ее на всякий случай нарисовал. 

//подключаем символьный ЖК-дисплей к AVR

#include

//порт к которому подключена шина данных ЖКД

#define

PORT_DATA PORTD

#define

PIN_DATA  PIND

#define

DDRX_DATA DDRD

//порт к которому подключены управляющие выводы

#define

PORT_SIG PORTB

#define

PIN_SIG  PINB

#define

DDRX_SIG DDRB

#define

RS 5

#define

RW 6

#define

EN 7

//макросы для работы с битами

#define

ClearBit(reg, bit)       reg &= (~(1<<(bit))) <p>#define SetBit(reg, bit)          reg |= (1<<(bit))    <p>#define F_CPU 8000000

#define

_delay_us(us)    

__delay_cycles

((F_CPU / 1000000) * (us));

#define

_delay_ms(ms)     __delay_cycles((F_CPU / 1000) * (ms));

//функция записи команды

void

LcdWriteCom(

unsigned char

data) {   ClearBit(PORT_SIG, RS);   

// устанавливаем RS в 0

  PORT_DATA = data;       

// выводим данные на шину  

    SetBit(PORT_SIG, EN);   

// устанавливаем Е в 1

  _delay_us

(2);   ClearBit(PORT_SIG, EN);   

// устанавливаем Е в 0

  _delay_us(40);

//функция записи данных

void

LcdWriteData(

unsigned char

data) {   SetBit(PORT_SIG, RS);    

//устанавливаем RS в 1

  PORT_DATA = data;       

//выводим данные на шину     

  SetBit(PORT_SIG, EN);   

 //устанавливаем Е в 1

  _delay_us

(2);   ClearBit(PORT_SIG, EN);   

// устанавливаем Е в 0

int

main(

void

) {

  while

(1);

  return

0; }

Здесь нет сложных мест, все должно быть понятно. Идем дальше.

   Любой ЖК-дисплей перед использованием нужно инициализировать. Процесс инициализации обычно описан в datasheet`е на контроллер дисплея. Но даже если там и нет информации, последовательность, скорее всего, будет такая. 1. Подаем питание 2. Ждем >40 мс 3. Подаем команду Function set DL – бит установки разрядности шины 0 – 4 разрядная шина, 1 – 8 разрядная шина N – бит установки количества строк дисплея 0 – однострочный режим, 1 – двухстрочный режим F – бит установки шрифта 0 – формат 5*8, 1 – формат 5*11 * – не важно что будет в этих битах 4. Подаем команду Display ON/OFF D – бит включения/выключения дисплея 0 – дисплей выключен, 1 – дисплей включен C – бит включения/выключения курсора 0 – курсор выключен, 1 – курсор включен B – бит включения мерцания 0 – мерцающий курсор включен, 1 – мерцающий курсор выключен 5. Подаем команду Clear Display 7. Подаем команду Entry Mode Set I/D – порядок увеличения/уменьшения адреса DDRAM(ОЗУ данных дисплея) 0 – курсор движется влево, адрес уменьшается на 1, 1 – курсор движется вправо, адрес увеличивается на 1 SH – порядок сдвига всего дисплея 0 – сдвига нет, 1 – сдвиг происходит согласно сигналу I/D – если он 0 – дисплей сдвигается вправо, 1 – дисплей сдвигается влево Для нашего примера функция инициализации будет выглядеть так

//функция инициализации

void InitLcd(void) {  

//настраиваем порты ввода/вывода

  DDRX_DATA = 0xff;   PORT_DATA = 0xff;      DDRX_SIG = 0xff;   PORT_SIG |= (1<<RW>

//0b00111000 – 8 разрядная шина, 2 строки

  LcdWriteCom(0x0f); 

//0b00001111 – дисплей, курсор, мерцание включены

  LcdWriteCom(0x01); 

//0b00000001 – очистка дисплея

  _delay_ms(2);   LcdWriteCom(0x06); 

//0b00000110 – курсор движется вправо, сдвига нет

}    Теперь у нас есть необходимый минимум, чтобы начать работу с дисплеем. Выведем на него слово “Test.”

//собственно наша программа

int

main( void ) {   InitLcd();   LcdWriteData(‘T’);   LcdWriteData(‘e’);   LcdWriteData(‘s’);   LcdWriteData(‘t’);   LcdWriteData(‘.’);   while(1);   return 0; }    Первые результаты мы получили.  Доводить программу до ума будем в следующих статьях. Описание на дисплей WH0802A Описание на контроллер KS0066 Проект дляCodeVision

У вас недостаточно прав для комментирования.

back to top

MicroTechnics

Поделиться!

© 2013-2021 MicroTechnics.ru

Дата: 13 Июля 2015. Автор: Алексей

Заполучил я тут от хорошего магазина Чип Резистор очередной девайс для изучения и применения в полезных устройствах. Сей девайс оказался заточен для управления ЖК дисплеем под управлением контроллера HD44780, в 4-х битном режиме. Для этой цели на плате установлена микросхема PCF8574, которая является преобразователем шины I2C в параллельный 8 битный порт. Плата разведена таким образом, чтобы ее можно было сразу скрестить с ЖК дисплеем. На вход подается питание и линии I2C. На плате сразу установлены подтягивающие резисторы на линиях SCL и SDA, потенциометр для регулировки контрастности и питание самого дисплея. Джампер справа включает/отключает подсветку. Далее вооружившись тестером была составлена следующая табличка.

Выводы LCD Выводы модуля
RS P0
R/W P1
E P2
D4 P4
D5 P5
D6 P6
D7 P7

После изучения модуля было выявлено что P3 управляет подсветкой. Если джампер установлен, то 1 включает подсветку, а 0 выключает. При снятом джампере подсветка всегда выключена. Далее было принято решение дополнить библиотеку axlib функциями для работы с шиной I2C(программная реализация) и функциями для управления микросхемой PCF8574. В двух словах как работает модуль. Для того чтобы вывести параллельно байт, для этого нужно послать в шину I2C адрес микросхемы (по умолчанию он равен 0x4E. Так же можно менять адрес методом впаивания перемычек на плате и меняя значение трех младших разрядов адреса), затем после получения ACK посылается байт данных. После того как микросхема отвечает ACK, байт появляется на параллельном порту микросхемы. Для управления ЖК дисплеем я взял функции из библиотеки axlib и немного переделал их для работы с шиной I2C.

   #include     #include   #include   #include     #define ADD 0x4E // Адрес микросхемы /*  LCDМикросхема  RSP0  RWP1  ENP2  D4P4  D5P5  D6P6  D7P7    На ножке P3 подключени подсветка. 1 вкл, 0 выкл.  */    void com(BYTE com)  {  com |= 0x08;    // Р3 в единицу, дабы горела подсветка  pcf8574_byte_out(com, ADD);// Вывод данных  com |= 0x04;// Е в единицу  pcf8574_byte_out(com, ADD);// Вывод данных  com &= 0xFB;// Е в ноль  pcf8574_byte_out(com, ADD);// Вывод данных  }    void init(void)  {  _delay_ms(30);// Пауза после подачи питания  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x20);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x20);// Установка параметров  com(0x80);// Установка параметров  com(0x00);// Выключаем дисплей  com(0x80);// Выключаем дисплей  com(0x00);// Очищаем дисплей  com(0x10);// Очищаем дисплей  com(0x00);// Устанавливаем режим ввода данных  com(0x60);// Устанавливаем режим ввода данных  com(0x00);// Включаем дисплей с выбранным курсором  com(0xC0);// Включаем дисплей с выбранным курсором  }    void char_out(BYTE data)  {    BYTE data_h = ((data & 0xF0) + 0x09);  BYTE data_l = ((data << 4) + 0x09);           pcf8574_byte_out(data_h, ADD); <i>// Передача старших 4 бит  data_h |= 0x04;  pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит  data_h &= 0xF9;  pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит    pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  data_l |= 0x04;  pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  data_l &= 0xF9;  pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  }    void str_out(BYTE *str)  {  while((*str) != '')  {  char_out(*str);  str++;  }  }    int main(void)  {    init();  str_out("ЁPҐBET MҐP!");        while(1)      {        }  }   

Собственно что здесь происходит. Сначала подключаем библиотеки для I2C и для PCF8574. Про I2C я писал уже здесь, поэтому распинаться еще раз на буду, а вот что в PCF8574.h я расскажу. В состав библиотеки вошли всего три функции.

   BYTE pcf8574_test(BYTE add)  {  BYTE ask = ACK;  add &= 0xFE;    i2c_start();  ask = i2c_send_byte(add);  i2c_stop();    return ask;  }   

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

   BYTE pcf8574_byte_out(BYTE data, BYTE add)  {  BYTE ask = ACK;  add &= 0xFE;    i2c_start();  ask = i2c_send_byte(add);  if(!ask) ask = i2c_send_byte(data);  i2c_stop();    return ask;  }   

Эта функция уже заточена чисто под данную микросхему. В качестве аргументов ей передаются байт для передачи в шину и адрес микросхемы. Функция сначала запросит микросхему по адресу, а затем пошлет байт. Если микросхема получила байт и ответила ACK, то функция закончит работу с микросхемой и вернет ноль как удачная посылка байта. А микросхема в это время выведет этот байт в свой параллельный порт. Иначе получим NACK и вернем единицу, передача провалилась.

   BYTE pcf8574_str_out(BYTE *data, BYTE col, BYTE add)  {  BYTE ask = ACK;  add &= 0xFE;    i2c_start();  ask = i2c_send_byte(add);  for(BYTE i=0; i 

Эта функция создана для эксперимента. Принимает указатель на массив однобайтовых данных, количество этих байт и адрес микросхемы. Собственно попытка передать все данные одной сессией, а не одним байтом за сессию. Функция работает, но так для ЖК дисплея и не подошла. А теперь давайте вернемся к основной программе. После подключения библиотек, прописываем адрес микросхемы. Далее создаем три функции по аналогии с lcd.h. Отличие лишь в принципе передачи данных.

   void com(BYTE com)  {  com |= 0x08;// Р3 в единицу, дабы горела подсветка  pcf8574_byte_out(com, ADD);// Вывод данных  com |= 0x04;// Е в единицу  pcf8574_byte_out(com, ADD);// Вывод данных  com &= 0xFB;// Е в ноль  pcf8574_byte_out(com, ADD);// Вывод данных  }   

Эта функция передает только команды дисплею. Отсюда появилась первая строка с логическим сложением команды с 0х08. Эта бяка нужна из-за того что мы передаем байт не прямо в порт ЖК дисплея, а через наш ретранслятор. То есть если мы подали байт, а потом нам нужно вывести только один бит, то соизвольте к предыдущему байту присвоит нужный бит и уже его снова отправить в порт. Вот такая заморочка. Сложение с 0х08 необходимо для постоянного удержания единицы на третьем разряде. Помните про подсветку? Вот именно это сложение и включает подсветку. После вызываем функцию передачи байта в шину. О ней написано выше. Затем передаем байт по шине в микросхему. Далее следует выставить в единицу Е, чем собственно занимается логическое сложение байта с 0х04. После обнуление Е. Таким образом можно послать любую команду дисплею лишь передав в качестве аргумента саму команду.

   void init(void)  {  _delay_ms(30);// Пауза после подачи питания  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x30);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x20);// Переход в 4-х битный режим  _delay_us(40);// Задержка для выполнения команды  com(0x20);// Установка параметров  com(0x80);// Установка параметров  com(0x00);// Выключаем дисплей  com(0x80);// Выключаем дисплей  com(0x00);// Очищаем дисплей  com(0x10);// Очищаем дисплей  com(0x00);// Устанавливаем режим ввода данных  com(0x60);// Устанавливаем режим ввода данных  com(0x00);// Включаем дисплей с выбранным курсором  com(0xC0);// Включаем дисплей с выбранным курсором  }   

Эта функция занимается лишь инициализацией дисплея. Последовательность команд взята из даташита на ЖК дисплей.

   void char_out(BYTE data)  {    BYTE data_h = ((data & 0xF0) + 0x09);  BYTE data_l = ((data << 4) + 0x09);           pcf8574_byte_out(data_h, ADD); <i>// Передача старших 4 бит  data_h |= 0x04;  pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит  data_h &= 0xF9;  pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит    pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  data_l |= 0x04;  pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  data_l &= 0xF9;  pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит  }   

Эта функция передает данные ЖК дисплею. Выполняется так же как и команды за исключением того, что передача байта идет сначала старшим полубайтом, а затем младшим. А остальное тоже самое.

   void str_out(BYTE *str)  {  while((*str) != '')  {  char_out(*str);  str++;  }  }   

Ну, а эта функция чисто для передачи строки дисплею. Собственно к нашей теме она никакого отношения не имеет. Проект для AtmelStudio 6.2

Грамотный    01.08.15 17:11

Запятая пропущена. Правильно: “ПРИВЕТ, МИР!” И сей девайс заточен не только для HD44780. Подтягивающие резисторы ставятся со стороны мастера. Согласно спецификации, запись данных в контроллер LCD идет по спаду Е. Отсюда первая же функция упрощается: void com(BYTE com) { com |= 0x08; // подсветка pcf8574_byte_out(com | 0x04, ADD);// Вывод данных pcf8574_byte_out(com, ADD); // Е в ноль } Да и остальные тоже существенно меньше могут быть. Например, void char_out(BYTE data) будет всего из двух вызовов, и уж тем более без дополнительных переменных. Инициализация LCD выполнена с нарушениями спецификации таймингов.

Алексей    02.08.15 19:11

Из-за отсутствия запятой, дисплей не пострадает. Сей девайc как раз заточен именно под дисплеи с таким, либо аналогичным контроллером. А вот именно микросхема действительно простой расширитель порта. По поводу Е я согласен. Дополнительные переменные нужны. Если передать функции аргумент с выполнением неких действий с логикой, могут возникнуть глюки. Уже с таким сталкивался. Инициализация выполняется без нарушений тайменгов. В документации сказано, что между командами ставиться пауза 40 мкс. Из-за того что передача идет по шине i2c, а та в свою очередь программная и медленная, то периоды выполняются с лихвой. Если все же Вам не лень, то напишите свой вариант и пришлите мне. Я его опубликую. В конце концов данный сайт предназначен на любительскую аудиторию и каждый кто хочет может высказать свое мнение и видение на жизнь МК.

Алексей    06.08.15 09:14

Добавлены тайменги при инициализации дисплея по замечанию уважаемого “Грамотного”

Дмитрий    14.06.16 21:57

Здравствуйте Алексей.Можно в генератор кода добавить библиотеку для работы с PCF8574.

Алексей    14.06.16 22:32

Я подумаю.))

ruslan    21.12.16 19:54

Ребята, нашел подробное описание по подключению LCD 1602 по I2C интерфейсу на основе PCF8574 Подключение LCD 1602 I2C

Алексей    21.12.16 21:53

О да. Особенно код на асме. Ардуинщики оценят по полной))) пы.сы. Даже если не взирать на асм, то там прога написана под PIC контроллер. Для AVRщиков это “очень” полезная информация? особенно начинающим))) Я ничего не имею против PIC, но даже асм у PIC и AVR разный. А по поводу подробностей работы ЖК дисплея, то можно глянуть тут))) Правда я ее еще писал под CVAVR но все команды разобраны и разложены по полочкам. Но в любом случае решайте сами где понятнее написано))) Автор пишет, читатель выбирает.

GeK    04.01.17 12:52
Алексей    04.01.17 14:27

Что-то вы перепутали. Выписка из документации на микросхему 0b01001110 это 0x4E Так что тут все верно. А если нужно сменить адрес, то всего лишь нужно его поменять в дефайне.

Юрий    14.12.17 21:26

Доброго времени суток! А можно еще код функции lcdgotoxy и lcdclear для работы с переходником на PCF8574.

Александр    20.05.18 18:14

Доброго времени суток! как вы выводите русский текст.

Алексей    20.05.18 23:04

Это отечественный дисплей от фирмы МЭЛТ. У него в памяти зашита кириллица.

Александр    21.05.18 04:55
Алексей    21.05.18 09:22

Я бы для начала написал бы тестовою программу. Перебор всей памяти с выводом на дисплей символов и их адресов. А потом уже выеснять в чем проблема. Скорее всего таблица символов не совпадает с таблицей ascii.

Андрей    03.09.18 08:32
Андрей    03.09.18 10:22

Или в Proteuse никто не проверял?

Андрей    03.09.18 10:56

Разобрался main_init

Павел    30.05.19 23:35

Любопытная вещь, адрес дисплея 0х4Е, а если тот же дисплей подключить к ардуинке то адрес 0х27

Павел    31.05.19 11:04

Спасибо огромное за Вашу работу! Перерыл весь интернет, ни один из приведенных примеров кроме Вашего не заработал. Единственное, в архиве проекта в функции инициализации дисплея не прописаны задержки _delay_, и он соответственно не работает

Алексей    01.06.19 09:52

Ну это больше демонстрационный проект. По хорошему нужно библиотеку axlib переписывать, но с учетом того что STM32 и STM8 двигается семимильными шагами, смысла в AVR уже нет вообще.

Павел    05.06.19 12:57

У STM нет DIP корпусов, сложнее делать печатные платы. Для моих проектов возможностей AVR хватает с запасом, на одной Atmega 8 очень много можно уместить

Алексей    05.06.19 15:20

Да, но сколько стоит Atmega8 и stm8s003)))

Дмитрий    07.06.19 00:41
Дмитрий    07.06.19 17:56
Павел    07.06.19 20:37

Сколько стоит, 150 рублей, по цене релюшки в общем), а как вы разводите платы под STM? ЛУТ ненадежен, ЧПУ фрезер не уверен что возьмет (не пробовал)

Алексей    09.06.19 18:59

Фоторезист или китайцы.

Каждый радиолюбитель после некоторого количества простых самоделок приходит к цели сконструировать что-то грандиозное с использование датчиков и кнопок. Ведь гораздо интереснее выводить данные на дисплей, нежели на монитор порта. Но тогда встает вопрос: какой дисплей выбрать? И вообще, как подключать его, что нужно для подключения? Ответы на эти вопросы будут рассмотрены в этой статье.

LCD 1602

Среди множества вариантов среди дисплеев отдельно хочется отметить именно дисплей LCD1602 на базе контроллера HD4478. Существует этот дисплей в двух цветах: белые буквы на синем фоне, черные буквы на желтом фоне. Подключение LCD 1602 к Arduino также не вызовет никаких проблем, так как есть встроенная библиотека, и ничего скачивать дополнительно не нужно. Дисплеи отличаются не только ценой, но и размером. Зачастую радиолюбителями используется 16 x 2, то есть 2 строки по 16 символов. Но существует также и 20 x 4, где 4 строки по 20 символов. Размеры и цвет не играют никакой роли в подключении дисплея lcd 1602 к Arduno, подключаются они одинаково. Угол обзора составляет 35 градусов, время отклика дисплея – 250 мс. Работать может при температурах от -20 до 70 градусов по Цельсию. При работе использует 4 мА на экран и на подсветку 120 мА.

Где используется?

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

Подключение к Arduino

Подключение LCD 1602 к Arduino Nano и Uno не отличается. С дисплеем можно работать в двух режимах: 4 бита и 8. При работе с 8-битным используются и младшие, и старшие биты, а с 4-битным – только младшие. Работать с 8-битным особого смысла нет, так как добавится для подключения еще 4 контакта, что не целесообразно, ведь скорости выше не будет, предел обновлений дисплея – 10 раз в секунду. Вообще, для подключения lcd 1602 к Arduino используется много проводов, что доставляет некие неудобства, но существует особые шилды, но об этом позже. На фотографии изображено подключение дисплея к Arduino Uno:

Пример программного кода:

#include   // Добавляем необходимую библиотеку  LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7)    void setup(){     lcd.begin(16, 2);                  // Задаем размерность экрана      lcd.setCursor(0, 0);              // Устанавливаем курсор в начало 1 строки    lcd.print("Hello, world!");       // Выводим текст    lcd.setCursor(0, 1);              // Устанавливаем курсор в начало 2 строки    lcd.print("fb.ru");         // Выводим текст  }    void loop(){  }

Что же делает код? Первым делом подключается библиотека для работы с дисплеем. Как уже говорилось выше, эта библиотека уже входит в состав Arduino IDE и дополнительно скачивать и устанавливать ее не надо. Далее определяются контакты, которые подключены к выводам: RS, E, DB4, DB5, DB6, DB7 соответственно. После чего задается размерность экрана. Так как мы работаем с версией, где 16 символов и 2 строки, то пишем такие значения. Устанавливаем курсор в начало первой строки и выводим наш первый текст Hello World. Далее ставим курсор на вторую строку и выводим название сайта. Вот и все! Было рассмотрено подключение lcd 1602 к Arduino Uno.

Что такое I2C и зачем он нужен?

Как уже говорилось выше, подключение дисплея занимает очень много контактов. Например, при работе с несколькими датчиками и дисплеем LCD 1602 контактов может просто не хватить. Зачастую радиолюбителями используются версии Uno или Nano, где не так много контактов. Тогда люди придумали специальные шилды. Например, I2C. Он позволяет подключать дисплей всего в 4 контакта. Это в два раза меньше. Продается модуль I2C как отдельно, где самому нужно припаивать, так и уже припаянный к дисплею LCD 1602.

Подключение с помощью I2C модуля

Подключение LCD 1602 к Arduino Nano с I2C занимает мало места, всего 4 контакта: земля, питание и 2 выхода для передачи данных. Питание и землю подключаем на 5V и GND на Arduino соответственно. Оставшиеся два контакта: SCL и SDA подключаем к любым аналоговым пинам. На фотографии можно увидеть пример подключения lcd 1602 к arduino с I2C модулем:

Программный код

Если для работы с дисплеем без модуля необходимо было воспользоваться только одной библиотекой, то для работы с модулем нужно две библиотеки. Одна из них уже есть в составе Arduino IDE – Wire. Другую библиотеку, LiquidCrystal I2C, надо скачивать отдельно и устанавливать. Для установки библиотеки в Arduino содержимое скачанного архива необходимо загрузить в корневую папку Libraries. Пример программного кода с использованием I2C:

#include    #include   LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей  void setup()  {    lcd.init();                         lcd.backlight();// Включаем подсветку дисплея    lcd.print("FB.ru");    lcd.setCursor(8, 1);    lcd.print("LCD 1602");  }  void loop()  {    // Устанавливаем курсор на вторую строку и нулевой символ.    lcd.setCursor(0, 1);    // Выводим на экран количество секунд с момента запуска ардуины    lcd.print(millis()/1000);  }

Как можно увидеть, код почти не отличается.

Как добавить свой символ?

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

1
1
1 1 1
1
1 1 1
1
1

Если 0 – там ничего нет, если 1 – это закрашенный участок. В примере выше можно увидеть создание символа “улыбающийся смайл”. На примере программы в Arduino это будет выглядеть следующим образом:

#include   #include    // Лобавляем необходимую библиотеку  // Битовая маска символа улыбки  byte smile[8] =  {    B00010,    B00001,    B11001,    B00001,    B11001,    B00001,    B00010,  };      LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7)    void setup(){     lcd.begin(16, 2);                  // Задаем размерность экрана      lcd.createChar(1, smile);          // Создаем символ под номером 1      lcd.setCursor(0, 0);               // Устанавливаем курсор в начало 1 строки    lcd.print("1");                   // Выводим смайлик (символ под номером 1) - "1"        }    void loop(){  }

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

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

Бывают такие случаи, когда дисплей не работает. Например, включается, но не показывает символы. Или вовсе не включается. Сначала посмотрите, правильно ли вы подключили контакты. Если вы использовали подключение lcd 1202 к Arduino без I2C, то очень легко запутаться в проводах, что может стать причиной некорректной работы дисплея. Также следует удостовериться в том, что контрастность дисплея увеличена, так как при минимальной контрастности даже не видно, включен ли LCD 1602 или нет. Если это ничего не помогает, то, возможно, проблема может кроется в пайке контактов, это при использовании модуля I2C. Также частой причиной, при которой дисплей может не работать, является неправильная установка I2C адреса. Дело в том, что производителей много, и они могут ставить разный адрес, исправлять нужно тут:

LiquidCrystal_I2C lcd(0x27,16,2);

В скобках можно увидеть два значения, 0x27 и 16,2 (16, 2 – является размером дисплея, а 0x27 как раз таки адрес I2C). Вместо этих значений можно попробовать поставить 0x37 или 0x3F. Ну и еще одной причиной является просто неисправный LCD 1602. Учитывая, что практически все для Arduino изготавливается в Китае, то нельзя быть уверенным на 100%, что приобретенный товар не является браком.

Плюсы и минусы LCD 1602

Рассмотрим плюсы и минусы дисплея LCD 1602.

Плюсы

  • Цена. Этот модуль можно приобрести совсем по демократичной цене в китайских магазинах. Цена составляет 200-300 рублей. Иногда продается даже вместе с I2C модулем.
  • Легко подключать. Вероятно, никто сейчас не подключает LCD 1602 без I2C. А с этим модулем подключение занимает всего 4 контакта, никаких “паутин” из проводов не будет.
  • Программирование. Благодаря готовым библиотекам работать с этим модулем легко, все функции уже прописаны. А при необходимости добавить свой символ затрачивается всего пару минут.

Минусы

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

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

  • Вы здесь:  
  • Главная image
  • Программер image
  • Основы Arduino image
  • Как подключить дисплей LCD1602 к Arduino
Категория: Основы Arduino
Опубликовано: 23 февраля 2019

Всем привет, давайте сегодня займемся подключением ардуино к дисплею LCD 1602.

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

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

Рассмотрим, что у нас на схеме, это резистор, который регулирует яркость дисплея, схему подключения я покажу чуть позже. Здесь у нас 5 Вольт, 3,3 Вольты, черный традиционно GRD, и тут остальная разводка выполнена, покажу, как это всё устроено, как это работает.

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

Вот схема ардуино, это дисплей LCD 1602, сопротивление, проводники, питание 5 Вольт, и так далее. Принципиальная схема выглядит так, контакты дисплея пронумерованы от одного до 16, так же всё это буквенно обозначено, сопротивление на 100 ом, и вот меняя его значение, изменяется яркость на дисплее.

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

Нам нужно будет подключить библиотеку, называется она Liquid Crystal (жидкие кристаллы), также объявим массивы array1 и array2 тип char.

 #include < LiquidCrystal.h > 

В массиве array1 я написал название своего сайта – maxfad.ru, давайте я напишу название маленькими буквами.

 char array1[]="maxfad.ru                 "; 

Второй массив array2 у нас будет вот такой с текстом hello, world!.

 char array2[]="hello, world!             "; 

Обратите внимание количество знаков в массивах нас равно 26, то есть мы имеем одинаковую длину строк, чтобы у нас примерно одинаково они все прорисовывались на дисплее.

Объявим переменную для задержки в 250 миллисекунд и объявим контакты, которые будем использовать на нашем lcd-экране и пока с этим всё.

 int tim = 250; LiquidCrystal lcd(4, 6, 10, 11, 12, 13); 

Давайте сохраним на рабочий стол наш проект, очистим как всегда лишняя в setup у нас будет всё очень просто, мы указываем что в нас LCD двухстрочный, по 16 символов,

void setup() {   lcd.begin(16, 2);   } 

а вот в цикле loop займёмся написанием следующего кода.

lcd.setCursor(15,0);

Давайте установим курсор в положение 15:0, напишем цикл for int, пройдемся в цикле от 0 до 26 до нашей длины строки и будем увеличивать на единичку наш счётчик.

В счётчике мы будем скролить в лево дисплей через функцию Scroll displayleft будем делать смещение влево, нас получится смещение влево.

Далее мы начнём печатать символы из массива array1, начну печатать исходя из значения 1 2 3 4 и так далее, и далее мы сделаем задержку между печатью символов через 250 миллисекунд.

for (int positionCounter1 = 0; positionCounter1 < 26; positionCounter1++)     {       lcd.scrollDisplayLeft();       lcd.print(array1[positionCounter1]);       delay(tim);      } 

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

 lcd.clear(); lcd.setCursor(15,1); 

И здесь мы делаем практически всё тоже самое, скоролим в лефт, печатаем всё что у нас по одному символу находится во втором массиве, делаем задержку 250мс.

 for (int positionCounter = 0; positionCounter < 26; positionCounter++)     {       lcd.scrollDisplayLeft();       lcd.print(array2[positionCounter]);       delay(tim);     } lcd.clear(); 

И после этого мы очищаем наш экран от всяких записей сохраним, сделаем форматирования текста (ctrl+T). Давайте ещё раз посмотрим, что у нас тут получилось, такой вот скетч.

#include < LiquidCrystal.h> char array1[]="MAXFAD.RU                 "; char array2[]="hello, world!             "; int tim = 250;   LiquidCrystal lcd(4, 6, 10, 11, 12, 13);  void setup() {   lcd.begin(16, 2);   } void loop()  {     lcd.setCursor(15,0);       for (int positionCounter1 = 0; positionCounter1 < 26; positionCounter1++)     {       lcd.scrollDisplayLeft();       lcd.print(array1[positionCounter1]);       delay(tim);      }     lcd.clear();      lcd.setCursor(15,1);       for (int positionCounter = 0; positionCounter < 26; positionCounter++)     {       lcd.scrollDisplayLeft();       lcd.print(array2[positionCounter]);       delay(tim);     }     lcd.clear(); }

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

Давайте теперь напишем какой-нибудь текст на русском, на второй строчке, посмотрим, что получится, допустим напишем не hello world, а привет мир. Сохраняем, проверяем, загружаем обновление. Первая строчка без изменений maxfad.ru а текст второй строки – как в фильме Хищник, абракадабра, корявит дико.

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

Смотрите видео: Как подключить дисплей LCD1602 к Arduino

Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
А как считаете Вы?
Напишите в комментариях, что вы думаете – согласны
ли со статьей или есть что добавить?
Добавить комментарий