Урок 12
Часть 1
LCD индикатор 16×2
Сегодня мы начнём изучение жидкокристаллического индикатора символьного, который способен выводить определённые символы в две строки по 16 символов в каждую. Изучать мы данный индикатор будем с целью его подключения к микроконтроллеру AVR и управления им.
Выглядит индикатор, с которым мы будем работать вот таким вот образом
То есть индикатор выполнен в виде модуля, в котором установлен контроллер HD44780, предназначенный для управления дисплеем. Также, как мы видим, в данном модуле существуют 16 контактов, которые я припаял самостоятельно и к которым мы и будем подсоединяться с контроллера с помощью проводов. Поставляется данный модуль без контактов. На их месте существуют контактные технологические отверстия. Скорее всего, сделано это для того, чтобы мы сами могли выбрать тип контактов, которые нам будут удобны для работы с данным модулем.
Вроде и кажется, что 16 контактов — это много, но на самом деле не так уж и много. За счет контроллера HD44780, установленного в модуле, нам не придется подводить по 8 и более контактов к каждому из 32 символов, этим как раз и займётся данный контроллер. Мы лишь только будем давать ему определённые команды и посылать определённые данные. Хотя это также сопряжено с определёнными трудностями программирования данного устройства, но на это и существует урок, чтобы данные трудности как-то преодолеть.
Также следует отметить, что типов таких модулей существует несколько и распиновка контактов может незначительно отличаться. Поэтому я и показываю в приемлемом качестве именно тот дисплей, который будем исользовать мы во избежание путаницы из за неправильного подключения, а в последствии и выхода из строя дисплея. Данные случаи уже имели место, нам этого совершенно не нужно.
Например, модуль компании Winstar на 1 ножке имеет анод, а наш китайский дисплей, который стоит дешевле, в отличие от Winstar, на данной ножке имеет катод.
Поэтому будьте внимательны и читайте документацию на тот именно модуль, который будет у вас.
Иногда ножки подключения индикаторов нумеруются на плате, как, например в том модуле, который мы будем сегодня использовать
Ну раз уж мы увидели надписи на ножках модуля, давайте тогда разберёмся, какая ножка для чего служит. Пойдём слева направо.
Ножка первая — VSS — это общий провод или «земля»
2 — VDD — питание.
3 — V0 — это ножка, с помощью которой регулируется контрастность дисплея. То есть контрастность дисплея будет зависеть от поданного напряжения на данную ножку. Как правило берётся переменный резистор на 10 килоом, подключенный крайними ножками на общий провод и на питание, а с центральной ножки данного резистора провод идёт как раз на ножку V0 и посредством регулировки движка резистора мы и регулируем контрастность дисплея в модуле.
4 — RS — это такая хитрая ножка, с помощью которой контроллер дисплея будет «знать», какие именно данные находятся на шине данных. Если мы подадим на данную ножку логический 0, то значит будет команда, если 1 — то это данные.
5 — RW — данная ножка в зависимости от логического состояния на ней говорит контроллеру дисплея, будем мы с него читать или будем мы в него писать данные. Если будет 0 — то мы в контроллер дисплея будем писать, а если 1 — то будем читать данные из контроллера дисплея. Данная функция используется редко. Как правило мы всегда только пишем данные в дисплей. Чтение обычно требуется для того, чтобы определить, что дисплей принял наши данные, либо чтобы определить состояние. Но существуют определённые тайминги, позволяющие нам на слово «верить» котнроллеру дисплея, что он наши данные принял и обработал. Также читать мы можем из памяти дисплея, что, в принципе, незачем. Поэтому мы обычно соединяем данный контакт с общим проводом.
6 — E — это так называемая стробирующая шина, по спадающему фронту (когда 1 меняется в 0) на которой контроллер дисплея понимает, что именно сейчас наступил момент чтения данных на ножках данных D0 — D7, либо передачи данных из модуля в зависимости также от состояния ножки RW.
Ножки D0 — D7 — это параллельная восьмибитная шина данных, через которую и передаются или принимаются данные. Номера 0 — 7 соответствуют одноименным битам в байте данных. Но также есть ещё 4-битный способ передачи данных в контроллер и из контроллера дисплея, когда используются только ножки данных D4 — D7, а ножки D0 — D3 уже не используются. Как правило такой способ используется в целях экономии ножек порта и именно такой способ мы и будем сегодня использовать, так как мы теряем скорость вдвое, но у нас дисплей символьный и спешить нам некуда. В 4-битном режиме мы передаём или принимаем байт в 2 приёма по половинке, сначала старшую часть байта, затем младшую.
Ножки A и K — это анод и катод для подачи напряжения для питания светодиодной подсветки дисплея. Как правило можно питать от 5 вольт, но желательно поставить токоограничивающий резистор на 100 ом и скорее всего тогда подсветка дисплея «проживёт» дольше. Всё это обычно указывается в технической документации на дисплей.
Также данную информацию мы видим в технической документации на дисплей
Теперь немного ознакомимся, каким образом мы будем организовывать процесс общения с дисплеем. То есть каким образом мы будем этим процессом управлять. Ведь контроллер дисплея не «знает» что именно мы от него хотим. Для этого в даташите существует вот такая таблица, представляющая собой перечень команд и способы их реализации
В самой первой колонке данной таблице находятся сами команды. Следующие 2 колонки — это то, в каком состоянии должны в момент команды находиться ножки RS и RW. Дальнейшие 8 колонок показывают нам состояние ножек шины данных, затем идёт колонка с пояснениями к командам, то есть что именно с помощью данной команды мы достигнем. А затем в последней колонке находятся тайминги или временные интервалы, необходимые для того, чтобы та или иная команда или инструкция выполнилась. Причем оговорено, при какой именно частоте генератора это достигается. То есть, я так понимаю, что в модуле существует генератор, тактирующий работу контроллера дисплея, который настроен на определённую частоту и данная частота может быть разной. Поэтому желательно пробовать сначала с большим интервалом, то есть всё достигается на практике. Поэтому некоторые модули других моделей могут не работать с тем же кодом, который мы в данном уроке напишем. Опять же читайте внимательно техническую документацию именно к своему модулю.
Например, первая команда Clear Display говорит сама за себя. Она очищает дисплей. Вообще за отображение на дисплее у нас отвечает оперативная память DDRAM, также существующая в контрроллере дисплея. Вот данную память как раз и очищает данная команда.
Остальных команд мы коснёмся несколько позднее.
Теперь идём дальше по технической документации. Дальше идёт объяснение каждой команды и назначение каждого бита, представленного в таблице. Мы можем заметить, что в таблице каждый используемый бит как-то называется.
Дальше идёт объяснение процесса инициализации модуля дисплея. Инициализация любого активного устройства — это неотъемлимая часть программирования. Без первичной инициализации не будет работать ни одно устройство.
Сначала показана инициализация 8-битного режима, а затем 4-битного режима. Нам интересен именно последний способ. Поэтому посмотрим данную страничку
Мы видим, что всё здесь очень подробно рассказано и показано. Вот эту диаграмму мы и будем использовать, когда будем писать код инициализации дисплея. Опять же требование — 270 кГц частота работы генератора.
Также посмотрим организацию знакомест дисплея в памяти DDRAM. Это нам будет необходимо для написания функции позиционирования
Как мы видим, вторая строка находится в области видиопамяти через некоторый пропуск после первой. Во-первых, существуют дисплеи разной размерности, например у меня ещё есть дисплей 20х4 на том же контроллере, поэтому и пропуск. Также существует определённая команда, которая передвигает видимую часть памяти, это может быть использовано для подготовки символов в невидимой области, а затем путём передвижения невидимую область мы делаем видимой. Нам это пока не требуется. Если потребуется, то мы обязательно с этим разберёмся, ну либо для какого-то красивого скроллинга дисплея также может это потребоваться.
Подобная документация существует также не только на дисплей, а ещё и на контроллер. Я её также в конце статьи обязательно приложу к страничке.
А теперь наконец-то проект.
В отличие от предыдущих занятий сегодня у нас будет пустой проект. Обычно мы продолжали начатый и копировали код с прошлого занятия. Сегодня мы этим заниматься не будем и создадим пустой проект Test09. Создадим мы его таким же образом, как и все предыдущие, выбрав тот же контроллер, поэтому процедуру создания и настройки я показывать не буду. У нас и так урок обещает быть очень большим.
Для протеуса проект мы скопируем как и раньше, переименовав его в Test09, и выбрав путь к прошивке нового проекта, чтобы нам заново не искать контроллер, резисторы и прочие вещи, а также не настраивать контроллер.
Вернемся в наш проект в студию. Верхнюю часть файла, где мы объявляем частоту и подключаем библиотеки, мы, в принципе можем всё-таки их прошлого кода скопировать
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
Скомпилируем код, чтобы у нас была хотя бы какая-то прошивка.
Напишем функцию port_ini(). Под все ножки модуля дисплея мы будем использовать порт D. Так как режим у нас 4-битный, то нам вполне хватит ножек, даже останутся
//—————————————-
void port_ini(void)
{
PORTD=0x00;
DDRD=0xFF;
}
//—————————————-
Также давайте данную функцию вызовем в функции main()
int main(void)
{
port_ini(); //Инициализируем порты
Зайдём теперь в проект в протеус и найдем там дисплей в библиотеке компонентов
Подключим его следующим образом
Если мы запустим проект, то мы увидим всего лишь, что дисплей у нас просо будет светиться и всё.
Дальнейшую работу с данным дисплеем мы продолжим в следующей части.
Предыдущий урок Программирование МК AVR Следующая часть
Техническая документация на дисплей
Техническая документация на контроллер дисплея HD44780
Программатор и дисплей можно приобрести здесь:
Программатор USBASP USBISP с адаптером USBASP USBISP 3.3 с адаптером
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Классно, очень информативно. Спасибо!
Спасибо!
Думаю, что чересчур информативно. Надо будет впоследствии разбить на части, как следующий урок по ШИМ. Будет проще читать, а то слишком длинно.
Всё прекрасно изложено, не нужно разбивать на части. Открыл страничку и всё по порядку, мысль не теряется. Если чего то недопонял — крутнул колёсиком назад и прочитал ещё раз. Даже я, который никогда не изучал СИ, подсел на Ваши уроки. Нигде в Тырнете не видел таких подробных уроков. Спасибо!
И Вам спасибо за оценку!
Но разбивать всё же надо даже с точки зрения оптимизации.
Допустимо ли называть свои библиотеки так же как и Атмеловские? Можно же запутаться какую подключил — свою или тулчайновскую.
Конечно допустимо! Ничего в этом страшного. Называть можно как заблагорассудится. Вы можете назвать по другому. Atmel никак не регистрировал права на имена библиотек.
Спасибо за уроки!
НО, пожалуйста!, объясните КАК вы делаете сплошную черту в комментариях!??!?!?!
КАК!?!?
Конечно есть Alt+0151, но это явно не то… 🙁
всем КУ! люди добрые подскажите можно ли подключить два lcd1602 К ОДНОМУ МИКРОКОНТРОЛЛЕРУ таким подключением как в этом уроке. чтобы два LCD1602 выводили разную информацию. привязка только к AVR(atmega8,atmega16, и так далее). спасибо за уроки! и спасибо всем кто подскажет по моему вопросу. всем БЛАГ и УДАЧИ!
А в чём проблема-то? Никто не мешает сколько угодно дисплеев подключать к любому мк, лишь бы ножек хватило. Кроме того, в данном случае можно попробовать ножки сильно сэкономить — соответствующие ножки дисплеев запараллеливаем все, кроме одной — EN. Вот ей и дёргаем на нужном дисплее. Дисплей, на котором EN не дергают, просто проигнорирует команду (данные)
спс за помощь!
Всем привет! Спасибо за хорошо и понятно изложенную здесь информацию! Но остался один вопрос по схеме приведенной из даташита. В схеме инициализации после 100 мкс идет однострочная таблица (000011), а сразу после нее без каких-либо временных задержек идет 8-ми строковая таблица, которая и завершает процесс инициализации. Так вот мне непонятно каким образом пользоваться этой таблицей (из 8 строк) на практике? Нужно выбрать одну строку из 8 или перебрать все 8 строк без временных задержек?
Лучше поздно чем никогда. Надо внимательно присмотреться к таблице 11. Display control instructions.