В этой статье приведен пример подключения LCD индикатора к микроконтроллеру AVR, а именно ATmega8. При выборе LCD cледует различать обычные многопозиционные LCD серии ИЖКЦ, модули на их основе с микросхемой HT1611 и алфавитно-символьные LCD с встроенным контроллером. Именно последние и относят к наиболее перспективным изделиям. В подтверждение тому множество фирм в мире, специализирующихся на выпуске подобной продукции. Крупнейшие из них находятся в Тайване, Китае, Японии, США.
Среди параметров, отличающих одни LCD от других, выделяется марка внутреннего контроллера. В дальнейшем будут рассматриваться только модели, совместимые с контроллером HD44780 (фирма Hitachi) и его аналогами, например, KS0066 (фирма Samsung), SED1278
(фирма Epson), ST7066 (фирма Sitronix). Таких изделий на отечественном рынке подавляющее большинство, да и в любительских конструкциях они стали стандартом "де-факто".
При покупке LCD надо поинтересоваться следующими моментами:
поддерживается ли система команд HD44780 ("Да");
имеется ли русификация знакогенератора с выводом больших и малых букв ("Да");
однополярное или двухполярное требуется питание ("Однополярное +5 В");
имеется ли подсветка (если "Да", то нужна светодиодная, а не электролюминесцентная);
сколько символов и строк отображается на экране LCD ("8x1",
"8x2", "16x1", "16x2", "20x2", "20x4" и т.д.).
Внутреннее устройство LCD
Достоинством символьных многострочных LCD является то, что заботу о подаче требуемых напряжений на массив "ЖК-конденсаторов" берет на себя встроенный управляющий контроллер. На рис.1 показана структурная схема типового LCD с организацией 16х2, которая идентична для всех моделей независимо от фирмы-изготовителя. Основу составляет специализированный контроллер, обычно выполненный в виде одной или двух микросхем-"капелек", реже - в виде фирменной SMD-микросхемы. По назначению выводов и системе команд он совпадает с родоначальником серии - HD44780. Общепринятое название таких микросхем "Dot Matrix Liquid Crystal Display Controller/Driver", из чего следует их двойная функция - контроллер управляет интерфейсом, а драйвер "зажигает" сегменты.
Контроллер синхронизируется внутренним RC-генератором G1, имеющим частоту 250 ±50 кГц. Напряжение подсветки подается через выводы А и К на светодиоды, которые освещают ЖК-панель с торца или обратной стороны корпуса. Светодиоды включены матрицей и соединены параллельно-последовательно. В связи с этим напряжение подсветки довольно высокое 4,0...4,2 В.
Назначение и нумерация всех внешних выводов LCD унифицированы (рис.2). Это не зависит от количества строк и символов, будь то "8x1" или "16x2". Даже контакты светодиодной подсветки 15, 16 имеются на всех LCD, хотя при ее физическом отсутствии они будут просто "висеть в воздухе".
Небольшой нюанс. На печатной плате LCD порядок нумерации контактных площадок отличается от модели к модели. Например, встречаются следующие варианты: слева направо 1-16, справа налево 16-1, вперемежку 15, 16, 1-14. Подсказку следует искать визуально по отмаркированным цифрам на печатной плате. Контакты 15, 16 обычно дублируются еще одной парой контактов с маркировкой А и К соответственно. Электрически они соединены параллельно.
Конструктивно выводы могут располагаться сверху, снизу или на боковой стороне платы LCD. Это не суть важно, ведь соединяться с изделием они будут жгутом проводов длиной до 10 см. Крепление LCD производится винтами через 4 угловых отверстия.
Электрический интерфейс состоит из трех шин:
DB0-DB7 шина данных;
RS, R/W, E шина управления;
VCC, GND, Vo, A, K шина питания.
Внимание: перед подключением питания VCC и GND внимательно прочитайте описание на Ваш дисплей, т.к. контакты питания у некоторых дисплеев могут различаться.
Типовая схема подключения LCD к МК показана на рис.3. Именно она и будет использоваться для первой тестовой проверки LCD с выведением на экран знаменитой фразы "Hello, world!" ("Здравствуй, мир!"). Кнопка SB1 осуществляет начальный сброс. Переменным резистором R2 регулируют контрастность изображения. Его сопротивление непринципиально и может меняться от 5 до 20 кОм.
Рис. 3
Кстати, резистор R2 является первым элементом, который надо обязательно покрутить в разные стороны при начальном включении питания. Если LCD исправен, то в крайних положениях движка будут наблюдаться полное гашение и полная засветка экрана.
Отрегулировать R2 следует на перегибе характеристики, как правило, с потенциалом ближе к общему проводу, когда слабо видны все точки знакомест на LCD. Неправильная установка контрастности может привести к ложному выводу о дефекте индикатора, хотя все, что надо сделать, это покрутить движок резистора.
Управляющая программа хранится в МК DD1. Чтобы облегчить ее составление, здесь и в дальнейшем приняты некоторые упрощения.
Во-первых, LCD будет работать только на прием информации по всем 11 соединительным линиям шины данных и управления.
Во-вторых, экран LCD считается жестко привязанным к начальной позиции с фиксированными адресами знакомест.
В-третьих, при программировании будет использоваться ограниченный набор команд (желающие смогут в последствие расширить свои познания, изучив DATASHEET на HD44780.
Программное управление LCD
Поскольку внутри LCD находится свой собственный контроллер со своей разветвленной системой команд, то задача упрощается. Две такие мощные и интеллектуальные микросхемы, как HD44780 и ATmega8, смогут быстро между собой "договориться" на машинном языке. Труд программиста заключается в том, чтобы "объяснить" контроллерам правила общения и установить протокол соединения.
Таблица 3
В таблице (см. выше) показана расшифровка наиболее употребляемых команд, посылаемых от МК в LCD, а на рис.4 - показаны команды для перехода на определенное знакоместо верхней или нижней строки экрана. Время выполнения команд указано приблизительно. Оно определяется частотой внутреннего RC-генератора LCD, которая, в свою очередь, зависит от технологического разброса и температуры нагрева корпуса.
Рисунок 4
Различают команды прямого и косвенного действия. Первые из них занимают адреса 0x01-0x3F и не требуют передачи данных. За вторыми (диапазон выше 0x3F) обязательно следует передача одного или нескольких байтов информации. Для примера на рис.5 показаны временные диаграммы выполнения команды 0x80 "Установка курсора в первое знакоместо верхней строки экрана" и индикация в нем цифры "4" пересылкой кода данных 0x34.
Рисунок 5
Формировать диаграммы, показанные на рис.5, должен МК с учетом задержек из табл.3, необходимых контроллеру LCD на выполнение команд. Для повышения устойчивости работы экономить на задержках не надо. По крайней мере, при отладке программы они должны быть достаточно большими.
Каждое знакоместо на экране LCD имеет свой логический адрес. Представить его можно в виде регистра, куда заносится один байт информации. В зависимости от содержимого байта на экране появляется тот или иной символ. Распределение символов соответствует таблице знакогенератора, похожей на применяемые в шрифтах компьютера.
Далее показана Си-программа для тестовой проверки LCD по схеме, собранной на рис.3.
// Тестовая программа для LCD, шина 8 бит #include <avr/io.h> #include <util/delay.h> #define RS PC0 // RS подключаем к PC0 микроконтроллера #define EN PC2 // EN подключаем к PC2 микроконтроллера // Функция записи команды в LCD void lcd_com(unsigned char p) { PORTC &= ~(1 << RS); // RS = 0 PORTC |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD = p; // Вывод команды на шину DB0-7 LCD _delay_us(100); // Длительность сигнала EN PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); // Пауза для выполнения команды } // Функция записи данных в LCD void lcd_dat(unsigned char p) { PORTC |= (1 << RS)|(1 << EN); // RS = 1, EN = 1 (начало записи команды в LCD) PORTD = p; // Вывод команды на шину DB0-7 LCD _delay_us(100); // Длительность сигнала EN PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); // Пауза для выполнения команды } // Функция инициализации LCD void lcd_init(void) { DDRC |= (1 << PC2)|(1 << PC1)|(1 << PC0); // PC2-0 выходы PORTC = 0x00; // Лог. нули на выходе DDRD = 0xFF; // PD7-0 выходы PORTD = 0x00; // Лог. нули на выходе lcd_com(0x08); // Полное выключение дисплея lcd_com(0x38); // 8 бит 2 строки _delay_us(100); lcd_com(0x38); // 8 бит 2 строки _delay_us(100); lcd_com(0x38); // 8 бит 2 строки lcd_com(0x01); // Очистка дисплея _delay_us(100); lcd_com(0x06); // Сдвиг курсора вправо _delay_ms(10); lcd_com(0x0C); // Курсор невидим } // Основная программа int main (void) { lcd_init(); // Инициализация дисплея lcd_dat('H'); // Выводим символы на экран lcd_dat('e'); lcd_dat('l'); lcd_dat('l'); lcd_dat('o'); lcd_dat(' '); lcd_dat('w'); lcd_dat('o'); lcd_dat('r'); lcd_dat('l'); lcd_dat('d'); lcd_dat('!'); while(1) { // Больше ничего не делаем } }
Функции "lcd_com" и "lcd_dat" формируют соответственно левую и правую половину временных диаграмм, показанных на рис.5.
Без процедуры инициализации ни один LCD работать не будет. Это самая важная часть листинга. Именно на процессе инициализации часто "спотыкаются" начинающие программисты. Дело в том, что в разных источниках приводятся разные варианты последовательностей команд инициализации и не все из них гарантированно будут работать с конкретным LCD.
Наиболее общая процедура инициализации приведена в DATASHEET на HD44780. Функция "lcd_init" в целом повторяет ее с тем отличием, что команда полного выключения дисплея 0х08 поставлена первой, чтобы при включении питания на экране не появлялся "мусор". Здесь нет ограничений против экспериментов, главный критерий - практика.
После выполнения инициализации курсор устанавливается в крайнее слева положение в верхней строчке экрана. Следовательно, первая буква "H" будет выведена именно в это знакоместо. Далее курсор автоматически переходит на одну позицию вправо и следующая команда выведет сюда букву "e" и т.д.
Комментарии
Здравствуйте, не должен, важно чтобы он стоял первым в главном цикле - main