Символьные ЖК-модули на HD44780: LCD 1602 и 2004
HD44780 — контроллер почти всех символьных ЖК-модулей: 1602, 2004, 0802. Здесь — распиновка и подключение, система команд с временами по даташиту Hitachi, инициализация в 4-битном режиме, адреса строк, I²C-переходник на PCF8574, русский текст и генератор своих символов.
Обновлено Редакция GAW
Содержание
- Распиновка LCD 1602: 16 выводов
- Питание, контраст и подсветка
- Шина HD44780: регистры, RS, R/W и E
- Система команд HD44780
- Адреса DDRAM: как адресуются строки
- Инициализация HD44780 в 8- и 4-битном режиме
- Флаг занятости или задержки
- Пример на C для AVR: 4-битный режим без чтения
- Arduino: LiquidCrystal и LiquidCrystal_I2C
- Свои символы в CGRAM
- Знакогенератор, кириллица и русский текст
- I²C-модуль на PCF8574
- Модули на 3,3 и 5 В
- Типичные ошибки и отладка
HD44780 — контроллер и драйвер символьного жидкокристаллического индикатора фирмы Hitachi. Он хранит коды выводимых символов, содержит готовый шрифт и сам формирует напряжения для жидкокристаллической панели, а микроконтроллер только передаёт ему команды и коды символов по параллельной шине. Совместимые микросхемы — Samsung KS0066U, Sitronix ST7066U, Sunplus SPLC780D, КБ1013ВГ6 «Ангстрема» — понимают ту же систему команд, поэтому всё сказанное ниже относится к модулям 1602, 2004 или 0802 на любой из них.
Цифры в названии модуля — число знакомест в строке и число строк: 1602 — 16 символов в 2 строки, 2004 — 20 символов в 4 строки. Каждый символ — матрица 5 × 8 точек, нижняя строка которой отведена под курсор.
Коротко
- Питание: контроллер HD44780U работает от 2,7 до 5,5 В, типовые модули 1602 и 2004 рассчитаны на 5 В ± 10 %.
- Шина: 8 или 4 линии данных плюс RS, R/W и E. В 4-битном режиме байт передаётся двумя полубайтами, старший — первым.
- Время выполнения: почти все команды — 37 мкс, Return home — 1,52 мс при частоте генератора 270 кГц; Clear display у совместимых контроллеров — 1,52–1,53 мс.
- Адреса строк: первая строка начинается с 0x00, вторая — с 0x40; у модуля 2004 третья и четвёртая — с 0x14 и 0x54.
- Свои символы: CGRAM вмещает 8 символов 5 × 8 точек с кодами 0–7; встроенный знакогенератор HD44780U — 208 символов 5 × 8 и 32 символа 5 × 10.
- I²C-переходник: на PCF8574 отвечает по адресам 0x20–0x27, на PCF8574A — 0x38–0x3F; без перемычек — 0x27 или 0x3F.
Распиновка LCD 1602: 16 выводов
У модулей 1602, 2004 и большинства других символьных модулей один и тот же 16-выводной разъём с шагом 2,54 мм. Назначение выводов — по даташиту Winstar WH1602B; у других производителей так же, но расположение разъёма и выводов подсветки бывает разным, поэтому перед подключением сверьтесь с маркировкой на плате.
| Вывод | Обозначение | Назначение |
|---|---|---|
| 1 | VSS | общий провод, 0 В |
| 2 | VDD | питание логики: у 5-вольтовых модулей 4,5–5,5 В |
| 3 | V0 (VO) | напряжение контраста |
| 4 | RS | выбор регистра: 0 — команда, 1 — данные |
| 5 | R/W | направление: 0 — запись, 1 — чтение |
| 6 | E | строб обмена; запись — по спаду |
| 7–10 | D0–D3 | младшие линии данных; в 4-битном режиме не используются |
| 11–14 | D4–D7 | старшие линии данных; D7 при чтении — флаг занятости |
| 15 | A | анод подсветки (+) |
| 16 | K | катод подсветки (−) |
Входы RS, R/W и D0–D7 у HD44780U подтянуты к питанию внутри микросхемы — ток подтяжки от 50 до 250 мкА при 5 В. Поэтому неподключённые D0–D3 в 4-битном режиме ничему не мешают. У входа E подтяжки нет, и оставлять его в воздухе нельзя: Hitachi предупреждает, что промежуточный уровень на КМОП-входе увеличивает ток потребления, а случайный импульс на E — это ложная запись.
Питание, контраст и подсветка
Питание. Модуль 1602 Winstar WH1602B потребляет от логического питания 1,0–1,5 мА при 5 В (без подсветки), допустимое VDD — 4,5–5,5 В. Сама микросхема HD44780U работает от 2,7 В, но об этом — в разделе про модули на 3,3 и 5 В.
Контраст. Жидкокристаллической панели нужно напряжение VDD − V0. У WH1602B-TMI-ET при 25 °C это 3,6–3,8 В, то есть V0 около 1,2–1,4 В при VDD = 5 В; у модуля 2004 WH2004A — 4,4–4,6 В. Напряжение сильно зависит от температуры: тому же WH1602B при −20 °C нужно до 5,2 В, а при 70 °C — от 3,2 В. Поэтому Winstar рекомендует подстроечный резистор 10–20 кОм: крайние выводы — на VDD и VSS, движок — на V0. Через потенциометр 10 кОм течёт 0,5 мА — заметная добавка к току модуля, который сам потребляет около миллиампера. Если устройство работает в комнате, вместо потенциометра подойдёт постоянный делитель напряжения: 10 кОм от VDD и 3,6 кОм на землю дают 1,32 В.
У модулей МЭЛТ свои правила: по документации MT-16S2H у 5-вольтовых исполнений вывод V0 соединяют с землёй (для регулировки — через переменный резистор 10 кОм), а у 3-вольтовых оставляют свободным.
Подсветка — светодиодная, и задавать нужно ток, а не напряжение: Winstar так и пишет, что напряжение в таблице приведено для справки. Разброс между модулями большой:
| Модуль | Подсветка | Ток | Напряжение |
|---|---|---|---|
| Winstar WH1602B-TMI-ET | белая | 32 мА (допустимо 10–40 мА) | 3,4–3,6 В |
| Winstar WH2004A-YGH-JT | жёлто-зелёная | 280 мА (252–336 мА) | 4,0–4,4 В |
| МЭЛТ MT-16S2H | янтарная, жёлто-зелёная, голубая, белая | 100 мА при питании подсветки от Ucc | — |
Ток задают резистором последовательно с выводом A. Для белой подсветки WH1602B от 5 В: R = (5 − 3,5) В / 32 мА ≈ 47 Ом, на резисторе рассеивается 1,5 В × 32 мА = 48 мВт. Посчитать для своего модуля поможет калькулятор резистора для светодиода. На плате многих модулей резистор подсветки уже стоит — у WH1602B на схеме подключения показан и внутренний резистор, и внешний. Если документации нет, включите подсветку через 47–100 Ом и измерьте ток. Яркость регулируют ШИМ через транзисторный ключ в цепи K: ток жёлто-зелёной подсветки в сотни миллиампер вывод микроконтроллера не выдержит.
Шина HD44780: регистры, RS, R/W и E
Внутри контроллера микроконтроллеру доступны только два регистра: регистр команд (IR) и регистр данных (DR). Какой из них участвует в обмене и в каком направлении, задают RS и R/W:
| RS | R/W | Операция |
|---|---|---|
| 0 | 0 | запись команды в IR |
| 0 | 1 | чтение флага занятости (D7) и счётчика адреса (D6–D0) |
| 1 | 0 | запись данных в DDRAM или CGRAM |
| 1 | 1 | чтение данных из DDRAM или CGRAM |
Обмен запускает сигнал E. При записи контроллер защёлкивает RS, R/W и данные по спаду E, поэтому всё должно быть выставлено заранее и удерживаться ещё немного после спада. При чтении контроллер выдаёт данные на шину, пока E в единице.
Времена по даташитам. При питании 2,7–4,5 В контроллер медленнее, и требования к сигналам у HD44780U строже:
| Параметр | Обозначение | HD44780U, 4,5–5,5 В | HD44780U, 2,7–4,5 В | ST7066U, 5 В |
|---|---|---|---|---|
| Период E | tcycE | ≥ 500 нс | ≥ 1000 нс | ≥ 1200 нс |
| Длительность импульса E | PWEH (у Sitronix — tPW) | ≥ 230 нс | ≥ 450 нс | ≥ 140 нс |
| Фронт и спад E | tEr, tEf | ≤ 20 нс | ≤ 25 нс | ≤ 25 нс |
| Установка RS, R/W до фронта E | tAS | ≥ 40 нс | ≥ 60 нс | ≥ 0 нс |
| Удержание RS, R/W после спада E | tAH | ≥ 10 нс | ≥ 20 нс | ≥ 10 нс |
| Установка данных до спада E | tDSW | ≥ 80 нс | ≥ 195 нс | ≥ 40 нс |
| Удержание данных после спада E | tH | ≥ 10 нс | ≥ 10 нс | ≥ 10 нс |
| Данные при чтении — после фронта E | tDDR | ≤ 160 нс | ≤ 360 нс | ≤ 100 нс |
Отличия совместимых контроллеров видны уже здесь: у ST7066U импульс E может быть короче, но период — не меньше 1,2 мкс. На практике это не мешает: у микроконтроллера на 16 МГц такт длится 62,5 нс, и паузы в 1 мкс между переключениями E с запасом закрывают требования любого из контроллеров. Библиотека LiquidCrystal так и делает: держит E в единице 1 мкс.
4-битный режим: два полубайта на байт
В 4-битном режиме используются только линии D4–D7, а каждый байт — команда, код символа или статус — передаётся двумя циклами шины: сначала старший полубайт на D7–D4, затем младший на тех же линиях. Контроллер выполняет команду только после второго полубайта, и флаг занятости проверяют тоже после него.
Именно здесь чаще всего ошибаются. Если перепутать порядок полубайтов, 0x48 превратится в 0x84; если перепутать провода D4–D7, биты внутри полубайта поменяются местами; если потерять один полубайт, контроллер будет склеивать байты со сдвигом до следующей инициализации.
Система команд HD44780
Команда — это байт, записанный при RS = 0 и R/W = 0. Её тип определяет старший установленный бит: 0x01 — Clear display, 0x02 — Return home, 0x04 и выше — Entry mode set и так далее до 0x80 — Set DDRAM address. Время выполнения — по таблице 6 даташита HD44780U при частоте генератора 270 кГц.
| Команда | RS | R/W | D7…D0 | Код | Время | Что делает |
|---|---|---|---|---|---|---|
| Clear display | 0 | 0 | 0000 0001 | 0x01 | не указано; у ST7066U и SPLC780D — 1,52 мс, у KS0066U — 1,53 мс | заполняет DDRAM пробелами (0x20), ставит адрес 0, отменяет сдвиг и включает I/D = 1 |
| Return home | 0 | 0 | 0000 001* | 0x02 | 1,52 мс | адрес 0 и отмена сдвига дисплея; содержимое DDRAM не меняется |
| Entry mode set | 0 | 0 | 0000 01 I/D S | 0x04–0x07 | 37 мкс | направление движения курсора и сдвиг дисплея при записи |
| Display on/off control | 0 | 0 | 0000 1 D C B | 0x08–0x0F | 37 мкс | дисплей, курсор-подчёркивание, мигание знакоместа |
| Cursor or display shift | 0 | 0 | 0001 S/C R/L * * | 0x10–0x1F | 37 мкс | сдвиг курсора или всего изображения без записи в DDRAM |
| Function set | 0 | 0 | 001 DL N F * * | 0x20–0x3F | 37 мкс | разрядность шины, число строк, размер символа |
| Set CGRAM address | 0 | 0 | 01 A5…A0 | 0x40–0x7F | 37 мкс | следующие данные пойдут в CGRAM по этому адресу |
| Set DDRAM address | 0 | 0 | 1 A6…A0 | 0x80–0xFF | 37 мкс | следующие данные пойдут в DDRAM по этому адресу |
| Read busy flag and address | 0 | 1 | BF A6…A0 | — | 0 мкс | флаг занятости и текущий адрес |
| Write data | 1 | 0 | D7…D0 | — | 37 мкс | запись кода символа или строки CGRAM |
| Read data | 1 | 1 | D7…D0 | — | 37 мкс | чтение DDRAM или CGRAM |
Звёздочка — бит, который не учитывается. Значения битов:
- I/D — 1: после записи адрес увеличивается и курсор идёт вправо, 0: уменьшается и курсор идёт влево.
- S — 1: при каждой записи сдвигается всё изображение, курсор остаётся на месте («бегущая строка»).
- D, C, B — дисплей включён, курсор-подчёркивание включён, знакоместо под курсором мигает. 0x0C — дисплей без курсора, 0x0E — с курсором, 0x0F — с курсором и миганием.
- S/C, R/L — сдвигать изображение (1) или курсор (0), вправо (1) или влево (0): 0x10 и 0x14 двигают курсор, 0x18 и 0x1C — изображение. При сдвиге обе строки движутся вместе, и вторая строка в первую не переходит.
- DL — 1: 8-битная шина, 0: 4-битная. N — 1: две строки (скважность 1/16), 0: одна. F — 1: символы 5 × 10, 0: 5 × 8; две строки с символами 5 × 10 невозможны.
Типовые коды для модуля 1602 на 4-битной шине — 0x28 (Function set: 4 бита, 2 строки, 5 × 8), 0x0C, 0x06 и 0x01. Function set дают один раз, в начале работы: по даташиту число строк и шрифт после инициализации менять нельзя.
Время выполнения зависит от генератора
37 мкс и 1,52 мс — это значения при частоте встроенного генератора 270 кГц, и Hitachi прямо пишет, что время меняется обратно пропорционально частоте: при 250 кГц те же 37 мкс превращаются в 37 × 270 / 250 = 40 мкс. А частота генератора с резистором 91 кОм у HD44780U при 5 В — от 190 до 350 кГц. В худшем случае команда выполняется 37 × 270 / 190 ≈ 53 мкс, а Return home — 1,52 × 270 / 190 ≈ 2,16 мс. У KS0066U запись данных длится 43 мкс при 270 кГц, то есть до 61 мкс на медленном генераторе. Если программа не опрашивает флаг занятости, паузы нужно брать с этим запасом: 70 мкс после обычных команд и данных, 2,2 мс после Clear display и Return home. Библиотека LiquidCrystal ждёт 100 мкс после каждого полубайта и 2 мс после clear() и home().
Адреса DDRAM: как адресуются строки
Видеопамять DDRAM — 80 байт, по одному на знакоместо. В двухстрочном режиме (N = 1) контроллер делит её на две строки по 40 символов: адреса 0x00–0x27 и 0x40–0x67. Модуль показывает только часть каждой строки: 1602 — первые 16 символов, 2004 — первые 20 и следующие 20 в других строках экрана. Чтобы написать что-то в нужном месте, дают команду Set DDRAM address: 0x80 плюс адрес.
| Модуль | Строка 1 | Строка 2 | Строка 3 | Строка 4 |
|---|---|---|---|---|
| 0802 | 0x00–0x07 | 0x40–0x47 | — | — |
| 1602 | 0x00–0x0F | 0x40–0x4F | — | — |
| 2002 | 0x00–0x13 | 0x40–0x53 | — | — |
| 4002 | 0x00–0x27 | 0x40–0x67 | — | — |
| 1604 | 0x00–0x0F | 0x40–0x4F | 0x10–0x1F | 0x50–0x5F |
| 2004 | 0x00–0x13 | 0x40–0x53 | 0x14–0x27 | 0x54–0x67 |
Четырёхстрочный модуль для контроллера — всё тот же двухстрочный: третья строка экрана — продолжение первой строки контроллера, четвёртая — второй. Так и считает библиотека LiquidCrystal: начала строк — 0x00, 0x40, 0x00 + число столбцов и 0x40 + число столбцов.
Отсюда два сюрприза. Текст, не поместившийся в первую строку модуля 2004, продолжается в третьей, а не во второй. А у модуля 1602 после 16-го символа текст уходит в невидимые адреса 0x10–0x27 и появится во второй строке экрана, только когда пройдёт 40-я позиция: по даташиту курсор переходит на вторую строку после 40-го знакоместа первой. Поэтому переход на новую строку всегда делают командой Set DDRAM address.
Особый случай — модули 16 × 1. Если такой модуль собран по схеме рисунка 20 даташита HD44780U (скважность 1/16), его правая половина — это вторая строка контроллера: знакоместа 1–8 имеют адреса 0x00–0x07, знакоместа 9–16 — 0x40–0x47, а инициализировать модуль нужно как двухстрочный (N = 1).
Инициализация HD44780 в 8- и 4-битном режиме
После включения питания HD44780U инициализируется сам: очищает экран и устанавливает 8-битную шину, одну строку, шрифт 5 × 8, выключенный дисплей и автоинкремент адреса. Флаг занятости держится 10 мс после того, как VCC достигло 4,5 В. Но встроенный сброс срабатывает, только если питание нарастает за 0,1–10 мс, а перед повторным включением было выключено не меньше 1 мс. При медленном нарастании, провалах питания или перезагрузке одного микроконтроллера (модуль при этом остаётся включённым) рассчитывать на него нельзя. Поэтому программа всегда инициализирует контроллер сама, по процедуре с рисунков 23 и 24 даташита.
Последовательность для 4-битной шины
| Шаг | RS | D7…D4 | Пауза после | Смысл |
|---|---|---|---|---|
| 0 | — | — | > 15 мс после того, как VCC достигло 4,5 В (> 40 мс после 2,7 В) | ждём окончания встроенного сброса |
| 1 | 0 | 0011 | > 4,1 мс | Function set, 8 бит |
| 2 | 0 | 0011 | > 100 мкс | Function set, 8 бит |
| 3 | 0 | 0011 | время выполнения | Function set, 8 бит |
| 4 | 0 | 0010 | время выполнения | Function set: переход на 4 бита (сама команда ещё 8-битная) |
| 5 | 0 | 0010, затем N F * * | время выполнения | Function set по 4-битной шине: 0x28 — 2 строки, 5 × 8 |
| 6 | 0 | 0000, затем 1000 | время выполнения | Display off, 0x08 |
| 7 | 0 | 0000, затем 0001 | время Clear display | Clear display, 0x01 |
| 8 | 0 | 0000, затем 01 I/D S | время выполнения | Entry mode set, обычно 0x06 |
Флаг занятости до третьего шага читать нельзя, после него — можно; если его не читать, паузы должны быть длиннее времени выполнения команд. Процедура заканчивается выключенным дисплеем, поэтому затем дают Display on/off control, например 0x0C. Для 8-битной шины порядок тот же, только на шаги 1–3 подают полные байты 0x30, а шагов 4 и 5 нет: сразу Function set 0x38.
Зачем три раза 0x3
Программа не знает, в каком состоянии контроллер: только что включён (8 бит), уже работает в 4-битном режиме или в 4-битном режиме ждёт второй половины байта, потому что микроконтроллер перезагрузился посреди передачи. Три полубайта 0011 приводят к одному результату в любом случае:
- 8-битный режим: каждый полубайт — полная команда Function set с DL = 1, затем 0010 переключает шину на 4 бита.
- 4-битный режим, ждёт старший полубайт: первые два 0011 образуют байт 0x33 — Function set с DL = 1, контроллер переходит на 8 бит, и дальше как в первом случае.
- 4-битный режим, ждёт младший полубайт: первый 0011 дописывает чужой байт, и результат непредсказуем — длинная пауза после этого полубайта перекрывает даже самые долгие команды; следующие два 0011 образуют 0x33 — и снова 8-битный режим.
Поэтому «укороченная» инициализация — один полубайт 0010 и сразу 0x28 — работает после включения питания, а после перезагрузки микроконтроллера, когда модуль уже в 4-битном режиме, даёт мусор.
Отличия совместимых контроллеров
| Контроллер | Производитель | Команды | Clear display | Return home | Пауза после включения | tcycE при 5 В | Порог единицы на входах при 5 В |
|---|---|---|---|---|---|---|---|
| HD44780U | Hitachi | 37 мкс | не указано | 1,52 мс | > 15 мс после 4,5 В | 500 нс | 2,2 В |
| KS0066U | Samsung | 39 мкс, чтение и запись данных — 43 мкс | 1,53 мс | 1,53 мс | > 30 мс после 4,5 В | 500 нс | 2,2 В |
| ST7066U | Sitronix | 37 мкс | 1,52 мс | 1,52 мс | > 40 мс после 4,5 В | 1200 нс | 0,7 · VCC = 3,5 В |
| SPLC780D | Sunplus | 38 мкс | 1,52 мс | 1,52 мс | > 15 мс после 4,5 В | 500 нс | 2,2 В |
| КБ1013ВГ6 (модули МЭЛТ) | «Ангстрем» | 40 мкс | 1,5 мс | 40 мкс | > 20 мс | 500 нс | 2,2 В |
Время выполнения у первых четырёх — при 270 кГц; данные КБ1013ВГ6 — из документации модуля МЭЛТ MT-16S2H. Samsung и Sitronix приводят в даташитах свои варианты 4-битной инициализации, без трёх команд 0011, но процедура Hitachi состоит только из обычных команд Function set и подходит для всех; её же выполняет LiquidCrystal: 50 мс, 0x3, 4,5 мс, 0x3, 4,5 мс, 0x3, 150 мкс, 0x2. У ST7066U есть ещё одно условие: первые 40 мс после включения питания линии интерфейса надо держать в нуле.
Флаг занятости или задержки
Пока контроллер выполняет команду, флаг занятости BF равен 1 и новые команды не принимаются. Прочитать его можно в любой момент: RS = 0, R/W = 1, флаг — на D7, на D6–D0 — счётчик адреса. В 4-битном режиме статус передаётся, как и всё остальное, двумя полубайтами: BF в старшем, но читать нужно оба, иначе контроллер потеряет счёт полубайтам.
Опрос флага быстрее: программа ждёт ровно столько, сколько нужно этому экземпляру контроллера при этой температуре, а не худший случай. Но для него нужен вывод R/W, переключение линий данных на вход и уверенность, что 5-вольтовые выходы модуля не повредят входы микроконтроллера. Задержки проще: R/W на землю, линии — только на выход, а цена — несколько десятков лишних микросекунд на команду. Для текстового экрана, который обновляется несколько раз в секунду, разница не важна.
Тонкости, о которых пишут производители:
- Счётчик адреса обновляется ещё tADD после того, как BF сбросился (4 мкс при 270 кГц у HD44780U): прочитанный сразу адрес может оказаться старым.
- Sitronix требует начинать опрос BF у ST7066U не раньше чем через 80 мкс после команды и не держать E постоянно в единице во время опроса.
- До третьего шага инициализации флаг занятости не проверяют.
Если R/W подключён к PB2, ожидание флага в 4-битном режиме для примера из следующего раздела выглядит так:
#define LCD_RW PB2
static uint8_t lcd_read4(void)
{
PORTB |= _BV(LCD_E);
_delay_us(1); /* tDDR: data valid 160 ns (360 ns at 3 V) after E rises */
uint8_t nibble = PIND >> 4; /* D4..D7 = PD4..PD7 */
PORTB &= ~_BV(LCD_E);
_delay_us(1);
return nibble;
}
static void lcd_wait_busy(void)
{
uint8_t status;
DDRD &= 0x0F; /* D4..D7 as inputs */
PORTB &= ~_BV(LCD_RS);
PORTB |= _BV(LCD_RW); /* RS = 0, R/W = 1: busy flag and address */
do {
status = (uint8_t)(lcd_read4() << 4); /* BF, AC6..AC4 */
status |= lcd_read4(); /* AC3..AC0: both nibbles must be read */
} while (status & 0x80);
PORTB &= ~_BV(LCD_RW);
DDRD |= 0xF0; /* D4..D7 back to outputs */
}
Пример на C для AVR: 4-битный режим без чтения
ATmega328P на 16 МГц, подключение как на схеме выше: D4–D7 — PD4–PD7, RS — PB0, E — PB1, R/W на земле. Паузы взяты с запасом на самый медленный генератор контроллера.
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#define LCD_RS PB0
#define LCD_E PB1
static void lcd_write4(uint8_t nibble) /* nibble in bits 3..0 */
{
PORTD = (uint8_t)((PORTD & 0x0F) | (nibble << 4)); /* D4..D7 = PD4..PD7 */
PORTB |= _BV(LCD_E); /* RS and data are already set: tAS, tDSW */
_delay_us(1); /* PW_EH >= 230 ns (450 ns at 3 V) */
PORTB &= ~_BV(LCD_E); /* the falling edge latches the nibble */
_delay_us(1); /* tH, tAH and the rest of tcycE */
}
static void lcd_write(uint8_t value, uint8_t rs)
{
if (rs) PORTB |= _BV(LCD_RS); else PORTB &= ~_BV(LCD_RS);
lcd_write4(value >> 4); /* high nibble first */
lcd_write4(value & 0x0F);
_delay_us(70); /* 37-43 us at 270 kHz, up to 61 us at 190 kHz */
}
void lcd_command(uint8_t cmd)
{
lcd_write(cmd, 0);
if (cmd <= 0x03) _delay_ms(2.2); /* Clear display, Return home */
}
void lcd_data(uint8_t data)
{
lcd_write(data, 1);
}
void lcd_init(void)
{
DDRD |= 0xF0;
DDRB |= _BV(LCD_RS) | _BV(LCD_E);
PORTB &= ~(_BV(LCD_RS) | _BV(LCD_E));
_delay_ms(50); /* > 40 ms after VCC reaches 2.7 V */
lcd_write4(0x3); /* Function set: 8-bit */
_delay_ms(4.5); /* > 4.1 ms */
lcd_write4(0x3);
_delay_us(150); /* > 100 us */
lcd_write4(0x3);
_delay_us(70);
lcd_write4(0x2); /* Function set: 4-bit (an 8-bit command) */
_delay_us(70);
lcd_command(0x28); /* 4-bit bus, 2 lines, 5x8 dots */
lcd_command(0x08); /* display off */
lcd_command(0x01); /* clear */
lcd_command(0x06); /* increment, no display shift */
lcd_command(0x0C); /* display on, cursor off */
}
void lcd_goto(uint8_t col, uint8_t row) /* 16x2 and 20x4; for 16x4 rows 3, 4 are 0x10, 0x50 */
{
static const uint8_t row_start[4] = { 0x00, 0x40, 0x14, 0x54 };
lcd_command((uint8_t)(0x80 | (row_start[row & 3] + col)));
}
void lcd_puts(const char *s)
{
while (*s) lcd_data((uint8_t)*s++);
}
void lcd_create_char(uint8_t n, const uint8_t rows[8])
{
lcd_command((uint8_t)(0x40 | ((n & 7) << 3))); /* Set CGRAM address */
for (uint8_t i = 0; i < 8; i++) lcd_data(rows[i]);
lcd_command(0x80); /* back to DDRAM */
}
int main(void)
{
static const uint8_t degree[8] = { 0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00 };
lcd_init();
lcd_create_char(1, degree);
lcd_goto(0, 0);
lcd_puts("HD44780, 4-bit");
lcd_goto(0, 1);
lcd_puts("T = 23.5\x01" "C"); /* split: "\x01C" would be one escape, 0x1C */
for (;;) {}
}
Две детали в последней строке. Свой символ записан в ячейку 1, а не 0: код 0 в строке C означает её конец. И строковый литерал разбит на два: шестнадцатеричная escape-последовательность в C захватывает все следующие шестнадцатеричные цифры, и "\x01C" превратилась бы в один байт 0x1C.
Arduino: LiquidCrystal и LiquidCrystal_I2C
В Arduino модуль подключают библиотекой LiquidCrystal. Конструктор с шестью аргументами — RS, E, D4–D7 — означает 4-битный режим без вывода R/W, его соединяют с землёй:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
void setup() {
lcd.begin(16, 2); // 4-bit initialization, 0x28, display on, clear
lcd.print("Hello, 1602");
}
void loop() {
lcd.setCursor(0, 1); // column 0, row 1: Set DDRAM address 0x40
lcd.print(millis() / 1000);
}
Внутри begin() — процедура Hitachi с паузами 50 мс, 4,5 мс, 4,5 мс и 150 мкс, а setCursor() складывает столбец с началом строки из таблицы 0x00, 0x40, 0x00 + столбцы, 0x40 + столбцы. Флаг занятости библиотека не читает, даже если указан вывод R/W: после каждого полубайта она ждёт 100 мкс, после clear() и home() — 2 мс.
Для модуля с I²C-переходником нужна библиотека LiquidCrystal_I2C; конструктор принимает адрес переходника и размер экрана:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x3F for a PCF8574A backpack
void setup() {
lcd.init(); // Wire.begin() and the same 4-bit initialization
lcd.backlight(); // P3 = 1
lcd.print("Hello, I2C");
}
void loop() {}
Ни одна из библиотек не меняет таблицу знакогенератора: lcd.print() отправляет в модуль байты строки как есть. Строка «Привет» в исходнике Arduino хранится в UTF-8, по два байта на букву, и на экране превратится в набор посторонних символов. Как выводить русский текст — в разделе о знакогенераторе.
Свои символы в CGRAM
В CGRAM помещается восемь своих символов 5 × 8 точек (или четыре 5 × 10). Символ — это 8 байт, по одному на строку точек сверху вниз. В каждом байте значимы пять младших битов: бит 4 — левая точка, бит 0 — правая, единица — точка светится; биты 7–5 не используются. Восьмая строка — строка курсора: курсор-подчёркивание рисуется поверх неё по логическому ИЛИ, поэтому, если курсор нужен, её оставляют пустой.
| Строка | Точки | Байт |
|---|---|---|
| 1 | ·████ | 0x0F |
| 2 | █···█ | 0x11 |
| 3 | █···█ | 0x11 |
| 4 | ·████ | 0x0F |
| 5 | ··█·█ | 0x05 |
| 6 | ·█··█ | 0x09 |
| 7 | █···█ | 0x11 |
| 8 | ····· | 0x00 |
Так выглядит буква «Я». Чтобы её загрузить, дают команду Set CGRAM address с адресом первой строки нужного символа — 0x40 + 8 × n для символа n от 0 до 7 — и записывают 8 байт как данные, при RS = 1. Затем обязательно возвращаются в DDRAM командой Set DDRAM address, иначе следующий текст тоже уйдёт в CGRAM. Библиотека LiquidCrystal делает то же в createChar() и обратно не переключается: после неё нужен setCursor() или clear().
Выводят свой символ кодом n или n + 8: бит 3 кода контроллер не учитывает. Это удобно в C, где код 0 завершает строку: вместо символа 0 можно печатать 8. Но так ведёт себя HD44780 и большинство аналогов; в знакогенераторе модулей МЭЛТ коды 0x08–0x0F заняты своими символами. В Arduino символ 0 выводят через lcd.write(byte(0)) — без приведения к byte вызов неоднозначен, об этом предупреждает и пример CustomCharacter из библиотеки.
CGRAM — это ОЗУ: после выключения питания символы пропадают, и загружать их нужно при каждой инициализации. Зато контроллер читает CGRAM при каждом обновлении экрана, и, если переписать символ, сразу изменятся все его копии на экране. На этом строят анимацию, индикаторы уровня и шкалы: например, пять символов со столбцами шириной от 1 до 5 точек дают полосу с шагом в одну точку.
Генератор символов CGRAM
Нарисуйте символ: щелчок по точке включает или выключает её, мышью можно провести по нескольким точкам сразу. Генератор покажет 8 байт и готовый код для Arduino или на C. В списке «Образец» — русские буквы, которых нет в японском знакогенераторе, и несколько значков; готовый массив можно вставить в поле ниже и отредактировать.
Исходные данные
Рисунок: щёлкните по точке или проведите по нескольким
Нижняя строка — строка курсора: курсор-подчёркивание рисуется поверх неё
русские буквы, которых нет в японском знакогенераторе, и несколько значков
8 чисел через запятую: 0x0E, 0b01110, B01110 или десятичные
Результат
- Код символа в тексте
- 0 или 8в строке C удобнее 8: код 0 её завершает
- Команда Set CGRAM address
- 0x40затем 8 байт данных, RS = 1
byte ya[8] = {
0b01111,
0b10001,
0b10001,
0b01111,
0b00101,
0b01001,
0b10001,
0b00000
};
// setup(), after lcd.begin() or lcd.init():
lcd.createChar(0, ya);
lcd.setCursor(0, 0); // back to DDRAM
lcd.write(byte(0));Знакогенератор, кириллица и русский текст
Шрифт контроллера зашит в знакогенератор CGROM при изготовлении кристалла, и его вариантов несколько. У HD44780U это 208 символов 5 × 8 и 32 символа 5 × 10; в таблице кодов первые 16 кодов отданы CGRAM, коды 0x20–0x7F — латиница, цифры и знаки почти как в ASCII, верхняя половина — национальные символы.
| Вариант | Где встречается | Что в верхней половине |
|---|---|---|
| Английский и японский | HD44780UA00, ST7066U-0A, Winstar с суффиксом JT | катакана, несколько греческих букв и знаков |
| Английский и европейский | HD44780UA02, ST7066U-0B и 0E, Winstar с суффиксом ET | буквы с диакритикой, греческие, у A02 — 18 заглавных русских |
| Английский и кириллица | Winstar с суффиксом CT, модули МЭЛТ (страница 0) | заглавные и строчные русские буквы, кроме похожих на латинские |
| Windows-1251 | модули МЭЛТ, страница 1 | русский алфавит в кодировке Windows-1251 |
В японском варианте A00 коды 0x20–0x7D совпадают с ASCII, кроме 0x5C — там знак иены ¥ вместо обратной косой черты; 0x7E и 0x7F — стрелки → и ←. Для приборов пригодятся 0xDF — знак градуса, 0xE4 — µ, 0xF4 — Ω, 0xF7 — π. В варианте A02 знак градуса — уже 0xB0. Узнать, какой знакогенератор в вашем модуле, проще всего опытом: выведите все коды от 0xA0 до 0xFF и посмотрите.
Кириллица в знакогенераторе
В вариантах с кириллицей — у Winstar это CT, «English and Cyrillic standard font», у модулей МЭЛТ — страница 0 — буквы стоят по одним и тем же кодам. Буквы, начертание которых совпадает с латинскими, отдельно не хранятся и берутся из ASCII: А, В, Е, К, М, Н, О, Р, С, Т, Х и строчные а, е, о, р, с, у, х.
| Буквы | Коды |
|---|---|
| Б Г Ё Ж З И Й Л П У Ф Ч Ш Ъ Ы Э | 0xA0–0xAF по порядку |
| Ю Я | 0xB0, 0xB1 |
| б в г ё ж з и й к л м н п т | 0xB2–0xBF по порядку |
| ч ш ъ ы ь э ю я | 0xC0–0xC7 по порядку |
| Д Ц Щ | 0xE0–0xE2 |
| д ф ц щ | 0xE3–0xE6 |
Слово «Привет» для такого модуля — это байты 0xA8, 'p', 0xB8, 0xB3, 'e', 0xBF: П, затем латинская p, и, в, латинская e и т. Компилятор сам не перекодирует, поэтому строку либо записывают байтами, либо перекодируют функцией по таблице:
static const uint8_t hello[] = { 0xA8, 'p', 0xB8, 0xB3, 'e', 0xBF, 0 }; /* "Привет" */
lcd_puts((const char *)hello);
В знакогенераторе A02 кириллица неполная: заглавные Б, Д, Ж, З, И, Й, Л, П, У, Ц, Ч, Ш, Щ, Ъ, Ы, Э занимают коды 0x80–0x8F, Ю и Я — 0xAC и 0xAD, а Г можно заменить греческой Γ с кодом 0x92. Строчных русских букв в A02 нет.
У модулей МЭЛТ на контроллере КБ1013ВГ6 две страницы знакогенератора, и переключает их бит P (D1) команды Function set: в 4-битном режиме с двумя строками 0x28 — страница 0, 0x2A — страница 1. Страница 1 устроена как кодировка Windows-1251: А–Я — 0xC0–0xDF, а–я — 0xE0–0xFF, Ё — 0xA8, ё — 0xB8. Строку, набранную в среде с кодировкой Windows-1251, такой модуль покажет без перекодирования; исходники Arduino сохраняются в UTF-8, и перекодировать всё равно придётся.
Если кириллицы в модуле нет
В самом распространённом японском варианте русских букв нет. Остаётся комбинировать: похожие буквы выводить латинскими, а недостающие — Б, Г, Д, Ж, З, И, Й, Л, П, У, Ф, Ц, Ч, Ш, Щ, Ъ, Ы, Ь, Э, Ю, Я — рисовать в CGRAM. Так работает, например, библиотека LCD_1602_RUS для Arduino: буквы, похожие на латинские, она берёт из английского набора, а остальные рисует в CGRAM.
I²C-модуль на PCF8574
Переходник I²C — плата с расширителем портов PCF8574 или PCF8574A, которая припаивается к 16-выводному разъёму модуля. Восемь выводов расширителя заменяют микроконтроллеру шину HD44780, и модуль подключается всего четырьмя проводами: питание, земля, SDA и SCL. Модуль при этом работает в 4-битном режиме, а сигнал E формирует программа, записывая в расширитель байт с установленным и сброшенным битом.
Назначение битов — по библиотеке LiquidCrystal_I2C; большинство переходников разведены так же:
| Вывод PCF8574 | Вывод модуля | Бит в байте |
|---|---|---|
| P0 | RS (4) | 0x01 |
| P1 | R/W (5) | 0x02 |
| P2 | E (6) | 0x04 |
| P3 | подсветка: ключ в цепи K (16) | 0x08 |
| P4–P7 | D4–D7 (11–14) | 0x10–0x80 |
Адрес. PCF8574 и PCF8574A отличаются только постоянной частью адреса. Младшие три бита задают выводы A2–A0, на переходниках — перемычки, которые обычно подтянуты к питанию, а запайка соединяет вывод с землёй:
| A2 A1 A0 | PCF8574 | PCF8574A |
|---|---|---|
| 0 0 0 | 0x20 | 0x38 |
| 0 0 1 | 0x21 | 0x39 |
| 0 1 0 | 0x22 | 0x3A |
| 0 1 1 | 0x23 | 0x3B |
| 1 0 0 | 0x24 | 0x3C |
| 1 0 1 | 0x25 | 0x3D |
| 1 1 0 | 0x26 | 0x3E |
| 1 1 1 | 0x27 | 0x3F |
Адреса семибитные, как их ожидает библиотека Wire; если в описании переходника указано 0x4E, это тот же 0x27, сдвинутый на разряд, — подробности в статье о шине I²C. Там же — скетч сканера шины, который найдёт адрес, если надпись на микросхеме не читается.
Скорость. PCF8574 рассчитан на Standard-mode — до 100 кГц. LiquidCrystal_I2C на каждый полубайт делает три записи в расширитель: данные, E = 1 и E = 0. Каждая запись — START, адрес, байт и STOP, около 20 тактов SCL, то есть 0,2 мс на 100 кГц. Символ из двух полубайтов занимает около 1,3 мс вместе с паузами библиотеки, строка из 16 символов — около 21 мс. Для текстового экрана этого достаточно, но перерисовывать весь экран в каждом проходе loop() не стоит.
Подсветка и контраст. Бит P3 включает подсветку через транзисторный ключ — поэтому в библиотеке подсветка включена, когда бит равен 1: сам выход PCF8574 в единице отдаёт лишь около 100 мкА. Анод подсветки обычно подключён к питанию через перемычку на плате: сняв её, подсветку отключают совсем. Подстроечный резистор контраста стоит на самом переходнике, и его, как правило, приходится подстраивать под конкретный модуль.
Подтяжки. На переходнике обычно стоят свои подтягивающие резисторы SDA и SCL к его питанию. Если на шине несколько модулей со своими подтяжками, они складываются параллельно — как это посчитать, разобрано в статье об I²C.
Модули на 3,3 и 5 В
Сам контроллер работает от 2,7 до 5,5 В, а ограничение — в жидкокристаллической панели: 5-вольтовому модулю нужно 3,6–4,6 В между VDD и V0, при морозе — ещё больше. При питании 3,3 В и V0 на земле на панель приходится только 3,3 В, и изображение получается бледным или не видно совсем. Выходов два:
- Модуль, рассчитанный на 3 В. У таких исполнений есть преобразователь, который делает нужное напряжение для панели; у Winstar на структурной схеме он обозначен как необязательный генератор отрицательного напряжения, у МЭЛТ 3-вольтовые исполнения работают от 2,7–3,6 В, а вывод V0 оставляют свободным.
- Отрицательное напряжение на V0. Если модуль 5-вольтовый, а питания 5 В нет, на V0 подают напряжение ниже нуля от отдельного источника.
Чаще встречается другая задача: модуль на 5 В, микроконтроллер на 3,3 В. Тогда всё решает порог единицы на входах модуля. У HD44780U, KS0066U, SPLC780D и КБ1013ВГ6 при питании 4,5–5,5 В это 2,2 В, и выходы 3,3 В его проходят с запасом. У ST7066U порог — 0,7 · VCC, то есть 3,5 В при 5 В, и 3,3 В формально не хватает; Winstar для своих модулей на ST7066U указывает тот же порог. Читать флаг занятости в такой схеме нельзя без согласования уровней: при чтении модуль выдаёт на линии данных уровень своего питания, до 5 В. Самый простой вариант — R/W на землю и задержки вместо опроса.
С I²C-переходником на 5 В ситуация та же: порог единицы PCF8574 — 0,7 · VDD, то есть 3,5 В, а подтяжки переходника поднимают SDA и SCL до 5 В — на входы 3,3-вольтового микроконтроллера, которые могут быть на это не рассчитаны. Надёжное решение — двунаправленный преобразователь уровней на MOSFET, схема — в статье о шине I²C.
Типичные ошибки и отладка
| Симптом | Вероятная причина | Что проверить |
|---|---|---|
| Верхняя строка — ряд закрашенных прямоугольников, нижняя пустая | контроллер не инициализирован: после включения он сам переходит в однострочный режим | RS и E, порядок D4–D7, паузы, процедуру инициализации |
| Подсветка горит, символов не видно | неверное напряжение на V0 | подстроечник контраста; у модулей Winstar при VDD = 5 В на V0 0,4–1,4 В |
| Мусор после перезагрузки микроконтроллера, после выключения питания всё нормально | 4-битный режим сбился на полубайт | полная процедура с тремя 0011 при каждом старте |
| Вместо букв посторонние символы | перепутан порядок полубайтов или линий D4–D7 | старший полубайт — первым, D4–D7 подключены по порядку |
| После 16-го символа текст пропадает; на 2004 продолжается через строку | так устроена DDRAM | переход на новую строку — командой Set DDRAM address |
| Свой символ не появился, следующий текст тоже пропал | после записи в CGRAM адрес остался в CGRAM | Set DDRAM address или setCursor() после createChar() |
| Пропадает первый символ после очистки экрана | не выдержано время Clear display | не меньше 2,2 мс или опрос флага занятости |
| I²C-модуль не отвечает | другой адрес, перемычки A0–A2, нет подтяжек или общего провода | сканер шины I²C, адреса 0x20–0x27 и 0x38–0x3F |
| Экран мерцает при обновлении | clear() в каждом проходе цикла | перезаписывать изменившиеся знакоместа, остаток строки — пробелами |
| Случайные символы при работе мотора или реле | помеха на линии E: каждый её спад — запись | короткие провода, общий провод рядом с сигнальными, развязка питания |
Порядок отладки «с нуля»:
- Питание и контраст без микроконтроллера. Подайте VDD и землю, подключите подстроечник. Верхняя строка из закрашенных знакомест при повороте движка означает, что панель, контроллер и контраст в порядке. Напряжение на V0 относительно VSS у модуля WH1602B при комнатной температуре — около 1,3 В.
- Линии управления. Логическим анализатором или осциллографом проверьте, что на E есть импульсы, а при командах RS = 0.
- Инициализация. Первыми должны пройти три полубайта 0011, затем 0010, и только потом 0x28 двумя полубайтами, со старшего.
- Вывод и адреса. Выведите строку из 16 разных символов и проверьте, на месте ли каждый: перепутанные линии данных видны сразу.
Другие интерфейсы и модули — в разделах «Интерфейсы» и «ЖК-дисплеи», архитектура микроконтроллеров из примеров — в разделе AVR.
Частые вопросы
Как подключить LCD 1602 к Arduino?
В 4-битном режиме хватает шести выводов: RS, E и D4–D7. R/W соединяют с землёй, D0–D3 оставляют свободными. VSS — на землю, VDD — на +5 В, на V0 — движок потенциометра 10–20 кОм, включённого между питанием и землёй. Подсветку (выводы 15 и 16) подключают через резистор, если его нет на плате модуля. В скетче — библиотека LiquidCrystal: LiquidCrystal lcd(12, 11, 5, 4, 3, 2) и lcd.begin(16, 2).
Какой адрес у I2C-модуля LCD 1602?
Зависит от микросхемы на переходнике и перемычек A0–A2. У PCF8574 адреса 0x20–0x27, у PCF8574A — 0x38–0x3F. Без запаянных перемычек выводы A0–A2 подтянуты к питанию, и адрес равен 0x27 или 0x3F соответственно. Если не подходит ни один, запустите сканер шины I2C: он покажет адрес, на который переходник отвечает.
Почему на LCD 1602 светятся только прямоугольники в верхней строке?
Питание и контраст в порядке, а инициализация не прошла. После включения контроллер сам переходит в однострочный режим, и при достаточном контрасте верхняя строка выглядит как ряд закрашенных знакомест. Проверьте подключение RS и E, порядок линий D4–D7, паузы и последовательность инициализации: три команды 0x3, затем 0x2.
Как вывести русские буквы на LCD 1602?
Сначала узнайте, какой знакогенератор в модуле. Если в нём есть кириллица (модули Winstar с суффиксом CT, модули МЭЛТ), русские буквы лежат в верхней половине таблицы, и текст нужно перекодировать: например, «П» — 0xA8, «и» — 0xB8. В модулях с японским знакогенератором кириллицы нет: похожие на латиницу буквы выводят латинскими, остальные рисуют в CGRAM — не больше восьми разных одновременно.
Можно ли питать LCD 1602 от 3,3 В?
Контроллер работает от 2,7 В, но жидкокристаллической панели 5-вольтового модуля нужно 3,6–4,6 В между VDD и V0, и от 3,3 В изображение будет бледным или не появится совсем. Берите модуль, рассчитанный на 3 В, или подайте на V0 отрицательное напряжение. 5-вольтовый модуль можно оставить на 5 В и управлять им с 3,3-вольтового микроконтроллера в режиме только записи, если порог его входов это допускает.
Источники
- Hitachi. HD44780U (LCD-II) Dot Matrix Liquid Crystal Display Controller/Driver, ADE-207-272(Z), Rev. 0.0, 1999 — табл. 1 — регистры, табл. 4 — знакогенераторы A00 и A02, табл. 5 — CGRAM, табл. 6 — команды и время выполнения, рис. 23 и 24 — инициализация, AC и DC Characteristics — шина и уровни
- Sitronix. ST7066U Dot Matrix LCD Controller/Driver, V2.2, 2006 — время команд, инициализация, Power Supply Conditions (tPOR, tIOL), AC и DC Characteristics, варианты знакогенератора 0A, 0B, 0E
- Samsung. KS0066U 16COM/40SEG Driver & Controller for Dot Matrix LCD — табл. 7 — команды и время выполнения, инициализация, табл. 10 и 12 — DC и AC характеристики
- Sunplus. SPLC780D 16COM/40SEG Controller/Driver, Preliminary, Version 0.1, 2003 — п. 5.3 — команды, п. 5.7 — инициализация, п. 6 — электрические характеристики
- Winstar Display. WH1602B-TMI-ET# Specification, ver. J, 2017 — назначение выводов, напряжение VDD − V0, схема регулировки контраста, подсветка
- Winstar Display. WH2004A-YGH-JT# Specification — адреса DDRAM модуля 20×4, VDD − V0, жёлто-зелёная подсветка
- Winstar Display. WH2004A-TMI-CT# Specification — суффикс CT — English and Cyrillic standard font, контроллер ST7066U, таблица знакогенератора
- МЭЛТ. Жидкокристаллический индикатор MT-16S2H, версия документа 1.2, 2019 — контроллер КБ1013ВГ6, табл. 1 и 2 — характеристики, табл. 4 — команды и бит P, табл. 5 и 6 — страницы знакогенератора
- NXP Semiconductors. PCF8574; PCF8574A: Remote 8-bit I/O expander for I2C-bus with interrupt, Rev. 5, 2013 — табл. 4 и 5 — адреса, интерфейс 100 кГц, квазидвунаправленные выводы, уровни входов
- Arduino. Библиотека LiquidCrystal — LiquidCrystal.cpp: begin(), setRowOffsets(), createChar(), задержки; пример CustomCharacter
- Библиотека LiquidCrystal_I2C (YWROBOT, на основе кода DFRobot) — назначение битов порта PCF8574, init(), задержки
- Библиотека LCD_1602_RUS — русские буквы в модулях без кириллицы через CGRAM
- Atmel. ATmega328/P Datasheet Complete, Atmel-42735B, 11/2016 — порты ввода-вывода для примера на C