Работаем с LCD дисплеем на основе микроконтроллера — HD44780 (ч.1)

 

lcd_HD44780

 

ЖК дисплей на основе микроконтроллера HD44780 является наиболее часто используемым в электроники. Вы можете его встретить в кофейных автоматах, часах, копирах, принтерах, роутерах и т.п. Также данный дисплей используется в LCD шилдах для Arduino.

ЖК дисплей представляет из себя модуль, состоящий из микроконтроллера HD44780 разработанный фирмой Hitachi и непосредственно самим ЖК дисплеем. Микроконтроллер принимает команды и обрисовывает соответствующие символы на ЖК дисплее.

 

Существует огромное количество разновидностей данного ЖК модуля, он может быть 1,2, 4 –ех строчный с различным числом символов на строке, с подсветкой или без, с различным цветом подсветки и т.п. Объединяет их всех наличие микроконтроллера HD44780, зная команды которого позволит нам без проблем использовать в своих проектах ту или иную модификацию.

 

Предисловие

 

Для работы с дисплеями на основе HD44780 создано большое количество библиотек как на ассемблере так и на СИ, также для Arduino существует своя библиотека «LiquidCrystal».

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

 

Где взять первоисточник информации?

Если вы захотите сами разобраться как работать с LCD дисплеем на HD44780 и вникнуть глубже, то в этом вам поможет даташит на микроконтроллер HD44780, которые легко найти в интернете (но если вам лень, вы можете скачать с сайта).

 

Изучение я разобью на два этапа

1. Сначалая я приведу матчасть по работе с LCD на HD44780, этому посвящён данный пост

2. Далее, в следующем посте, я буду использовать модель дисплея LMO16L в Proteus. (LMO16L это один из типичный дисплеев на HD44780)

  • на данном этапе я отработаю протокол взаимодействия с дисплеем используя PATTERN GENERATOR.
  • после того, как отработаю протокол, я напишу прошивку для Arduino, попробую её на той же модели LMO16L и испытаю на реальном Arduino с подключенным LCD шилдом. Если дисплей будет работать также как и на модели, можно считать что мы умеем работать с ЖК дисплеем.
  • для закрепления, я напишу прошивку на ассемблере для Atmega8 и испробую её на LMO16L

 

 

В данном посте я расскажу:

P.S. разделы кликабельны, при нажатие вы спускаетесь к соответствующему разделу

 

 

Как подключить дисплей?

 

Все дисплеи на основе HD44780 имеет схожую распиновку

config_HD44780

Где

  • GND – земля (иногда пишут Vss)
  • Vcc – напряжение питания +5В (иногда пишут Vdd)
  • Vo – напряжение контрастности от 0В до +5В, данный вывод надо подключить к потенциометру, для регулировки
  • RS –вывод с помощью которого, дисплей определяет что в него поступает данные или команды
  • RW – вывод с помощью которого, дисплей определяет передавать или получать данные
  • E – линия синхронизации
  • D0D7 – шина команд/данных
  • LED + , LED — – выводы для питания подсветки

 

Дисплей может работать в 2-ух режимах:

  • в 8-и разрядном (т.е. когда, для обмена информацией используются контакты от D0 до D7),  данные пересылаются за один такт
  •  в 4-ех разрядном (для обмена используются только контакты D4 – D7),  в этом случае данные пересылаются за 2-а такта, сначала старшие 4-е бита, потом младшие 4-е бита.

 

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

 

circuit_HD44780

 

В качестве примера я показал подключение дисплея к ATmega8, хотя, можно использовать любой другой микроконтроллер. Выводы D4-D7, RS, E подключаются к любому цифровому порту микроконтроллера. Вывод RW мы использовать не будем, т.к. нам нет практической нужды принимать данные из ЖК (это обычная практика), наша задача — только передавать. По этому, свободные выводы RW, D0 – D3 посадим на землю.

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

 

 

Как происходит обмен информаций с ЖК?

 

Мы будем говорить о 4-ех разрядном режиме ЖК, поэтому для работы нам потребуется минимум 6 линий микроконтроллера.

Итак общение с ЖК происходит с помощью управляющих выводов:

RS – логическая единица ЖК принимает данные, логический ноль ЖК принимает команды;

С помощью линий данных:

D4 – D7 — разряды идут от младшего к старшему

И с помощью вывода стобирующих импульсов:

E

ЖК принимает информацию с помощью D4-D7, которая может быть данными (ASCII код выводимого символа)  если на RS логическая единица или командой (очистить экран, перенести курсор и т.п.) если на RS логический ноль. О том, какие бывают команды я расскажу позже, сейчас сконцентрируем внимание на физическом уровне взаимодействия.

Обмен информацией происходит по байтно, т.к. мы говорим 4-ех разрядном режиме, то микроконтроллер выставляет на D4-D7 логические единицы и логические нули, которые соответствуют старшему передаваемому полубайту, далее на E формируется стробирующий импульс, по заднем фронту которого ЖК считывает данные.

Далее микроконтроллер заново выставляет на D4-D7 логические единицы и логические нули, которые соответствуют младшему передаваемому полубайту и опять на E формируется стробирующий импульс, по заднем фронту которого ЖК считывает данные. После некоторой временной паузы (зависит от команды) цикл передачи байта данных или команды повторяется, ничего сложного.

time_data_HD44780

 

Если работать в 8-и разрядном режиме, то будут задействованы D0 – D7 и данные/команды будут передаваться за один такт, а не за два.

time_data_HD44780_2

 

 

Какие бывают команды?

 

Команды ЖК на HD44780 можно разделить на две группы:

  • команды настройки и записи в ЖК (9 команд)
  • команды чтения из ЖК (2-е команды)

 

Т.к. мы не будем считывать с ЖК (вывод RW посадили на ноль), то, я рассмотрю команды для настройки и записи, которые для удобства я свел в таблицу и пронумеровал, весь список вы можете посмотреть в даташите на странице 191.

table_command_HD44780

 

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

 

По порядку разберем, какая память есть в HD44780 и как работают команды…

Микроконтроллер HD44780 содержит следующую память:

  1. DDRAM;
  2. CGROM;
  3. CGRAM.

 

1.  В DDRAM памяти содержится ASCII коды символов которые в данный момент отображаются на экране, еще её называют видеопамять. Для 16-и символьных 2-ух строчных дисплеев её размер составляет 80 байт, т.е. по 40 байт на каждую строку. Каждый символ занимает 1 байт. У вас может возникнуть вопрос, почему 40 байт, ведь символов на строке 16? Дело в том, что на дисплеи отображается только часть DDRAM, с 0х80 по 0х8F включительно для 1-ой строки и с 0хС0 по 0хСF включительно для 2-ой строки, остальную часть не видно.

DDRAM_HD44780

 

Перенести черту видимости вправо или влево, можно с помощью команды №5. Для этого, нужно выставить S/C=1 и R/L в зависимости от направления, если вправо —R/L=1, если влево — R/L=0. Таким образом мы можем передвигать видимую часть по DDRAM, ширина её все равно останется равным 16-и символам для 1-й строки и 16-и символам для 2-й строки.

С помощью команды №5 передвигая видимую часть DDRAM, мы получаем эффект бегущей строки, например команда №5 была послана ЖК модулю 7 раз:

 

left_display_lcd

 

В дисплеи есть так называемый счетчик адреса или курсор, который начинает считать с 0x80 (в экране это левый верхний угол), при записи нового символа в DDRAM счетчик инкрементируется или декрементируется.

Помимо этого, с помощью команды №5 можно перемещать сам курсор, если выставить S/C=0 и R/L в зависимости от направления, если вправо —R/L=1, если влево — R/L=0.

 

Команда №1 служит для очистки памяти DDRAM, следовательно, всех текущих отображающихся символов и  установки курсора в начальное положение, т.е. в верхний левый угол дисплея.

 

Команда №2 не очищает DDRAM, а только устанавливает курсор в начальное положение, т.е. в верхний левый угол дисплея.

 

Дисплей по умолчанию не знает, в какую сторону сдвигать курсор при записи, для этого существует команда №3. Если бит ID=1, то курсор после записи символа сдвигается вправо (инкрементируется), если ID=0 (декрементируется), то влево.

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

 

usual_lcd_HD44780

 

Пусть курсор также установлен в начальное положение (в левый верхний угол), но ID=0 – курсор смещается при записи влево, буква за буквой выводиться справа налево, то, мы получим следующее:

 

no_usual_lcd_HD44780

 

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

Установив бит S=1 в этой-же команде, вы разрешаете сдвигать экран при записи символов. Если курсор инкрементируется (т.е. пишем слева на право), то экран будет сдвигаться влево. Если пишем справа налево, то экран будет сдвигаться вправо. Запутались? =)

Например, если мы установим курсор в правый нижний угол (команда №5), далее в команде №3 установим ID=1 (пишем слева направо) и S=1 (разрешаем сдвигать экран при записи), то при записи s-engineer.ru мы получим следующий результат.

 

no_usual_lcd_HD44780_2

 

Текст выводился слева на право (как обычно) и сдвигался влево.

 

С помощью команды №4 мы можем включать и отключать отображение DDRAM памяти на дисплеи. Установив бит D=0, дисплей прекращает отображать символы, но в памяти DDRAM они остаются, при D=1 дисплей отображает содержимое DDRAM.

 

lcd_display_off_on

 

Бит С позволяет отобразить курсор, если С=1, то курсор в виде символа “_”, если С=0 курсор не виден.

 

cursor_on_HD44780

 

Если установить бит В=1, то курсор будет мигать, если В=0 курсор не мигает.

 

gif_blink_cursor

 

Команда №6 используется при инициализации ЖК, если бит DL=1, то, дисплей использует с DB0 по DB7, а при DL=0, только 4-е вывода шины, т.е. с DB5 по DB7.

Бит N указывает сколько строк мы будем использовать (N=1 две строки, N=0 одну строку).

Разряд F позволяет указать размер шрифта, обычно используется 5х7 при F=1, но можно использовать и 5х10 при F=0 используя только одну строку (обычно, данный функционал не работает).

 

С помощью команды №8 можно указать в какую ячейку DDRAM мы будем записывать ASCII код символа. Она похожа на команду №5, т.к. в ней мы тоже управляем перемещением курсора, но только уже по адресам. Командой №8, мы можем использовать для своих нужд часть памяти DDRAM, которая не отображается на дисплеи.

 

Команда №9 переставляет собой просто данные. С её помощью производится запись ASCII кода символа в DDRAM память для его отображения на ЖК дисплеи. Для 4-ех разрядного режима, запись производится в два такта, сначала старший полубайт, потом младший полубайт.

Например, пошлем код 0x53, что соответствует знаку ‘S’.

 

one_char_HD44780

 

2. В памяти CGROM храниться «битовое изображение» выводимых символов. См. таблицу ниже

 

table_char_HD44780

 

Т.е. когда мы посылаем в DDRAM код 0x53, микроконтроллер HD44780 ищет ячейку 0x53 в CGROM и отрисовывает символ в соответствие с 1-и и 0-и данной ячейки.

(не всегда микроконтроллер содержит в CGROM кириллицу, там могут быть латинские или японские символы)

 

3. Память  CGRAM является частью CGROM. Главное её свойство заключается в том, что мы можем записывать в неё свои символы. Для этого нужно воспользоваться командой №7, в которой мы указываем адрес ячейки и далее командой №9 отправить 8 байт под ряд с «битовым изображением символа»

 

bit_image

 

Я решил создать символ состоящий из ‘s e’ по вертикали.

Далее, мы можем вывести данный символ, используя команду №9 зная его адрес ячейки.

 

new_image_HD44780

 

 

Как инициализировать дисплей на HD44780?

 

Т.к. ЖК дисплей содержит микроконтроллер, следовательно его необходимо проинициализировать, т.е. привести в рабочее состояние.

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

Я вывел для себя универсальную последовательность команд для инициализации, я проверил её на модели ЖК дисплея LM016L в Proteus и на реальном ЖК дисплеи WH1602B (LCD шилд для Arduino).

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

(картинка кликабельна)

initsilization_HD44780

Вы могли заметить, что для первой команды 0x30 не нужно выдавать младший полубайт, это потому, что, дисплей сразу принимает данные в 8и битном режиме, а т.к. DB0-DB4 у нас посажены на ноль, мы не можем ими управлять, да это и не нужно.

 

Если кратко, то инициализация это последовательность команд

  1. Команда №6 — 0x30 – установить режим 8 бит
  2. Команда №6 — 0x28 – установить режим 4 бита
  3. Команда №4 — 0x08 – выключить дисплей
  4. Команда №1 — 0x01–  сброс дисплея
  5. Команда №3 — 0x06–  при записи, курсор сдвигать вправо
  6. Команда №4 — 0x0C – включить дисплей

Вторая, практическая часть




Буду признателен если вы поделитесь данным постом

Комментарии
  1. Иван пишет:

    Супер, всё разложено по полочкам. Спасибо.

  2. admin пишет:

    Спасибо вам!

    Буду не против если кликните рекламку или сделайте пожертвование =)



Ваш комментарий


Ответ в цифрах

 
© s-engineer.ru, 2012-2017 | Все права защищены