Подключение lcd i2c. Подключение LCD экрана LCM1602 с I2C к Arduino

Сеть

Подключение lcd i2c. Подключение LCD экрана LCM1602 с I2C к Arduino

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

Шина данных ш2с позволяет по двум проводам подключать до 127 устройств, при чем одновременно. Данный I2C реализован на чипе PCF8574T.

Схема подключения:

Синяя штука — переменное сопротивление, позволяет настроить контрастность экрана.

Перемычка слева — отвечает за подсветку экрана.

Блок из 4х контактов подключается к arduino так:

GND — GND
VCC — 5V
SDA — A4 (если Arduino MEGA, то к D20)
SCL — A5 (если Arduino MEGA, то к D21)

Библиотека

Скетч

У дисплея может быть другой IIC адрес, вместо 0x27 может оказаться 0x3F. Чтобы точно определить адрес можете воспользоваться сканером i2c устройств .

#include
#include //задаем адрес LCD экрана 0x27, 16 символов, 2 строки

LiquidCrystal_I2C lcd(0x27, 16, 2);
void
setup
() {
lcd.init(); // Инициализируем экран

//включаем подсветку

lcd.backlight();
//Устанавливаем позицию начиная с которой выводится текст.

lcd.setCursor
(2, 0);
//выводим строку 1

lcd.print
(“Hello, World!”
);
//аналогично выводим вторую строку

lcd.setCursor
(1, 1);
lcd.print
(“www.сайт”
);
}
void
loop
() {
}

  • Модуль FC-113 сделан на базе микросхемы PCF8574T, которая представляет собой 8-битный сдвиговый регистр – «расширитель» входов-выходов для последовательной шины I2C. На рисунке микросхема обозначена DD1.
  • R1 – подстроечный резистор для регулировки контрастности ЖК дисплея.
  • Джампер J1 используется для включения подсветки дисплея.
  • Выводы 1…16 служат для подключения модуля к выводам LCD дисплея.
  • Контактные площадки А1…А3 нужны для изменения адреса I2C устройства. Запаивая соответствующие перемычки, можно менять адрес устройства. В таблице приведено соответствие адресов и перемычек: “0” соответствует разрыву цепи, “1” – установленной перемычке. По умолчанию все 3 перемычки разомкнуты и адрес устройства 0x27
    .

2
Схема подключения ЖК дисплея к Arduino
по протоколу I2C

Подключение модуля к Arduino осуществляется стандартно для шины I2C: вывод SDA модуля подключается к аналоговому порту A4, вывод SCL – к аналоговому порту A5 Ардуино. Питание модуля осуществляется напряжением +5 В от Arduino. Сам модуль соединяется выводами 1…16 с соответствующими выводами 1…16 на ЖК дисплее.

3
Библиотека для работы
по протоколу I2C

Теперь нужна библиотека для работы с LCD по интерфейсу I2C. Можно воспользоваться, например, вот этой (ссылка в строке “Download Sample code and library”).

Скачанный архив LiquidCrystal_I2Cv1-1.rar
разархивируем в папку libraries
, которая находится в директории Arduino IDE.

Библиотека поддерживает набор стандартных функций для LCD экранов:

Функция Назначение
LiquidCrystal()
создаёт переменную типа LiquidCrystal и принимает параметры подключения дисплея (номера выводов);
begin()
инициализация LCD дисплея, задание параметров (кол-во строк и символов);
clear()
очистка экрана и возврат курсора в начальную позицию;
home()
возврат курсора в начальную позицию;
setCursor()
установка курсора на заданную позицию;
write()
выводит символ на ЖК экран;
print()
выводит текст на ЖК экран;
cursor()
показывает курсор, т.е. подчёркивание под местом следующего символа;
noCursor()
прячет курсор;
blink()
мигание курсора;
noBlink()
отмена мигания;
noDisplay()
выключение дисплея с сохранением всей отображаемой информации;
display()
включение дисплея с сохранением всей отображаемой информации;
scrollDisplayLeft()
прокрутка содержимого дисплея на 1 позицию влево;
scrollDisplayRight()
прокрутка содержимого дисплея на 1 позицию вправо;
autoscroll()
включение автопрокрутки;
noAutoscroll()
выключение автопрокрутки;
leftToRight()
задаёт направление текста слева направо;
rightToLeft()
направление текста справа налево;
createChar()
создаёт пользовательский символ для LCD-экрана.

4
Скетч для вывода текста
на LCD экран по шине I2C

Откроем образец: Файл Образцы LiquidCrystal_I2C CustomChars
и немного его переделаем. Выведем сообщение, в конце которого будет находиться мигающий символ. В комментариях к коду прокомментированы все нюансы скетча.

#include // подключаем библиотеку Wire
#include // подключаем библиотеку ЖКИ
#define printByte(args) write(args); //
uint8_t heart = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; // битовая маска символа «сердце»
LiquidCrystal_I2C lcd(0x27, 16, 2); // Задаём адрес 0x27 для LCD дисплея 16×2
void setup() {

lcd.init(); // инициализация ЖК дисплея
lcd.backlight(); // включение подсветки дисплея
lcd.createChar(3, heart); // создаём символ «сердце» в 3 ячейке памяти
lcd.home(); // ставим курсор в левый верхний угол, в позицию (0,0)
lcd.!”); // печатаем строку текста
lcd.setCursor(0, 1); // перевод курсора на строку 2, символ 1
lcd.print(” i “); // печатаем сообщение на строке 2
lcd.printByte(3); // печатаем символ «сердце», находящийся в 3-ей ячейке
lcd.print(” Arduino “);
}

void loop() {
// мигание последнего символа
lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1
lcd.print(“t”);
delay(500);
lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1
lcd.print(” “);
delay(500);
}

Кстати, символы, записанные командой lcd.createChar();
, остаются в памяти дисплея даже после выключения питания, т.к. записываются в ПЗУ дисплея 1602.

5
Создание собственных символов
для ЖК дисплея

Немного подробнее рассмотрим вопрос создания собственных символов для ЖК экранов. Каждый символ на экране состоит из 35-ти точек: 5 в ширину и 7 в высоту (+1 резервная строка для подчёркивания). В строке 6 приведённого скетча мы задаём массив из 7-ми чисел: {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}
. Преобразуем 16-ричные числа в бинарные: {00000, 01010, 11111, 11111, 01110, 00100, 00000}
. Эти числа – не что иное, как битовые маски для каждой из 7-ми строк символа, где “0” обозначают светлую точку, а “1” – тёмную. Например, символ сердца, заданный в виде битовой маски, будет выглядеть на экране так, как показано на рисунке.

6
Управление ЖК экраном
по шине I2C

Загрузим скетч в Arduino. На экране появится заданная нами надпись с мигающим курсором в конце.

7
Что находится «за»
шиной I2C

В качестве бонуса рассмотрим временную диаграмму вывода латинских символов “A”, “B” и “С” на ЖК дисплей. Эти символы имеются в ПЗУ дисплея и выводятся на экран просто передачей дисплею их адреса. Диаграмма снята с выводов RS, RW, E, D4, D5, D6 и D7 дисплея, т.е. уже после преобразователя FC-113 «I2C параллельная шина». Можно сказать, что мы погружаемся немного «глубже» в «железо».

Временная диаграмма вывода латинских символов “A”, “B” и “С” на LCD дисплей 1602

На диаграмме видно, что символы, которые имеются в ПЗУ дисплея (см. стр.11 даташита, ссылка ниже), передаются двумя полубайтами,
первый из которых определяет номер столбца таблицы, а второй – номер строки. При этом данные «защёлкиваются» по фронту сигнала на линии E
(Enable), а линия RS
(Register select, выбор регистра) находится в состоянии логической единицы, что означает передачу данных. Низкое состояние линии RS означает передачу инструкций, что мы и видим перед передачей каждого символа. В данном случае передаётся код инструкции возврата каретки на позицию (0, 0) ЖК дисплея, о чём также можно узнать, изучив техническое описание дисплея.

И ещё один пример. На этой временной диаграмме показан вывод символа «Сердце» на ЖК дисплей.

Опять, первые два импульса Enable
соответствуют инструкции Home()
(0000 0010 2) – возврат каретки на позицию (0; 0), а вторые два – вывод на ЖК дисплей хранящийся в ячейке памяти 3 10 (0000 0011 2) символ «Сердце» (инструкция lcd.createChar(3, heart);
скетча).

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

Плата разведена таким образом, чтобы ее можно было сразу скрестить с ЖК дисплеем. На вход подается питание и линии I2C. На плате сразу установлены подтягивающие резисторы на линиях SCL и SDA, потенциометр для регулировки контрастности и питание самого дисплея.

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

#include
#include
#include
#include
#define ADD 0x4E // Адрес микросхемы

/*
LCD Микросхема
RS P0
RW P1
EN P2
D4 P4
D5 P5
D6 P6
D7 P7
На ножке P3 подключени подсветка. 1 вкл, 0 выкл.
*/
// Вывод данных

com |= 0x04; // Е в единицу

pcf8574_byte_out(com, ADD); // Вывод данных

com &= 0xFB; // Е в ноль

pcf8574_byte_out(com, ADD); // Вывод данных

}
void init(void)
{
_delay_ms(30);
com(0x30);
_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 бит
data_h |= 0x04;
pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит
// Передача старших 4 бит
// Передача младших 4 бит
// Передача младших 4 бит
// Передача младших 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 бит
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
Алексей 21.12.16 21:53

О да. Особенно код на асме. Ардуинщики оценят по полной)))

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

GeK 04.01.17 12:52

“I2C адрес микросхемы (по умолчанию он равен 0x4E”

Старшие 4 бита адреса фиксированы,
префикс У PCF8574 равен 0100, а у PCF8574A – 0111
Младшие 3 бита зависят от состояния входов микросхемы A2-A0. По умолчанию все 3 перемычки разомкнуты, соответственно адрес микросхемы принимает значение 0111111.
// A2 A1 A0 PCF8574 PCF8574A
// 1 1 1 0x20 0x38
// 1 1 0 0x21 0x39
// 1 0 1 0x22 0x3A
// 1 0 0 0x23 0x3B
// 0 1 1 0x24 0x3C
// 0 1 0 0x25 0x3D
// 0 0 1 0x26 0x3E
// 0 0 0 0x27 0x3F

Алексей 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

Доброго времени суток! Я пиши как у вас в Проект для AtmelStudio 6.2 ” ЁPҐBET MҐP!” то выводит нормально
а если пиши “ПРИВЕТ МИР!” выводит ерунду всякую. у меня два
варианта дисплеев у одного зашита кириллица. второй китайский.

Алексей 21.05.18 09:22

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

Андрей 03.09.18 08:32

День Добрый!

А схемку под Proteus не можете подкинуть?

Андрей 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

Здравствуй, Алексей.
Подскажи, пожалуйста, как нужно читать из pcf8574 состояние порта?
Хочу сделать внешний блок, 8 GPIO по шине i2c – саме оно.

Дмитрий 07.06.19 17:56

Сам себе отвечу
Функция возвращает байт – состояние портов микросхемы
uint8_t pcf8574_byte_rcv(uint8_t addr)
{
uint8_t ask = ACK;
addr |= 0b01; //READ
uint8_t data=0;
i2c_start();
ask = i2c_send_byte(addr);
if(!ask) data = i2c_read_byte(NACK);
i2c_stop();

Return data;
}

Павел 07.06.19 20:37

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

  • Модуль FC-113 сделан на базе микросхемы PCF8574T, которая представляет собой 8-битный сдвиговый регистр – «расширитель» входов-выходов для последовательной шины I2C. На рисунке микросхема обозначена DD1.
  • R1 – подстроечный резистор для регулировки контрастности ЖК дисплея.
  • Джампер J1 используется для включения подсветки дисплея.
  • Выводы 1…16 служат для подключения модуля к выводам LCD дисплея.
  • Контактные площадки А1…А3 нужны для изменения адреса I2C устройства. Запаивая соответствующие перемычки, можно менять адрес устройства. В таблице приведено соответствие адресов и перемычек: “0” соответствует разрыву цепи, “1” – установленной перемычке. По умолчанию все 3 перемычки разомкнуты и адрес устройства 0x27
    .

2
Схема подключения ЖК дисплея к Arduino
по протоколу I2C

Подключение модуля к Arduino осуществляется стандартно для шины I2C: вывод SDA модуля подключается к аналоговому порту A4, вывод SCL – к аналоговому порту A5 Ардуино. Питание модуля осуществляется напряжением +5 В от Arduino. Сам модуль соединяется выводами 1…16 с соответствующими выводами 1…16 на ЖК дисплее.

3
Библиотека для работы
по протоколу I2C

Теперь нужна библиотека для работы с LCD по интерфейсу I2C. Можно воспользоваться, например, вот этой (ссылка в строке “Download Sample code and library”).

Скачанный архив LiquidCrystal_I2Cv1-1.rar
разархивируем в папку libraries
, которая находится в директории Arduino IDE.

Библиотека поддерживает набор стандартных функций для LCD экранов:

Функция Назначение
LiquidCrystal()
создаёт переменную типа LiquidCrystal и принимает параметры подключения дисплея (номера выводов);
begin()
инициализация LCD дисплея, задание параметров (кол-во строк и символов);
clear()
очистка экрана и возврат курсора в начальную позицию;
home()
возврат курсора в начальную позицию;
setCursor()
установка курсора на заданную позицию;
write()
выводит символ на ЖК экран;
print()
выводит текст на ЖК экран;
cursor()
показывает курсор, т.е. подчёркивание под местом следующего символа;
noCursor()
прячет курсор;
blink()
мигание курсора;
noBlink()
отмена мигания;
noDisplay()
выключение дисплея с сохранением всей отображаемой информации;
display()
включение дисплея с сохранением всей отображаемой информации;
scrollDisplayLeft()
прокрутка содержимого дисплея на 1 позицию влево;
scrollDisplayRight()
прокрутка содержимого дисплея на 1 позицию вправо;
autoscroll()
включение автопрокрутки;
noAutoscroll()
выключение автопрокрутки;
leftToRight()
задаёт направление текста слева направо;
rightToLeft()
направление текста справа налево;
createChar()
создаёт пользовательский символ для LCD-экрана.

4
Скетч для вывода текста
на LCD экран по шине I2C

Откроем образец: Файл Образцы LiquidCrystal_I2C CustomChars
и немного его переделаем. Выведем сообщение, в конце которого будет находиться мигающий символ. В комментариях к коду прокомментированы все нюансы скетча.

#include // подключаем библиотеку Wire
#include // подключаем библиотеку ЖКИ
#define printByte(args) write(args); //
uint8_t heart = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; // битовая маска символа «сердце»
LiquidCrystal_I2C lcd(0x27, 16, 2); // Задаём адрес 0x27 для LCD дисплея 16×2
void setup() {

lcd.init(); // инициализация ЖК дисплея
lcd.backlight(); // включение подсветки дисплея
lcd.createChar(3, heart); // создаём символ «сердце» в 3 ячейке памяти
lcd.home(); // ставим курсор в левый верхний угол, в позицию (0,0)
lcd.!”); // печатаем строку текста
lcd.setCursor(0, 1); // перевод курсора на строку 2, символ 1
lcd.print(” i “); // печатаем сообщение на строке 2
lcd.printByte(3); // печатаем символ «сердце», находящийся в 3-ей ячейке
lcd.print(” Arduino “);
}

void loop() {
// мигание последнего символа
lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1
lcd.print(“t”);
delay(500);
lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1
lcd.print(” “);
delay(500);
}

Кстати, символы, записанные командой lcd.createChar();
, остаются в памяти дисплея даже после выключения питания, т.к. записываются в ПЗУ дисплея 1602.

5
Создание собственных символов
для ЖК дисплея

Немного подробнее рассмотрим вопрос создания собственных символов для ЖК экранов. Каждый символ на экране состоит из 35-ти точек: 5 в ширину и 7 в высоту (+1 резервная строка для подчёркивания). В строке 6 приведённого скетча мы задаём массив из 7-ми чисел: {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}
. Преобразуем 16-ричные числа в бинарные: {00000, 01010, 11111, 11111, 01110, 00100, 00000}
. Эти числа – не что иное, как битовые маски для каждой из 7-ми строк символа, где “0” обозначают светлую точку, а “1” – тёмную. Например, символ сердца, заданный в виде битовой маски, будет выглядеть на экране так, как показано на рисунке.

6
Управление ЖК экраном
по шине I2C

Загрузим скетч в Arduino. На экране появится заданная нами надпись с мигающим курсором в конце.

7
Что находится «за»
шиной I2C

В качестве бонуса рассмотрим временную диаграмму вывода латинских символов “A”, “B” и “С” на ЖК дисплей. Эти символы имеются в ПЗУ дисплея и выводятся на экран просто передачей дисплею их адреса. Диаграмма снята с выводов RS, RW, E, D4, D5, D6 и D7 дисплея, т.е. уже после преобразователя FC-113 «I2C параллельная шина». Можно сказать, что мы погружаемся немного «глубже» в «железо».

Временная диаграмма вывода латинских символов “A”, “B” и “С” на LCD дисплей 1602

На диаграмме видно, что символы, которые имеются в ПЗУ дисплея (см. стр.11 даташита, ссылка ниже), передаются двумя полубайтами,
первый из которых определяет номер столбца таблицы, а второй – номер строки. При этом данные «защёлкиваются» по фронту сигнала на линии E
(Enable), а линия RS
(Register select, выбор регистра) находится в состоянии логической единицы, что означает передачу данных. Низкое состояние линии RS означает передачу инструкций, что мы и видим перед передачей каждого символа. В данном случае передаётся код инструкции возврата каретки на позицию (0, 0) ЖК дисплея, о чём также можно узнать, изучив техническое описание дисплея.

И ещё один пример. На этой временной диаграмме показан вывод символа «Сердце» на ЖК дисплей.

Опять, первые два импульса Enable
соответствуют инструкции Home()
(0000 0010 2) – возврат каретки на позицию (0; 0), а вторые два – вывод на ЖК дисплей хранящийся в ячейке памяти 3 10 (0000 0011 2) символ «Сердце» (инструкция lcd.createChar(3, heart);
скетча).

Оцените статью
Добавить комментарий

9 − 7 =