Работа с символьным ЖКИ на базе контроллера HD44780. STM32 и LCD. Работа с графическим дисплеем Библиотека для работы с жки

По просьбе трудящихся, да и моим обещаниям решил я описать работу с знаковым ЖК 16х2 в среде CodeVisionAVR. Начнем с описания самого ЖК. Алфовитно-цифровой ЖК дисплей со встроенным чипом HD44780 фирмы Hitachi может выводить символы в одну, две или четыре сроки по 8, 16, 20 или 40 символов в каждой. В данной статье я буду рассматривать ЖК 16х2 (16 символов, 2 строки) . Данный дисплей для физического подключения к МК имеет 16 выводов (расположение выводов зависит от фирмы изготовителя) . Давайте посмотрим на эти выводы. Не мудрствуя лукаво я спер табличку в МЭЛТе. В принципе она подходит для любого ЖК.
Ну я думаю что объяснять не нужно для чего нужен тот или иной пин. Там все написано по русски. Но есть несколько небольших но. 1) ЖК дисплеи могут быть выпущены в двух вариантах на 5 вольт, либо на 3,3. 2) В цепи питания не всегда установлен токоограничивающий резистор. Смотрите внимательно, может стоять просто перемычка. (Я так спалил подсветку на двух дисплеях.) 3) Схема включения резистора для регулировки контрастности.
Так, ну теперь как сие чудо подключить к МК. Работать будем с ATmega8 и кварцем на 4 МГц. Вот собственно и схема.
Как видите ничего сложного нет. Первые три разряда порта D служат для управления, а последние четыре для данных. Также можно работать с этими дисплеями по 8-и битной шине, но я думаю отдавать лишние 4 ноги это расточительство. Поэтому будем работать по 4-х битной шине. Со схемой разобрались, теперь давайте с программной частью. Для инициализации дисплея и перевод его в 4-х битный режим нужно выполнить несколько команд. Но перед этим я хочу разъяснить как работают управляющие биты. Бит RS отвечает за то что будет принимать ЖК. Если RS = 0 , то мы передаем команду, а если 1 то данные. Если бит RW = 0 , то мы записываем в ЖК, а если 1 , то читаем. Бит Е просто строб. То есть как только мы захотим ввести команду или данные, то после того как выставили все биты на ножках просто выставляем в 1 бит Е , а потом опять роняем в 0 . 1 - Включить питание 2 - Выдержать паузу не менее 20 мс 3 - Команда для 4-х бит. шины 4 - Выдержать паузу не менее 40 мкс 5 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=1) 6 - Выдержать паузу не менее 40 мкс 7 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=1) 8 - Выдержать паузу не менее 40 мкс 9 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) 10 - Выдержать паузу не менее 40 мкс 11 - Выставить параметры (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) (RS=0), (RW=0), (D7=1), (D6=0), (D5=0),(D4=0) 12 - Выключаем дисплей (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) 13 - Очищаем экран (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=1) 14 - Режим ввода данных (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=1), (D5=1),(D4=0) О как. Теперь после этой абракадабры наш дисплей готов принимать данные. Что дальше. А дальше давайте ка рассмотрим команды ЖК. Для передачи команд/данных в ЖК по 4-х битной шине требуется два захода. Первым передаем старшие 4 байта, а вторым передаем младшие 4 байта. Дальше все команды я буду писать парами. Команда очистки индикатора и постановка курсора в левый верхний угол. RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=0, D6=0, D7=1 (E=1 потом 0) Команда перемещения курсора в левую позицию. (Х-значит пофик какое значение) RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=0, D6=1, D7=Х (E=1 потом 0) Команда устанавливает направление сдвига курсора(ID=0/1 влево/вправо). Так же разрешение сдвига дисплея (SH=1) при записи в DDRAM. RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=1, D6=ID, D7=SH (E=1 потом 0) Команда включения дисплея (D=1) и выбора курсора (A, B). A=0, B=0 Курсора нет, ничего не мигает A=0, B=1 Курсора нет, мигает весь символ A=1, B=0 Курсор в виде подчеркивания, не мигает A=1, B=1 Курсор в виде подчеркивания и мигает RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=1, D5=D, D6=A, D7=B (E=1 потом 0) Команда сдвига дисплея/курсора(SC=0/1 курсор/дисплей RL=0/1 влево/вправо). RS=0, RW=0, D4=0, D5=0, D6=0, D7=1 (E=1 потом 0) RS=0, RW=0, D4=SC, D5=RL, D6=X, D7=X (E=1 потом 0) Команда установки разрядности шины(DL=0/1 4/8 бит) А так же страници знакогенератора Р. RS=0, RW=0, D4=0, D5=0, D6=1, D7=DL (E=1 потом 0) RS=0, RW=0, D4=1, D5=0, D6=Р, D7=0 (E=1 потом 0) Команда установки адреса следующей операции с установкой туда курсора и выбора области CGRAM(Свои придуманные символы). RS=0, RW=0, D4=0, D5=1, D6=ACG, D7=ACG (E=1 потом 0) RS=0, RW=0, D4=ACG, D5=ACG, D6=ACG, D7=ACG (E=1 потом 0) Команда установки адреса последующей операции и выбор области памяти DDRAM (Знакогенератор). RS=0, RW=0, D4=0, D5=1, D6=ADD, D7=ADD (E=1 потом 0) RS=0, RW=0, D4=ADD, D5=ADD, D6=ADD, D7=ADD (E=1 потом 0) Команда Записи данных в текущую область. RS=1, RW=0, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) RS=1, RW=0, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) Команда Чтения данных в текущую область. RS=1, RW=1, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) RS=1, RW=1, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) Вот собственно и все команды. Есть еще команда чтения флага занятости, но я ей не пользуюсь, а просто выдерживаю между каждой командой не менее 40 мкс. Вот и все. А теперь после прочтения этого трактата, выпейте чашку чая или кофе и забудьте про все это. Так как всю эту муру на себя берут функции из библиотеки CodeVisionAVR. Создаем новый проект как это было уже рассказано. Для тех кто не в курсе идем сюда , остальные заходят в код-генераторе на вкладку LCD и выбирают PORTD . Что мы этим сделали. Первое мы сказали программе что хотим работать с ЖК дисплеем (выбрав вкладку LCD ). Потом мы сказали что подключим его к порту D . Ниже выпадающий список дает возможность выбрать количество символов в строке. Так как по умолчанию стоит 16 , а мы хотим работать с ЖК 16х2, то ничего менять не надо. Ниже для подсказки расписаны ножки порта для правильного подключения ЖК к МК. Все, сохраняем проект и смотрим на свеже-сгенерированный код. Первое на что надо обратить внимание - это на кусок кода после директивы препроцессора #include Вот на этот: // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include > Давайте его разберем построчно. Первая строка комментарий в котором говорится о том что мы подключили заголовочный файл с функциями для работы со знаковым ЖК. Второй строкой мы открываем блок для ввода ассемблерных команд. Следующая строка присваивает порт к которому подключен ЖК. Команда .equ в ассемблере делает тоже самое что команда #include в C. Если вы случайно в генераторе кода выбрали не тот порт, то его можно всегда поменять в этой строке. Номер порта всегда можно узнать в файле инициализации МК. Он всегда подключается в самой первой строке. В нашем случае это mega8.h . Следующая строка закрывает блок ассемблерного кода. И последняя строка как раз и подключает все необходимое для работы с ЖК. Теперь давайте пробежимся по основным функциям. Первая функция которую необходимо вызвать до того как вы начали мучать ЖК - это конечно же функция инициализации дисплея. Выглядит она так: void lcd_init(unsigned char lcd_columns) Данная функция инициализирует дисплей, а передаваемым параметром должно быть количества символов в строке. Мотаем нашу программу в самый низ и перед основным циклом видим две строки следующего содержания: // LCD module initialization lcd_init(16); Вот те самые 16 строк которые были выбраны в списке код-генератора программа и запихнула аргументом в функцию. Здесь также если вы с перепугу забыли что у вас ЖК 8 или 20 символов на строку, то просто поменяйте значение аргумента в этой функции. void lcd_gotoxy(unsigned char x, unsigned char y) Эта функция, судя из ее названия, переводит курсор в позицию x, y . Здесь x - это буковка. Слева направо от 0 до 15/19/39 (зависит от количества букв в строке) . А y - это строка. Сверху вниз от 0 до 0/1/3 (зависит от количества строк) . void lcd_putchar(char c) Эта функция выводит один символ в текущую позицию. Пример: lcd_putchar("A") или lcd_putchar(0x41) что на выходе даст один и тот же результат. То есть параметр может быть как символ, так и его код. lcd_gotoxy(0,0); lcd_putchar("A"); lcd_gotoxy(0,1); lcd_putchar(0x41); Я думаю комментарии здесь излишне, давайте посмотрим на результат.
Следующая функция. void lcd_puts(char *str) Эта функция выводит строку расположенную в SRAM начиная с текущей позиции. Пример: lcd_gotoxy(0,0); lcd_puts("СТРОКА"); Видим:
Следующая функция. void lcd_putsf(char *str) Эта функция выводит строку расположенную во FLASH начиная с текущей позиции. Пример: lcd_gotoxy(0,0); lcd_putsf("СТРОКА"); Видим:
Ну и замыкает все это безобразие функция "Ластик" void lcd_clesr(void) Вызвав данную функцию вы сотрете все что есть на дисплее, а курсор встанет в крайнее левое положение верхней строки. Вот так для начала можно выводить слова и цифры на ЖК дисплей при помощи готовых функций. Теперь давайте поговорим о том как выводить значение переменных. Для этих целей нам понадобится еще одна библиотека. Ну те кто программировал на С под ПК про нее должны знать. Называется она stdio.h Поднимаемся на самый верх программы и после директивы препроцессора #include добовляем #include В итоге наш код примет вид. // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include #include Теперь давайте познакомимся с функцией, которая занимается форматированием текста. void printf(char flash *fmtstr [,arg1, arg2, ...]) Как она работает. В char flash *fmtstr задается формат выводимого значения, а в аргументы arg1, arg2, ... имя переменной. Пример. unsigned char temp = 123; printf("temp = %05d\n", temp); Что означает эта абра-кадабра. Первая строка создает переменную и присваевает ей значение. Тут все понятно, а вот что делает вторая. Все по порядку. Сначала выводится запись temp = , затем 00123 . Почему выводится 00123 . А потому что у нас есть условие %05d\n которое говорит: 1) % - будем форматировать значения первого аргумента 2) 0 - будем выводить n знаков, пустые забьем нулями 3) 5 - выводим 5 знаков, если число меньше 5 знаков, то заполнить пустышки нулями. Об этом говорит пункт 2. Число будет выровнено по правому краю. 4) d - выводим число в десятичном формате. 5) \n - Заставит после вывода символа перейти на другую строку. Следующая функция. void sprintf(char flash, char flash *fmtstr [,arg1, arg2, ...]) Вот эта функция нам наиболее интересна. Она форматирует строку и записывает ее в массив. После мы можем смело массив вывести на экран. Как она работает. unsigned char temp = 123; unsigned char string; sprintf(string, "temp = %05d\n", temp); lcd_puts(string); Вот как это выглядит в живую.
Вот мы и научились выводить форматированный текст на ЖК. Далее кратко пробегусь по типам преобразования. i d - Для вывода десятичной целой со знаком u - Для вывода десятичной целой без знака e -d.d e-d E - Для вывода вещественного с плавающей точкой вида -d.d E-d f - Для вывода вещественного с плавающей точкой вида -d.d x - Для вывода в шеснадцатеричном виде маленькими буквами X - Для вывода в шеснадцатеричном виде большими буквами c - Для вывода в символа Если написать %-05d то знак "-" заставит выравнивать по левому краю, а пустышки нулями забиваться не будут. Если вы попытаетесь напечатать число с плавающей точкой, то сильно удивитесь. Число не напечатается. Во засада)) Проблема кроется в настройках компилятора. Для того чтобы компилятор начал понимать формат float нужно его немного настроить. Для этого заходим Project->Configure и заходим во вкладку C Compiler . В своистве (s)printf Features: выбираем float, width, precision . Вот и все. Пробуйте, экспериментируйте. Возникнут вопросы, пишите на форуме. Удачи!

Читатель нашего блога Михаил (mishadesh ) создал отличную библиотеку для работы с LCD и предложил написать статью для демонстрации ее возможностей. Собственно, сегодня именно об этом и пойдет речь 😉 Разберем, какие реализованы функции, а также в конце статьи будет выложен пример для работы с дисплеем.

Как обычно начнем с обсуждения железа… А тут на самом деле и не о чем говорить. Как и в первой статье, посвященной работе с дисплеями (), мы будем использовать отладочную плату Mini STM32 . Собственно, подключение дисплея, основные команды для записи данных, последовательность инструкций для инициализации – все это там есть =) Поэтому сейчас переходим сразу к обсуждению библиотеки для работы с графическими дисплеями.

Вот полный список функций с пояснениями:

Следующая функция, как видно из ее названия, меняет ориентацию экрана. Возможно два положения экрана, соответственно два возможных значения параметра orientation :

  • Orientation_Portrait
  • Orientation_Album

Функция отрисовывает на графическом дисплее символ, располагая его по переданным в функцию координатам, а также задавая его цвет. Начертание символа соответствует шрифту, определенному в файле font.c (файл идет в составе библиотеки).

Из функции LCD_DrawChar() плавно вытекает следующая функция:

void LCD_DrawString(char * s, uint16_t x, uint16_t y, uint16_t color, uint16_t backColor, uint8_t isTransparent) ;

Тут понятно и без лишних слов 😉 Функция печатает на LCD строку текста. Базой для этой функции является предыдущая – LCD_DrawChar() .

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

void LCD_drawLine ( int x1, int y1, int x2, int y2, uint16_t color) ; void LCD_DrawRect ( int x1, int y1, int x2, int y2, uint16_t color, uint8_t filled ) ; void LCD_DrawEllipse(uint16_t X1, uint16_t Y1, uint16_t R, uint16_t color) ;

Для рисования линии нужно передать в функцию координаты начальной точки, координаты конечной точки, а также нужный цвет. Для прямоугольника – координаты верхнего левого угла и координаты правого нижнего угла (!). Последний параметр filled – определяет, необходимо ли выполнять заливку фигуры. Единица – значит да, фигура будет закрашена выбранным цветом, ноль – будет нарисован только контур фигуры. С этим понятно) Осталась только окружность – функция DrawEllipse() . Здесь вместо координат начала и конца (верхнего/нижнего углов) передаем в качестве аргументов центр окружности и радиус.

Ну и напоследок еще одна функция:

void LCD_FillScr(uint16_t color) ;

Функция позволяет залить экран сплошным цветом.

Все перечисленные функции реализованы в файле GUI_DRV.c .

Помимо них библиотека включает в себя функции для записи данных в дисплей (LCD_DRIVER.c ) а также уже упомянутые шрифты (font.c ). Как видите, все четко отсортировано по разным файлам, так что в принципе все очень понятно, поэтому давайте перейдем к практическому примеру!

Давайте разбираться! Идем в файл main.c … Не буду приводить полный код функций инициализации периферии и дисплея, все это можно посмотреть непосредственно в файле, либо в предыдущей статье, ссылка на которую была в начале этой статьи 😉 Функция main() :

int main(void ) { initPeriph() ; initFSMC() ; initLCD() ; delay(10000 ) ; LCD_FillScr(0xFFFF ) ; delay(100 ) ; LCD_SetOrient(Orientation_Album) ; delay(100 ) ; LCD_DrawString("Библиотека для LGDP4532" , 30 , 30 , 0x888F , 0x0000 , 0 ) ; LCD_DrawRect(100 , 100 , 200 , 200 , 0x0000 , 0 ) ; LCD_DrawRect(120 , 120 , 180 , 180 , 0xFF00 , 1 ) ; LCD_DrawEllipse(150 , 150 , 50 , 0xF000 ) ; while (1 ) { } }

Начинаем с инициализации, закрашиваем экран белым цветом и устанавливаем альбомную ориентацию экрана. И теперь переходим к отрисовке графики)

Выводим на экран строку, а также два прямоугольника и круг. Результат налицо:

Очевидно, что все работает отлично 😉

Итак, на этом на сегодня заканчиваем, огромное спасибо Михаилу за проделанную работу и приведенные материалы. Вот контакты автора библиотеки:

Skype – mishadesh

Mail – [email protected]

На этом все, спасибо за внимание, до скорых встреч!

Общие сведения

На отладочной плате STM32L-Discovery установлен жидкокристаллический индикатор (ЖКИ, англ. LCD. Liquid crystal display), имеющий шесть 14 сегментных знаков, 4 знака двоеточия (Colon), 4 точки (DP), 4 полоски (Bar). Все сегменты объединены в группы СOM0, COM1, COM2, COM3 по 24 сегмента. Каждая группа имеет свой отдельный «общий провод».


На отладочной плате установлен микроконтроллер STM32L152RBT6. В микроконтроллере есть встроенный контроллер ЖКИ, который управляет монохромными жидкокристаллическими индикаторами.
Контроллер ЖКИ:

  1. Позволяет настраивать частоту обновлений (частоту кадров - частота, с которой обновляется информация на ЖКИ)
  2. Поддерживает статический и мультиплексный режим управления
  3. Поддерживает программную установку контраста
  4. Позволяет использовать несколько уровней управляющего напряжения (до четырех)
  5. Использует двойную буферизацию, позволяющую обновлять данные в регистрах LCD_RAM в любое время выполнения программы, не нарушая целостность отображаемой информации

Регистры памяти контроллера ЖКИ

В микроконтроллере STM32L152RB выделены специальные регистры LCD_RAM, информация, хранимая в которых, соответствует группе сегментов COM0 - COM3. Каждой группе соответствует два 32 разрядных регистра. Такое количество регистров позволяет микроконтроллеру управлять ЖКИ c большим количеством сегментов, чем установленным на отладочной плате.

Для управления ЖКИ со 176 сегментами используются 4 группы COM0 - COM3 по 44 сегмента каждая, для управления ЖКИ с 320 сегментами используются 8 групп COM0 - COM7 по 40 сегментов каждая.



На отладочной плате STM32L-Discovery используется ЖКИ с 96 сегментами, разделенными на 4 группы COM0 - COM3 по 24 сегмента каждая.


ЖКИ на отладочной плате STM32L-Discovery подключен таким образом, что используются биты S40, S41 вторых регистров LCD_RAM в каждой группе и биты S0-S27 первых регистров LCD_RAM. Для уменьшения количества используемых регистров, информация из битов S40-S43 будет записываться в свободные биты S28-S31, используя функцию переназначения (remapping).

Блок делителей частоты

Блок делителей частоты (Frequency generator) позволяет добиться различной частоты кадров (frame rates) на ЖКИ в диапазоне от 32 кГц до 1 МГц. В качестве источника тактирующего сигнала могут использоваться:
  1. Внешний НЧ генератор с частотой 32 кГц (LSE. Low speed external)
  2. Внутренний НЧ генератор с частотой 37 кГц (LSI. Low speed internal)
  3. Внешний ВЧ генератор с делителями частоты на 2,4,8 и 16 и максимальной частотой 1 МГц. (HSE. High speed external)
Для достижения точной синхронизации и снижения смещения напряжения постоянного тока через сегменты ЖКИ источник тактирующего сигнала должен обладать стабильностью. Тактирующий сигнал LCDCLK поступает в контроллер ЖКИ. Частота тактового сигнала делится, в соответствии с коэффициентами деления, которые устанавливаются битами PS, DIV регистра LCD_FCR (Frame Control Register). Результирующая частота на выходе блока делителей частоты рассчитывается по формуле:

F ck_div =F LCDCLK / (2 PS *(16+DIV))

Частота кадров рассчитывается по формуле:

F Frame =f ck_div *duty

Где duty – коэффициент заполнения – отношение длительность импульса к его периоду. За время одного кадра на ЖКИ последовательно выводится информация из регистров LCD_RAM[x], LCD_RAM и тд. Для ЖКИ установленного на отладочной плате, за один кадр контроллер ЖКИ должен вывести информацию из 4 групп сегментов COM0 - COM3, следовательно, длительность управляющего импульса для одной группы будет 1/4 длительности кадра, т.е. duty=1/4.

Управление ЖКИ

Существует два способа управления ЖКИ – статический режим управления и мультиплексный режим управления. При статической индикации каждый сегмент разряда индикатора подключен к выходу микроконтроллера. Применительно к ЖКИ, на отладочной плате STM32LDiscovery, потребуется 6*14=84 выводов микроконтроллера (без учета двоеточий, точек и полосок). Из-за использования такого количества выводов, подключение другой периферии станет невозможным. Микроконтроллер STM32L152RB имеет 64 вывода. При мультиплексном режиме управлении (динамический режим управления) одинаковые сегменты разрядов индикатора объединены в группы. Отображение информации происходит за счет поочередного зажигания сегментов разрядов индикатора, с частотой, не воспринимаемой человеческим глазом.

Мультиплексное управление позволяет управлять большим количеством сегментов. Вместо раздельного управления каждым элементом, они могу адресоваться по строкам и столбцам (COM и SEG), таким образом, упрощается управляющая схема, т.к. каждому сегменту не требуется собственная управляющая линия. Для включения выбранного сегмента, на него надо подать разность потенциалов COM и SEG. Пример работы первого разряда индикатора (на индикатор выводится «1:»):


Первый разряд индикатора в момент времени t 0


Первый разряд индикатора в момент времени t 1


Первый разряд индикатора в момент времени t 2


Общая схема подключения сегментов к выводам ЖКИ


Схема подключения выводов ЖКИ к портам микроконтроллера

Для линий SEG используется управляющее напряжение, количество уровней которого определяется коэффициентом bias. ЖКИ на отладочной плате использует мультиплексный режим управления с duty=1/4 и bias=1/3. Значение duty и bias устанавливаются через регистр LCD_CR (Control Register) в битах DUTY и BIAS.

Практика

Конфигурирование портов микроконтроллера

Для управления ЖКИ порты микроконтроллера должны быть настроены соответствующим образом:
  1. На выход
  2. Использование альтернативной функции AF 11 (Alternate function)
  3. Иметь частоты вывода в порт 400 кГц
  4. Использовать режим работы push-pull
  5. Без подтягивающих резисторов
При работе порта в режиме альтернативной функции, выходной буфер данных порта управляется сигналами, поступающими с периферии. Заголовочный файл stm32lxx.h библиотеки CMSIS содержит описание всех регистров периферии, а также структуры доступа к ним.

Выводы ЖКИ подключены к портам GPIOA (PA1-PA3,PA8-PA10,PA15), GPIOB (PB3-PB5, PB8-PB15), GPIOC (PC0-PC3,PC6-PC11) микроконтроллера. Для работы ЖКИ, на выбранные порты необходимо подать тактовый сигнал. Тактирование портов GPIO микроконтроллера происходит от шины AHB системы RCC (Reset and Clock Control) – системы тактировании и сброса. Подача тактового сигнала осуществляется установкой соответствующих битов в регистре RCC_AHBENR (AHB peripheral clock enable register).

Регистр RCC_AHBENR (на рисунке приведены первые 15 разрядов)

Для портов GPIOA, GPIOB, GPIOC необходимо установить 1 в 0, 1, 2 разряды регистра.

Далее я буду приводить код записи информации в регистр с использованием битмаски и с использованием шестнадцатеричных кодов. Использование битмасок удобнее, но работа с шестнадцатеричными кодами позволяет понять суть работы с регистрами.

RCC->AHBENR |=(RCC_AHBENR_GPIOAEN|RCC_AHBENR_GPIOBEN|RCC_AHBENR_GPIOCEN); или RCC->AHBENR = 0x7; /* 0x7=111 */

Для указания режимов работы порта используется регистр GPIOx_MODER (GPIO port mode register) (x = A..H). Все разряды регистра сгруппированы в группы MODERy, где y номер пина соответствующего порта. Порты необходимо настроить на режим альтернативной функции, т.е. в группе, отвечающей за пин, установить значение 10. Для порта GPIOA нужно настроить пины 1-3,8-10,15, т.е установить 1 в 3,5,7,17,19,21,31 разряды.


Регистр GPIOx_MODER (GPIO port mode register)

GPIOA->MODER |= (GPIO_MODER_MODER1_1 | GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1 | GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1 | GPIO_MODER_MODER15_1); или GPIOA->MODER = 0x802A00A8; /* 0x802A00A8=1000 0000 0010 1010 0000 0000 1010 1000 */
Порты микроконтроллера необходимо перевести в режим push-pull. Для этого необходимо в регистре GPIOx_OTYPER (GPIO port output type register) установить 1 в разряды, отвечающие за пины.


Регистр GPIOx_OTYPER (GPIO port output type register)

GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_1 | GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_3 | GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10 | GPIO_OTYPER_OT_15); или GPIOA->OTYPER &= ~0x0000870E; /* 0x870E=1000 0111 0000 1110 */
Оба варианта воздействуют на выбранные пины. (Для порта GPIOA настраиваются пины 1-3,8-10,15). Если необходимо перевести все пины порта в режим push-pull, можно записать в регистр значение:
GPIOA->OTYPER = 0x0;
Для указания частоты вывода информации в порт используется регистр GPIOx_OSPEEDR (GPIO port output speed register). Все разряды регистра сгруппированы в группы OSPEEDRy, где y номер пина соответствующего порта. В данной работе должна быть установлена частота 400 кГц т.е. в группе, отвечающей за пин, установить значение 00.


Регистр GPIOx_OSPEEDR (GPIO port output speed register)

GPIOA->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR1 | GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3 | GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR15); или GPIOA->OSPEEDR &= ~0xC03F00FC; /*0xC03F00FC=1100 0000 0011 1111 0000 0000 1111 1100 */
Если необходимо установить частоту вывода в порт 400 кГц для всех пинов, можно записать в регистр значение:
GPIOA->OSPEEDR = 0x0;
Для отключения подтягивающих резисторов pull-up, pull-down для выбранных пинов используется регистр GPIOx_PUPDR (GPIO port pullup/ pull-down register). Все разряды регистра сгруппированы в группы PUPDRy, где y – номер пина соответствующего порта. Для отключение подтягивающих резисторов в группе, отвечающей за пин, устанавливается значение 00.


Регистр GPIOx_PUPDR (GPIO port pull-up/pull-down register)

GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR1 | GPIO_PUPDR_PUPDR2 | GPIO_PUPDR_PUPDR3 | GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10 | GPIO_PUPDR_PUPDR15); или GPIOA->PUPDR &= ~0xC03F00FC; /*0xC03F00FC=1100 0000 0011 1111 0000 0000 1111 1100 */
Если необходимо отключить подтягивающие резисторы для всех пинов, можно записать в регистр значение:
GPIOA->PUPDR = 0x0;
Для использования альтернативной функции для портов микроконтроллера используются два регистра GPIOx_AFRL (GPIO alternate function low register), отвечающий за младшие пины (с 0 по 7) и GPIOx_AFRH (GPIO alternate function high register), отвечающий за старшие пины (с 8 по 15). Все разряды регистров сгруппированы в группы AFRLy и AFRHy, где y – номер пина соответствующего порта. Порты должны быть настроены на использование альтернативной функции AF11, для этого в группе, отвечающей за пин, должно быть установлено значение 1011.


Регистр GPIOx_AFRL (GPIO alternate function low register)


Регистр GPIOx_AFRH (GPIO alternate function high register)

Для этого необходимо записать в регистры значения:
GPIOA->AFR = 0xBBB0; /* 0xBBB0 = 1011 1011 1011 0000*/ GPIOA->AFR = 0xB0000BBB; /* 0xB0000BBB=1011 0000 0000 0000 0000 1011 1011 1011*/

AFR = 0xBBB0 – записывает значение в регистр GPIOx_AFRL.
AFR = 0xB0000BBB – записывает значение в регистр GPIOx_AFRH.

Настройки соответствующих пинов портов GPIOB, GPIOC производятся аналогично.

Настройка контроллера ЖКИ

При работе с контроллером ЖКИ, как и с другой периферией, на него необходимо подать тактовый сигнал. Тактовый сигнал также подается на систему управления питанием. Контроллер и система управления питанием для тактирования используют шину APB1. Для разрешения тактирования в регистре RCC_APB1ENR (APB1 peripheral clock enable register) необходимо установить 1 в 9 и 28 разрядах.


Регистр RCC_APB1ENR (APB1 peripheral clock enable register)

RCC->APB1ENR |= RCC_APB1ENR_PWREN|RCC_APB1ENR_LCDEN; или RCC->APB1ENR |= 0x10000200; /* 0x10000200=1 0000 0000 0000 0000 0010 0000 0000 */
Для работы контроллера ЖКИ необходимо указать источник тактовых сигналов. Источник указывается в регистре RCC_CSR. По умолчанию запись в этот регистр запрещена. В регистре управления питанием PWR_CR (PWR power control register) снимается защита от записи в регистр RCC_CSR. Регистр RCC_CSR управляет источниками тактирования часов RTC и контроллера ЖКИ
Запись в регистр RCC_CSR разрешается установкой 1 в 8 разряд регистра PWR_CR.


Регистр PWR_CR (PWR power control register)

PWR->CR |= PWR_CR_DBP; или PWR->CR |= 0x100; /* 0x100 =1 0000 0000 */
Для смены источника тактирования контроллера ЖКИ (и часов RTC тоже) необходимо сначала выполнить сброс источника тактирования установкой бита RTCRST (установкой 1 в 23 разряд) в регистре RCC_CSR (Control/status register).


Регистр RCC_CSR (Control/status register)

RCC->CSR |= RCC_CSR_RTCRST;
Или записав в регистр значение, используя оператор «|=», т.к. значение по
умолчанию регистра отлично от 0x0:
RCC->CSR |= 0x800000; /* 0x800000 = 1000 0000 0000 0000 0000 0000 */
Для выбора нового источника тактирования необходимо убрать бит RTCRST:
RCC->CSR &= ~RCC_CSR_RTCRST; или RCC->CSR &= ~0x800000;
В качестве источника тактового сигнала выбирается внешний НЧ генератор. Для включения генератора в регистре RCC_CSR необходимо установить бит LSEON (установить 1 в 8 разряд):
RCC->CSR |= RCC_CSR_LSEON; или RCC->CSR |= 0x100; /* 0x100 = 1 0000 0000 */
После включения генератора необходимо некоторое время на его стабилизацию. Готовность генератора проверяется аппаратной установкой бита LSERDY в регистре RCC_CSR:
while(!(RCC->CSR&RCC_CSR_LSERDY));
Выбор внешнего НЧ генератора в качестве источника тактового сигнала осуществляется установкой в группе RTCSEL регистра RCC_CSR значения 01:
RCC->CSR |= RCC_CSR_RTCSEL_LSE; или RCC->CSR |= 0x10000; /* 0x10000 = 01 0000 0000 0000 0000 */
В контроллере ЖКИ необходимо установить нужный режим bias. Для этого в регистре LCD_CR (LCD control register) необходимо установить значение 10 в группу BIAS. Перед установкой бит необходимо очистить биты от «мусора».


Регистр LCD_CR (LCD control register)

Сброс битов:
LCD->CR &= ~LCD_CR_BIAS; или LCD->CR &= ~0x60;
Выбор режима bias=1/3 с использованием битмаски:
LCD->CR |= LCD_CR_BIAS_1; или LCD->CR |= 0x40;
Устанавливаем режим duty=1/4. Для этого также вначале сбрасываем все биты:
LCD->CR &=~LCD_CR_DUTY; или LCD->CR &= ~0x1C;
Устанавливаем значение 011 в группу DUTY регистра LCD_CR для
режима duty=1/4:
LCD->CR |= LCD_CR_DUTY_0|LCD_CR_DUTY_1; или LCD->CR |= 0xС;
Активируем функцию переназначения выводов. Для этого устанавливаем 1 в 7 разряд регистра LCD_CR:
LCD->CR |= LCD_CR_MUX_SEG; или LCD->CR |= 0x80;
Устанавливаем значения коэффициентов деления частоты тактового сигнала LCDCLK. Значения коэффициентов выставляются в регистре LCD_FCR (LCD frame control register). Вначале также очищаем все биты, затем устанавливаем нужные.


Регистр LCD_FCR (LCD frame control register)

LCD->FCR &= ~LCD_FCR_PS; LCD->FCR &= ~LCD_FCR_DIV; или LCD->FCR &= ~0x3C00000; LCD->FCR &= ~0x3C0000;
Значения коэффициентов деления частоты тактового сигнала устанавливаем равными ck_ps = LCDCLK/16, ck_div = ck_ps/17. Для этого устанавливаем 1 в 24 и в 18 разряды:
LCD->FCR |= 0x1040000; /*0x1040000 = 1 0000 0100 0000 0000 0000 0000*/
Для установки нужного уровня контраста необходимо установить значение 010 в группу СС, так же предварительно очистив биты от старых значений:
LCD->FCR &= ~LCD_FCR_CC; LCD->FCR |= LCD_FCR_CC_1; или LCD->FCR &= ~0x1C00; LCD->FCR |= 0x800; /*0x800 = 1000 0000 0000*/
После установки всех значений необходимо некоторое время на синхронизацию регистра LCD_FCR. Синхронизация регистра проверяется аппаратной установкой бита FCRSF в регистре LCD_SR (LCD status register).

Регистр LCD_SR (LCD status register)

While(!(LCD->SR&LCD_SR_FCRSR));
В качестве источника напряжения для ЖКИ выбираем внутренний step-up converter для формирования V lcd . Для этого в первый разряд регистра LCD_CR (LCD control register) устанавливается значение 0:
LCD->CR &= ~LCD_CR_VSEL; или LCD->CR &= ~0x2;
Разрешение работы ЖКИ контроллера происходит установкой 1 в 0 разряд регистра LCD_CR (LCD control register):
LCD->CR |= LCD_CR_LCDEN; или LCD->CR |= 0x1;
После установки в качестве источника напряжения внутреннего step-up converter, необходимо дождаться его готовности. Готовность проверяется аппаратной установкой бита RDY в регистре LCD_SR (LCD status register):
while(!(LCD->SR&LCD_SR_RDY));
После разрешения работы контроллера ЖКИ, необходимо дождаться его готовности. Готовность проверяется аппаратной установкой бита ENS в регистре LCD_SR (LCD status register):
while(!(LCD->SR&LCD_SR_ENS));

Формирование изображения на ЖКИ

Все сегменты индикатора объединены в группы COM0 - COM3 по 24 сегмента в каждой (SEG0-SEG23). Информация о сегментах хранится в регистрах LCD_RAM памяти контроллера ЖКИ. Разводка печатной платы такова, что номера сегментов не соответствуют номерам разрядов регистров LCD_RAM.

Что бы отобразить 1 в первом разряде ЖКИ, необходимо зажечь сегменты 1B,1C. Сегмент 1B принадлежит группе COM0, сегмент 1C принадлежит группе COM1. Следовательно информация о них должна быть записана в регистры RAM (LCD_RAM0), RAM (LCD_RAM2) соответственно. За сегмент 1B отвечает вывод ЖКИ LCDSEG22, информация о котором храниться в разряде SEG40 регистра RAM (LCD_RAM1). С использованием функции переназначения за сегмент LCDSEG22 будет отвечать разряд SEG28 регистра RAM (LCD_RAM0). За сегмент 1С отвечает вывод ЖКИ LCDSEG1, информация о котором храниться в разряде SEG1 регистра RAM (LCD_RAM2).

LCD->RAM= 0x10000000; /*0x10000000 = 1 0000 0000 0000 0000 0000 0000 0000 */ LCD->RAM = 0x2; /*0x2= 10 */
До записи значений в регистры памяти необходимо проверить завершена ли предыдущая передача данных на ЖКИ. Для этого проверяется бит UDR (Update display request) регистра LCD_SR (LCD status register). Контроллер ЖКИ имеет два выходных буфера, информация заносится в первый буфер, а выводится на ЖКИ из второго буфера. Бит UDR устанавливается во время передачи из первого буфера во второй, защищая от записи регистры LCD_RAM:
while(LCD->SR & LCD_SR_UDR);
После записи информации в регистры LCD_RAM необходимо установить бит UDR в регистре LCD_SR (LCD status register)(установить 1 во 2 разряд):
LCD->SR |= LCD_SR_UDR; или LCD->SR |= 0x4; /*0x4 = 100 */

Часто пользователю требуется получать некоторую визуальную информацию с электронного устройства. Если информация может быть представлена в символьном виде, то одним из вариантов ее отображения является использование символьных жидко-кристаллических индикаторов (ЖКИ, или LCD в иностранном обозначении). Сегодня речь пойдет о символьных индикаторах, реализованных на базе контроллеров Hitachi HD44780, Samsung KS 0066 и аналогичных.

В качестве примера я буду рассматривать ЖКИ Winstar Wh1602D-TMI-CT# , имеющийся у меня для проведения экспериментов. Я уже упоминал этот ЖКИ в статье , графическими наработками которой я сегодня и воспользуюсь.

Подробный datasheet к LCD WINSTAR WH1602D-TMI-CT :

Category: Documents
Date: 22.03.2015

Упрощенно схему ЖКИ можно представить следующим образом:

Основой индикатора является жидко-кристаллическая матрица, подавая напряжение на элемент которой, мы можем наблюдать точку на экране. В символьных ЖКИ эта матрица состоит из определенного количества знакомест, которые группируются по строкам и столбцам. Размер знакоместа в пикселях часто составляет 5×8 точек. Маркировка моего индикатора содержит цифры 1602 и это означает, что мой индикатор может отображать 2 строки по 16 символов в каждой. Также кодировка включает: код производителя и тип индикатора, наличие подсветки, цвет, кодовую таблицу и так далее.

Система обозначений индикаторов WINSTAR

Показать/скрыть расшифровку обозначений

1. Код производителя : WINSTAR DISPLAY CO, LTD

2. Тип индикатора:

  • H — символьный (знакосинтезирующий)
  • C - графический цветной с пассивной матрицей CSTN (ColorSTN )
  • X — графический с матрицей TAB (Tape Automatic Bonding – кристалл монтируется на трёхслойной полиамидной подложке-ленте)
  • O - графический c матрицей COG (Chip On Glass - кристалл на стекле)

3. Горизонтальное разрешение:

  • число символов в строке для индикаторов символьного типа
  • число точек по горизонтали для индикаторов графического типа

4. Вертикальное разрешение:

  • число строк для индикаторов символьного типа
  • число точек по вертикали для индикаторов графического типа

5. Код модели

  • Кодирует геометрические размеры, используемый контроллер

6. Тип подсветки:

  • N — без подсветки
  • B - электролюминисцентная, цвет свечения — синий
  • D - электролюминисцентная, цвет свечения — зеленый
  • W - электролюминисцентная, цвет свечения - белый
  • Y — светодиодная, цвет свечения — желто-зеленый
  • A — светодиодная, цвет свечения — янтарный
  • R — светодиодная, цвет свечения — красный
  • G — светодиодная, цвет свечения — зеленый
  • T — светодиодная, цвет свечения — белый
  • P — светодиодная, цвет свечения - синий
  • F — лампа с холодным катодом (CCFL), цвет свечения — белый

7. Технология изготовления ЖК

  • B - TN серый, позитив
  • N — TN, негатив
  • G - STN серый, позитив
  • Y — STN желто-зеленый, позитив
  • M — STN синий, негатив
  • F — FSTN позитив
  • T - FSTN негатив
  • H - HTN серый, позитив
  • I — HTN черный, негатив
  • TN (Twisted Nematic) — структура кристаллов имеет спиралевидный тип
  • STN (Super Twisted Nematic ) - матрица, состоящая из ЖК-элементов с изменяемой прозрачностью
  • FSTN (Film Compensated STN ) — STN -матрица c пленочной компенсацией. Технология позволяет получить увеличенный угол обзора
  • HTN (Homeotropic Twisted Nematic ) - дисплеи основаны на более сильном молекулярном закручивании (обычно 110°) по сравнению с обычными скрученными нематиками TN (90°). Дают широкий угол обзора и улучшенную контрастность. По характеристикам превосходят STN –технологию. Низкое рабочее напряжение (2.5В и самая низкая стоимость среди нематиков делают их использование выгодным в переносных автономных устройствах).

8. Поляризатор, угол обзора, рабочий температурный диапазон

  • A — RF, 6:00, N.T.
  • D - RF, 12:00, N.T.
  • G - RF, 6:00, W.T.
  • J — RF, 12:00, W.T.
  • B — TF, 6:00, N.T.
  • E — TF, 12:00, N.T.
  • H — TF, 6:00, W.T.
  • K — TF, 12:00, W.T.
  • C — TM, 6:00, N.T.
  • F — TM, 12:00, N.T.
  • I — TM, 6:00, W.T.
  • L - TM, 12:00, W.T.
  • RF (Reflective LCD ) — ЖК индикатор, работающий исключительно на отражении света. Изображение видно только при достаточном внешнем освещении.
  • TF - (Transflective LCD ) -жидкокристаллический дисплей, который как отражает свет, так и испускает его (светится самостоятельно).
  • TM (Transmissive LCD ) - свет поступает сквозь LCD со стороны задней подсветки. Имеет высокое качество изображения в помещении и обычно очень низкое (черный экран) при солнечном свете.
  • N.T. — нормальный температурный диапазон 0...+50ºC W.T. — расширенный температурный диапазон -20...+70ºC

9. Дополнительные опции

Первые два символа — знакогенератор:

  • CT /CP — латиница/кириллица
  • EP /ET /EE /EN /EC /ES — латиница/европейский
  • JP /JT /JS /JN — латиница/японский
  • HP /HS — иврит

3-4 символы:

  • T - температурная компенсация
  • E или EZ — edge BL (светодиоды подсветки расположены по периметру). Также символ может отсутствовать.
  • K или LB — eco BL (светодиоды расположены сзади экрана равномерно)
  • V — встроенный источник отрицательного напряжения
  • N — без встроенного источника отрицательного напряжения

10. Дополнительная информация:

# — совместимость со стандартом RoHS

Примечание (производитель микросхемы контроллера):

  • xS - Samsung
  • xP - Sunplus
  • xT - Sitronix
  • xE - Epson
  • xU - UMC

Пользуясь этой системой обозначений я выяснил, что у меня в руках оказался знакосинтезирующий индикатор Winstar , отображающий символы в 16 столбцов и 2 строки, использующий контроллер KS 0066 или его аналог, со светодиодной подсветкой белого цвета по периметру, с синей негативной transmissive -матрицей, углом обзора «на 6 часов», рабочим диапазоном температур -20...+70ºC со знакогенератором, включающим кириллицу и совместимый со стандартом RoHS (не содержит вредных для здоровья компонентов, по всей видимости это означает, что при сборке использовался бессвинцовый припой).

Индикаторы на базе контроллеров HD44780 , KS066U

Управляет работой индикатора встроенный контроллер. В качестве контроллера обычно выступает Hitachi HD44780 , Samsung KS0066U или же их многочисленные аналоги и клоны. В индикаторах, производимых российской компанией МЭЛТ используется контроллер PCF8576.

У контроллера есть однобайтные ячейки памяти (DDRAM ), содержимое которых собственно отображается на экране согласно таблице записанной в CGRAM . Ячеек памяти обычно больше чем знакомест в ЖКИ, поэтому адресацию знакомест нужно смотреть в datasheet . Нам необходимо в нужную позицию записать код требуемого символа, а все остальное контроллер сделает сам.

Для выбора позиции существует виртуальный, управляемый посредством команд курсор (номер текущей ячейки памяти, АС ). Его можно сделать видимым. По умолчанию, при записи символа в ячейку, курсор сдвигаеться вперед на одну позицию.

Кодовая таблица индикатора, как правило состоит из трёх частей:

  • 0×00-0×07 — загружаемый знакогенератор, символы созданные вами
  • 0×20-0xFF — ASCII коды стандартный набор символов и английский алфавит
  • 0xA0-0xFF — символы национальных алфавитов и иные, с пропуском символов совпадающих по начертанию с английскими.

Показать/скрыть кодовую таблицу, с кириллицей

Пример: шестнадцатеричный код 0x4A соответствует букве J , код 0xB6 — букве ж .

Старшие четыре бита определяют столбец выбранного символа в таблице, младшие – строку. Можно создать свою собственную таблицу символов, записав ее в CGRAM . На каждый символ требуется 5 байт (на столбец по байту). Единицы в каждом байте определяют значимые пиксели. Например, для кодирования попиксельно цифры 8 потребуется такая последовательность: 0x6c,0×92,0×92,0×92,0x6c.

Конвертер кириллицы

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

Исходный текст:

Кодированный текст:

Таблица кодов команд:

D7 D6 D5 D4 D3 D2 D1 D0 Назначение
0 0 0 0 0 0 0 1 Очистка экрана, AC =0, адресация AC на DDRAM
0 0 0 0 0 0 1 AC =0, адресация на DDRAM , сброшены сдвиги, начало строки адресуется в начале DDRAM
0 0 0 0 0 1 I/D S Выбирается направление сдвига курсора или экрана
0 0 0 0 1 D C B Выбирается режим отображения
0 0 0 1 S/C R/L Команда сдвига курсора/экрана
0 0 1 DL N F Определение параметров развертки и ширины шины данных
0 1 AC5 AC4 AC3 AC2 AC1 AC0 Присвоение счетчику AC адреса в области CGRAM
1 AC6 AC5 AC4 AC3 AC2 AC1 AC0 Присвоение счетчику AC адреса в области DDRAM

Таблица значений флагов:

Флаг Значение
I/D Режим смещения счетчика адреса AC, 0 — уменьшение, 1 — увеличение
S Флаг режима сдвига содержимого экрана. 0 — сдвиг экрана не производится, 1 — после записи в DDRAM очередного кода экран сдвигается в направлении, определяемом флагом I/D: 0 — вправо, 1 — влево. При сдвиге не производится изменение содержимого DDRAM. Изменяются только внутренние указатели расположения видимого начала строки в DDRAM
S/C Флаг-команда, производящая вместе с флагом R/L операцию сдвига содержимого экрана (так же, как и в предыдущем случае, без изменений в DDRAM) или курсора. Определяет объект смещения: 0 — сдвигается курсор, 1 — сдвигается экран
R/L Флаг-команда, производящая вместе с флагом S/C операцию сдвига экрана или курсора. Уточняет направление сдвига: 0 — влево, 1 — вправо
D/L Флаг, определяющий ширину шины данных: 0 — 4 разряда, 1 — 8 разрядов
N Режим развертки изображения на ЖКИ: 0 — одна строка,1 — две строки
F Размер матрицы символов: 0 — 5×8 точек, 1 — 5×10 точек
D Наличие изображения: 0 — выключено, 1 — включено
C Курсор в виде символа подчеркивания: 0 — выключен, 1 — включен
B Курсор в виде мерцающего знакоместа: 0 — выключен, 1 — включен

Назначение выводов контроллера:

  • DB0 -DB7 — отвечают за входящие/исходящие данные
  • RS высокий уровень означает, что сигнал на выходах DB0-DB7 является данными, низкий — командой
  • W/R — определяет направление данных (чтение/запись). Так как операция чтения данных из индикатора обычно бывает невостребованной, то можно установить постоянно на этом входе низкий уровень
  • E — импульс длительностью не менее 500 мс на этом выводе определяет сигнал для чтения/записи данных с выводов DB0-DB7, RS и W/R
  • V 0 — используется для задания контраста изображения
  • A, K — питание подсветки (анод и катод), если она имеется
  • V CC и GND — питание ЖК-индикатора

Для управления ЖК-индикатором необходимо 6 или 10 выводов , в зависимости от того, выбран 4 или 8 битный режим обмена данными. Для сокращения требуемого числа выводов микроконтроллера можно работать в 4-битном режиме. В этом случае, на выводах DB4 -DB7 индикатора сначала будет передаваться старшие четыре бита данных/команды, затем — младшие четыре бита. Выводы DB0 -DB3 останутся незадействованными.

Один контроллер управляет ограниченным числом символов. На плате индикатора может быть 1, 2, 4, 8 контроллеров, а возможно — и больше.

Документация на контроллеры:

Контроллер Samsung KS0066U

Контроллер Hitachi HD44780

Category: Documents
Date: 21.03.2015

переведенный на русский язык вариант:

Category: Documents
Date: 21.03.2015

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

Таблица совместимости символьных ЖК-индикаторов разных производителей:

Показать/скрыть таблицу

Тип Winstar МЭЛТ Data Vision Bolymin Sunlike Microtips Wintek Ampire
8×2 WH0802A MT-8S2A DV-0802 BC0802A SC0802A MTC-0802X WM-C0802M AC082A
10×1 MT-10S1
12×2 WH1202A BC1202A
16×1 WH1601A DV-16100 BC1601A1 SC1601A MTC-16100X WM-C1601M AC161A
WH1601B BC1601B SC1601B
WH1601L MT-16S1A DV-16100 BC1601D1 SC1601D MTC-16101X WM-C1601Q AC161B
DV-16120 AC161J
16×2 WH1602L MT-16S2R DV-16210 BC1602E SC1602E MTC-16201X WM-C1602Q AC162E
SC1602N
WH1602D MT-16S2J DV-16230 BC1602B1 SC1602B MTC-16202X WM-C1602N AC162A
DV-16235 MTC-16203X
WH1602C MT-16S2D DV-16236 BC1602D SC1602D
WH1602A MT-16S2H DV-16244 BC1602H SC1602C MTC-16204X WM-C1602K
WH1602B DV-16252 BC1602A SC1602A MTC-16205B WM-C1602M
WH1602M DV-16257 BC1602F SC81602F
DV-16275
DV-16276
16×4 WH1604A MT-16S4A DV-16400 BC1604A1 SC1604A MTC-16400X WM-C1604M AC164A
WH1604B
20×1 DV-20100
MT-20S1L
20×2 WH2002A MT-20S2A DV-20200 BC2002A SC2002A MTC-20200X WM-C2002M AC202A
WH2002M
WH2002L MT-20S2M DV-20210 BC2002B SC2002C MTC-20201X WM-C2002P AC202B
DV-20211 AC202D
DV-20220
DV-20206-1
20×4 WH2004A MT-20S4A DV-20400 BC2004A SC2004A MTC-20400X WM-C2004P AC204A
SC2004G
SC2004C
WH2004L DV-20410 BC2004B MTC-20401X WM-C2004R AC204B
24×1 MT-24S1L
24×2 WH2402A MT-24S2A DV-24200 BC2402A SC2402A MTC-24200X WM-C2402P AC242A
MT-24S2L
40×2 WH4002A DV-40200 BC4002A SC4002A MTC-40200X WM-C4002P AC402A
40×4 WH4004A DV40400 BC4004A SC4004A MTC-40400X WM-C4004M AC404A
SC4004C

Питание, регулировка контрастности и подсветка

Внимательно нужно относится к полярности подключения питания к ЖК-индикатору, а также следить, чтобы напряжение питания лежало в диапазоне +4.5...5.5 В. Невнимательное отношение к этим моментам может привести к выходу индикатора из строя!

ЖК-индикаторы позволяют производить регулировку контрастности, используя делитель напряжения. Перед выводом данных на индикатор необходимо убедиться, что управляющее контрастностью напряжение находится в рабочем диапазоне. Номиналы резисторов отличаются у различных производителе ЖК-индикаторов. У некоторых моделей индикаторов на плате предусмотрены места для установки такого делителя и достаточно впаять туда нужные номиналы резисторов. Контрастность индикатора зависит от угла обзора. Если индикатор «на двенадцать часов», то смотреть на такой индикатор нужно таким образом, чтобы он находился ниже уровня глаз, если «ноль часов», то он предназначен для наблюдения на уровне глаз (перпендикулярно плоскости экрана). Если же индикатор «на шесть часов» то он должен использоваться при наблюдении выше уровня глаз. Этот момент обязательно нужно учесть при покупке.

Питание подсветки

Если в индикаторе имеется подсветка, то выводы для неё обычно располагаются отдельно. Необходимо подключить её к питанию, задав номинальный ток с помощью внешнего резистора R (см. datasheet ). Для моего индикатора номинальное напряжение на аноде должно составлять 3.5 В и ток 40 мА. Исходя из этого, номинал токоограничивающего резистора:

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

Как вы оцениваете эту публикацию?

  • Модуль 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 дисплея 16x2 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); скетча).