Работа с символьными ЖКИ на базе HD44780. STM32 и LCD

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

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

Внутренняя структура HD44780

В основе ЖКИ лежит матрица из жидких кристаллов, подавая напряжение на элемент которой мы можем «зажечь» точку на экране. В нашем случае матрица состоит из знакомест (чаще всего 8х5 пикселей), сгруппированых в несколько рядков. Этим всем управляет встроенный контроллер HD44780 . У контроллера есть однобайтные ячейки памяти (DDRAM ), содержимое которых собственно отображается на экране согласно таблице записанной в CGRAM . Ячеек памяти обычно больше чем знакомест в ЖКИ , поэтому адресацию знакомест нужно смотреть в даташите. То есть нам необходимо только в нужную позицию записать код нужного знака, а все остальное HD44780 сделает сам.

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

Старшая тетрада кода будет равна ряду выбранного символа, а младшая – строке. Можно создать свою таблицу символов, записав ее в CGRAM . На каждый символ требуется 5 байт, где единицы отвечают за «зажженные» пиксели. Например, цифра «8» кодируется последовательностью 0x6c,0x92,0x92,0x92,0x6c.
Коды команд приведены в таблице.

Таблица символов HD44780


Значения флагов:


Остается открытым вопрос: «как записать в нужную позицию код требуемого символа»? Для этого рассмотрим за что отвечают выводы ЖКИ . Выводы DB0-DB7 отвечают за входящие/исходящие данные. Высокий уровень на выводе RS дает индикатору понять, что сигнал на выводах DB0-DB7 является данными, а низкий – командой. Вывод W/R отвечает за направление данных, пишутся ли данные в память или читаются из нее (обычно чтение из ЖКИ не используется, можем смело на него подать низкий уровень). Импульс на выводе Е (длительностью не менее 500 нс) используется как сигнал для записи/чтения данных с выводов DB0-DB7 , RS и W/R .

Вывод V0 используется для задания контраста изображения, вывода А,К – для питания подсветки (если она есть в вашей модели ЖКИ ). Оставшиеся 2 вывода – собственно питание ЖКИ . То есть, для управления ЖКИ потребуется 8+1+1=10 выводов. Но можно работать в режиме 4-х битного интерфейса. При этом, сперва будет передавать старшая тетрада команды/данных на выводах DB4-DB7, а после – младшая. Выводы при DB0-DB3 при этом не используются. Итого для управления требуется 6 выводов микроконтроллера.
Теперь рассмотрим живой пример. Напишем программу для вывода текста «сайт» на имеющийся у меня в наличии WH1602А (2 строки по 16 символов).

Для других ЖКИ следует сверить соответствие ячеек DDRAM знакоместам. Схема подключения ЖКИ к контроллеру выглядит так.

Схема подключения к микроконтроллеру AVR


Резистор R3 - 17 Ом ограничивает ток через подсветку, а переменный VR1 задает контраст (если все правильно подключено и запрограммировано, но индикатор молчит, покрутите VR1, чтобы изображения стало видимым). Также не в коем случае не следует путать полярность ЖКИ , питать его выше 5,5В, со своего опыта могу сказать, что горят они моментально. Назначение всех остальных деталей такое же как в
Теперь перейдем к написанию программы. Для контроля индикатора напишем программу с несколькими ключевыми функциями работы с ЖКИ : lcd_dat(unsigned char x) – для записи данных х, lcd_com(unsigned char x) – для записи команды х, lcd_init(void) – для начальной инициализации индикатора:

    #include //библиотека ввода/вывода

  1. #define RS 2 //RS=PD2 - сигнал управления ЖКИ

    #define E 3 //E=PD3 - сигнал управления ЖКИ

  2. #define TIME 10 //Константа временной задержки для ЖКИ

    //Частота тактирование МК - 4Мгц

  3. //Программа формирвоания задержки

    void pause (unsigned int a)

    { unsigned int i;

  4. for (i= a; i> 0 ; i-- ) ;

  5. //Программа передачи команд в ЖКИ

    void lcd_com (unsigned char lcd)

    { unsigned char temp;

  6. temp= (lcd& ~(1 << RS) ) | (1 << E) ; //RS=0 – это команда

    PORTD= temp; //Выводим на portD старшую тетраду команды, сигналы RS, E

    asm("nop" ) ;

    PORTD= temp& ~(1 << E) ; //Сигнал записи команды

  7. temp= ((lcd* 16 ) & ~(1 << RS) ) | (1 << E) ; //RS=0 – это команда

    PORTD= temp; //Выводим на portD младшую тетраду команды, сигналы RS, E

    asm("nop" ) ; //Небольшая задержка в 1 такт МК, для стабилизации

    PORTD= temp& ~(1 << E) ; //Сигнал записи команды

  8. pause (10 * TIME) ; //Пауза для выполнения команды

  9. //Программа записи данных в ЖКИ

    void lcd_dat (unsigned char lcd)

    { unsigned char temp;

  10. temp= (lcd| (1 << RS) ) | (1 << E) ; //RS=1 – это данные

    PORTD= temp; //Выводим на portD старшую тетраду данных, сигналы RS, E

    asm("nop" ) ; //Небольшая задержка в 1 такт МК, для стабилизации

    PORTD= temp& ~(1 << E) ; //Сигнал записи данных

  11. temp= ((lcd* 16 ) | (1 << RS) ) | (1 << E) ; //RS=1 – это данные

    PORTD= temp; //Выводим на portD младшую тетраду данных, сигналы RS, E

    asm("nop" ) ; //Небольшая задержка в 1 такт МК, для стабилизации

    PORTD= temp& ~(1 << E) ; //Сигнал записи данных

  12. pause(TIME) ; //Пауза для вывода данных

  13. //Программа иниализации ЖКИ

    void lcd_init (void )

    lcd_com(0x2c ) ; //4-проводный интерфейс, 5x8 размер символа

    pause(100 * TIME) ;

    pause(100 * TIME) ;

    pause (100 * TIME) ;

  14. //Основная программа

    int main(void )

    DDRD= 0xfc ; //Инициализация portD

    PORTD= 0x00 ;

  15. pause(1000 ) ;

    lcd_init() ; //Инициализация ЖКИ

  16. lcd_dat("w" ) ; //Вывод "www.сайт"

    lcd_dat("w" ) ;

    lcd_dat("w" ) ;

    lcd_dat("." ) ;

    lcd_dat("a" ) ;

    lcd_dat("v" ) ;

    lcd_dat("r" ) ;

    lcd_dat("l" ) ;

    lcd_dat("a" ) ;

    lcd_dat("b" ) ;

    lcd_dat("." ) ;

    lcd_dat("c" ) ;

    lcd_dat("o" ) ;

    lcd_dat("m" ) ;

  17. lcd_dat("I" ) ; //Записываем "It"s so easy"

    lcd_dat("t" ) ;

    lcd_dat(""" ) ;

    lcd_dat("s" ) ;

    lcd_dat(" " ) ;

    lcd_dat("s" ) ;

    lcd_dat("o" ) ;

    lcd_dat(" " ) ;

    lcd_dat("e" ) ;

    lcd_dat("a" ) ;

    lcd_dat("s" ) ;

    lcd_dat("y" ) ;

  18. while (1 ) //бесконечный цикл

  19. return 1 ;

Программа очень проста, разобраться в ней не составит труда любому, кто хоть немного владеет C для AVR . Для латиницы и цифр ASCII коды совпадают с зашитыми в знакогенератор ЖКИ , поэтому позволительно использовать lcd_dat(‘A’) . Можно создать свою библиотеку для работы с ЖКИ, выделив функции lcd_dat(unsigned char x), lcd_com(unsigned char x), lcd_init(void) в отдельный модуль LCD.h и подключать его за надобностью.

Эта затея очень экономит время, стоит только один раз написать нужные функции, а потом все время их только использовать. Также можно подметить, что неудобно выводить длинную фразу по одной букве, для этого можно нашу выводимую строку запихнуть в массив из unsigned char и выводить с помощью цикла:

    int main(void )

    { unsigned char data [ 14 ] = { "w" , "w" , "w" , "." , "a" , "v" , "r" , "l" , "a" , "b" , "." , "c" , "o" , "m" } ;

    unsigned char i;

    DDRD= 0xfc ; //Инициализация portD

    PORTD= 0x00 ;

  1. pause(1000 ) ; //Задержка, чтобы ЖКИ успел включиться

    lcd_init() ; //Инициализация ЖКИ

  2. for (i= 0 ; i< 14 ; i++ ) //Вывод записи побуквенно

    lcd_dat(data[ i] ) ;

Только не стоит забывать, что нумерация массивов в С начинается с нуля. Существующую программу можно без существенных изменений использовать совместно с контроллером ATtiny2313 , подключив ЖКИ к PORTB , та как PORTD у ATtiny2313 имеет всего 7 выводов, а не 8, как у ATmega8 .

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

есть маленький недочет в этом примере

есть маленький недочет в этом примере, возможно по этой причине у многих не работает пример!

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

вобщем вся проблема с циклами задержки, для того чтоб дисплей поспевал за контроллером, а именно в функции-

//Программа формирвоания задержки

void pause (unsigned int a)

{ unsigned int i;

for (i=a;i>0;i--);

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

по крайней мере это справедливо для atmel studio 6.1, и в этом можно убедится просмотрем папку проэкта, там есть *.lss файл содержащий асемблерный код данной программы, генерируемы при сборке проекта. никакого намека на реализацию функции void pause...

в итоге при прошивке контроллера на дисплее получается случайный мусор или пустота...при нажатии несколько раз на ресет мусор может исчезать и вновь появлятся...явно на лицо расссинхронизация проца и экрана

а вот если сделать маленькую поправку

void pause (unsigned int a)

{ unsigned int i;

for (i=a;i>0;i--)
asm("nop");

То для компилятора это обретает смысл, это так же подтверждается явным появлением реализации функции в асемблерном коде

0000006c
:
6c: 9c 01 movw r18, r24
6e: 03 c0 rjmp .+6 ; 0x76
70: 00 00 nop
72: 21 50 subi r18, 0x01 ; 1
74: 31 09 sbc r19, r1
76: 21 15 cp r18, r1
78: 31 05 cpc r19, r1
7a: d1 f7 brne .-12 ; 0x70

и скорей всего все заработает....покрайней мере у меня на atmega16 (внутренняя RC синхронизация 1Mhz) и использовании atmel studio 6.1 было именно так... возможно на др частотах придется поигратся с константой #define TIME 10 и/или значениями передаваемыми функции void pause

вот здесь-> pause(значение) ...или pause(значение*TIME) ....

удачи в обучении управлению AVR!

Смотри, представь что ЖКИ -

Смотри, представь что ЖКИ - пишущая машинка, бумага в машинке - память ЖКИ, каретка - указатель курсора. Кроме того ЖКИ на экран выводит не все содержимое памяти, а лишь часть. Вроде как некоторое окно, которое мы налаживаем на нашу бумагу с текстом.

Вот I/D задает как мы будем печатать, справа-налево или слева-направо.
S определяет, будем ли мы сдвигать окно экрана вслед за тем, как печатаем или нет.
S/C - просто смещает видимое окно экрана или каретку машинки.
R/L - уточняет куда (влево или вправо) мы будем сдвигать экран или курсов с помощью флага S/C.

чего-то помоему не хватает!

Содрал вашу прогу и протэусе и на меги8 не стартует. Экран молчит, стал копать по даташитам и вот что нарыл:
не хватает в инициализации первых трех!

0011 - ждем 5 мс
0011 - ждем 100 мкс
0011 - ждем 2 мс
0010 - ждем 41 мкс
0000 - -и-
0010 - -и-
1000
0000
1000
0000
0001
0000
0100

если я не прав поправте!

Не работает!

Попробовал поменять частоты тактирования, задержки при инициализации и выводе символов(команд), пока что безуспешно. По поводу фьюзов, если вы имеете ввиду сконфигурировать выводы порта D c помощью регистров DDRB, PORTD как выходы с низким лог. уровнем, то это я сделал.
От делать нечего скомпилировал простую прогу вывода символов с помощью средств CodeVisionAVR, загнал в PROTEUS - работает!...а с реальным LCD отказывается..

Нет я говорю о том, что

Нет я говорю о том, что попробуй на порт D вывести например мигалку, или просто зажечь сразу весь порт. Я когда купил только микроконтроллер у меня этого не получилось сделать. Порыл форумы, оказалось что там как-то фьюзы запрограммированы что порт D и все его 8 бит не включены. Проверь этот момент, а лучше попробуй перевесить ЖКИ на другой порт например на B. То что программа в протеусе работает а с реальным нет - это и есть разница в параметрах ЖКИ забитого в протеусе и реального.

Не работает!

Собрал и подключил всё как по схеме, только МК использовал ATmega16 и LCD WH1602M, соответственно откомпилировал в WinAVR для него прошивку. Однако, выводить что либо LCD отказался, также собирал в протеусе(на ATmega 8 и LM016L), данные с МК выводятся но на LCD ничего не видно. В чем может быть проблема? (Если это важно, использовал внутренний RC генератор для тактирования на 1 мГц)

1. Для Atmega16 необходимо

1. Для Atmega16 необходимо через фьюзы включить сперва что бы порт D работал.
2. Попробуй изменить частоту тактирования на 4МГц и на 8МГц. Вся проблема ЖКИ в том, что не выдержаны все паузы при инициализации или при подаче команды. А контроллер ЖКИ очень чувствительный к этому.

Есть вопрос:
Собрал схемку хронометра на меге 8 с готовым хексом, - показания выводятся на WH0802,
показание- число из трех цифр, которые выводятся на весь экран, одна цифра состоит из 4-х знакомест. Экран типа псевдографический. Каким образом могла писаться прошивка??
Автор категорически отказывается давать исходники и не комментирует работу- наверное из соображения "интеллектуальной собственности".
По-свободе хочу попробовать написать свою прошивку в учебных целях.

Столкнулся с такой

Столкнулся с такой ситуацией.
Есть два LCD 16х2:
1 - MTC-S16204XFGHSAY
2 - WH1602A-YGH-CTK

1-ый использую в проекте с GPS.
2-ой решил использовать в проекте с клавиатурой. Но по каким то причинам lcd не работает.
Контраст регулируется и появляются квадратики. И все.
Возможно там другой порядок инициализации.
Помогите разобраться
Вот даташиты
filebox.od.ua/?file=24a31fc50d62bfcd658bdadac84088ab

Дисплеи ничем не отличаются.

Дисплеи ничем не отличаются. Распиновка одинакова. Тайминги немного разнятся. Попробуй увеличить задержки при отсылке команд на ЖКИ или понизь частоту МК.

Все ЖКИ на HD44780 имеют идентичную систему команд. Ты какой интерфейс юзаеш, 4-х битный, или 8-ми битный? Еще попробуй увеличить задержку между включением ЖКИ и его инициализацией, примерно до 0,1с. Полярность питания для ЖКИ не путалась, чтобы сгореть им немного надо? То я сдуру как-то спалил, а потом пытался подключить. Тоже выводились черные квадратики, через раз выводились данные, т.е. работал крайне нестабильно.

Использую программы из статей

Использую программы из статей о GPS.
интерфейс 4-ех битный

попробовал прогу отсюда
chipenable.ru/index.php/programming-c/75-chasy-na-mikrokontrollere.html

заработало

А что изменить в вашей проге?

Обрати внимание на задержки

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

Аналоги HD44780

Столкнулся с проблемой - не могу найти ЖКИ WH1602A по разумной цене. Например
в чипдипе такие стоят chipdip.ru/product/wh1602a-ygh-ct-k.aspx
700 деревянных. Что такое YGH в названии "WH1602A-YGH-CT(K), ЖКИ 16х2, англо-русский"
Какие есть аналоги ЖКИ на базе HD44780? Вот нашёл страничку micronika.ru/order.phtml?vid=64 - там в названии FDCC1602A-FSBFBW-51SR содержится 1602A,
просто обратил внимание. Может и FDCC1602A-FSBFBW-51S сойдёт без особого изменения кода?
Какие проблемы могут возникнуть при использовани
не собственно HD44780 от Хитачи, а его аналогов?
ЗЫ Не плохо бы почитать про использование различных ЖКИ, аналогов хд44780, чем МЭЛТ"овские
ЖКИ плохи

Часто пользователю требуется получать некоторую визуальную информацию с электронного устройства. Если информация может быть представлена в символьном виде, то одним из вариантов ее отображения является использование символьных жидко-кристаллических индикаторов (ЖКИ, или 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 мА. Исходя из этого, номинал токоограничивающего резистора:

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

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

По просьбе трудящихся, да и моим обещаниям решил я описать работу с знаковым ЖК 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 . Вот и все. Пробуйте, экспериментируйте. Возникнут вопросы, пишите на форуме. Удачи!

В этой статье я расскажу как с помощью достаточно распространенной библиотеки управлять LCD дисплеем на базе контроллера HD44780 и выводить на него информацию. Библиотека состоит из двух файлов lcd_lib.h и lcd_lib.c для использования с дисплеем подключенным по четырехбитной шине данных. В заголовочном файле прописываются настройки подключения дисплея к контроллеру, которые можно изменить по своему усмотрению, а также переменные и функции.

Ниже представлены базовые функции управления и вывода информации на LCD.

lcd_com – посылка команды в LCD

Пример:
lcd_com(0x01); // очистка дисплея
lcd_com(0x38); // интерфейс 8 бит 2 строки

lcd_dat – вывод одного символа в текущую позицию

Пример:
lcd_dat("U"); // вывод символа "U"
lcd_dat(0xB0); // вывод символа "Ю"(В соответствие с таблицей символов дисплея)

lcd_init – Инициализация LCD

Вот пример широко распространенной последовательности для инициализации LCD: 0x38, 0xOC, 0x06 .
0x38 устанавливает режим отображения 2-х строк с матрицей 5 х 8 точек и работу с 8-ми разрядной шиной данных;
0xOC включает отображение на экране ЖКИ-можуля, без отображения курсоров;
0x06 устанавливает режим автоматического перемещения курсора слева-направо после вывода каждого символа.

lcd_clr – очистка LCD

lcd_home – переводит курсор в начало

lcd_string – вывод строки указанной длинны в текущую позицию

Пример: lcd_string("TEST",4); // вывод строки TEST длиной 4 символа

lcd_gotoxy – перемещает курсор в указанную позицию

Пример: lcd_gotoxy(12, 1); // курсор в позиции тринадцатый разряд второй строки

copy_string_to_lcd – вывод строки из флеш-памяти в указанную позицию дисплея

Пример: copy_string_to_lcd("TEST",4,0); // вывод строки TEST в позицию пятый разряд первой строки

lcd_definechar – записывает пользовательское изображение символа в память дисплея

Чтобы вывести на экран дисплея собственный символ необходимо знать код символа, прописать этот код в памяти программ микроконтроллера (PROGMEM), затем поместить его в свободную ячейку памяти LCD (CGRAM) и выводить его на экран при помощи функции lcd_dat() .

Для программирования доступны 8 переопределяемых символов в режиме с матрицей 5х7 точек и 4 с матрицей 5х10 (в режиме 5х10 переопределяемые символы адресуются кодами DDRAM через один: 0x00, 0x02, 0x04, 0x06). Для кодирования матрицы используются горизонтально "уложенные" байты, пять младших битов которых несут информацию о рисунке (причем 1(единица) означает, что сегмент будет включен), 4-й разряд каждого из 8-ми (или 11-ти в режиме 5 х 10) байтов матрицы определяет левую колонку символа, а 0-й - правую. Старшие три бита не используются, равно как и старшие пять байтов, составляющих полную область матрицы символа (16 байтов) в режиме 5х10 (обратите внимание, что матрица программируемых символов допускает использование полной высоты строки (8 строчек для режима 5х7 и 11 строчек для режима 5х10), то есть можно размещать точки в области подчеркивающего курсора).

Создавать символ более удобно в двоичном формате, к примеру создадим символ прямоугольника, код будет таким:

Const uint8_t pryamougolnik PROGMEM= { 0b11111, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111, 0b0 };

lcd_shift_right – перемещает изображение на указанное число символов вправо

lcd_shift_Left – перемещает изображение на указанное число символов влево

lcd_cursor_on – включает курсор подчеркивание

lcd_cursor_blink – включает мигающий курсор

lcd_cursor_off – выключает курсор

lcd_blank – отключает изображение, но не очищает

lcd_visible – включает изображение

lcd_cursor_left – перемещает курсор на указанное число символов влево

lcd_cursor_right – перемещает курсор на указанное число символов вправо

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

lcd_num_to_str - позволяет выводить на дисплей переменную до 4 разрядов

Пример: void lcd_num_to_str(ADC, 4); // Выводим переменную АЦП 4 разряда

Сделаем проект "Аналоговый вольтметр" в котором информация об измеренном напряжении будет выводится на экран в виде горизонтальной динамической шкалы. Измеряемое напряжение подается на вход ADC0, максимум 5В. без использования делителя. Используем для этого проекта микроконтроллер atmega8, который тактируется от внутреннего генератора частотой 8МГц. Дисплей подключаем по четырехбитной шине в соответствие с настройками из файла lcd_lib.h. При создании проекта в AVRSTUDIO копируем 2 файла библиотеки в папку нашего проекта, а в дереве проекта добавляем эти файлы(lcd_lib.c и lcd_lib.h).

За вывод динамической шкалы отвечает функция lcd_progress_bar(uint8_t progress, uint8_t maxprogress, uint8_t length) , в зависимости от состояния переменных этой функции, шкала меняет свой уровень, progress - уровень от 0 до 255, maxprogress - максимальный уровень ограничивается числом от 0 до 255, length - длина шкалы от 0 до 16 ячеек(в зависимости от типа дисплея). Так как при максимальном напряжении на входе значение ADC равно 1024, делим это значение на 4 и присваиваем его переменной "u", а переменную "u" используем в функции вывода динамической шкалы progress() .

Полный текст программы выкладываю ниже:

//******Применение библиотек для работы с LCD HD44780***** #include #include #include #include "lcd_lib.h" const uint8_t simbol_1 PROGMEM= {
0b00000,0b10001,0b01010,0b00100,0b01010,0b10001,0b00000,0b00000
};
const uint8_t simbol_2 PROGMEM= {
0b00100,0b00100,0b00100,0b11111,0b00100,0b00100,0b00100,0b00000
}; unsigned char u; //******************************************************** void progress(void) // функция вывода шкалы { lcd_gotoxy(0, 0); lcd_string("0......05......1",16); lcd_gotoxy(0, 1); lcd_progress_bar(u, 255, 16); } //******************************************************** int main(void) { /***Настройка АЦП***/ ADCSRA |= (1 << ADEN) //Включение АЦП |(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8 ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН |(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // вход PC0 _delay_ms(100); lcd_init();// инициализация LCD lcd_clr();// очистить LCD _delay_ms(10); lcd_definechar(simbol_1, 6); // определяем собств. символ 1 lcd_definechar(simbol_2, 7); // определяем собств. символ 2 for(char a=0; a<10; a++) // цикл приветствия { lcd_gotoxy(0, 0); lcd_dat(6); _delay_ms(100); lcd_gotoxy(0, 0); lcd_dat(7); _delay_ms(100); lcd_gotoxy(3, 0); lcd_string("AЅa»oґoіГ№",10); // Аналоговый lcd_gotoxy(3, 1); lcd_string("іo»Дїјeїp",9); // вольтметр } _delay_ms(1000); lcd_clr();// очистить LCD while(1) { progress(); ADCSRA |= (1 << ADSC); //Начинаем преобразование while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования u = ADC/4; } }

И его аналогах, например, таких как S6A0069, KS0066 и т.д. Данные ЖК индикаторы – текстовые и умеют отображать текст и псевдографические символы. Размер знакоместа у них составляет 5x8 пикселей, ЖК индикаторы бывают разных размеров и с разными разрешениями, например: 8 символов на 2 строки – 8x2, 16x2, 20x2, 40x2, 16x4, 20x4 и т.д.

В данном уроке мы рассмотрим 4 битное подключения ЖК индикатора к микроконтроллеру AVR, и написание программы в среде .

У таких ЖК индикаторов существуют выводы:
VSS – Gnd (Минус питания)
VDD – Vcc (Плюс питания 5v)
VO – Установка контрастности ЖК матрицы
RS – Линия управления RS
RW (Read/Write) – Линия управления RW
E (Enable) – Линия управления E
D0 – Линия данных D0 (Не используется в 4 битном режиме)
D1 – Линия данных D1 (Не используется в 4 битном режиме)
D2 – Линия данных D2 (Не используется в 4 битном режиме)
D3 – Линия данных D3 (Не используется в 4 битном режиме)
D4 – Линия данных D4
D5 – Линия данных D5
D6 – Линия данных D6
D7 – Линия данных D7
A – Анод светодиода подсветки дисплея
K – Катод светодиода подсветки дисплея

Внимание! У разных ЖК индикаторов своё расположение выводов, точное расположение выводов вы можете узнать в технической документации (Даташите) на ваш ЖК индикатор.

Вывод ЖК индикатора VO управляет контрастностью ЖК матрицы в зависимости от подаваемого на этот вывод напряжения питания. Вывод RW если не надо считывать с дисплея информацию подключается к минусу питания.

Пример 4 битного подключения ЖК индикатора к микроконтроллеру Attiny2313:

Подстрочный резистор RV1 регулирует яркость ЖК индикатора.
В BASCOM-AVR перед работой ЖК индикатора необходимо указать, какие выводы дисплея подключены, к каким портам микроконтроллера, для этого есть команда Config Lcdpin, пример применения данной команды: Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2 а также указать разрешение ЖК индикатора командой Config Lcd, пример: Config Lcd = 16 * 2 и проинициализировать ЖК индикатор командой Initlcd, после этого ЖК индикатор будет готов к работе.

Вот список команд для работы с ЖК индикатором в BASCOM-AVR:
Config Lcdpin – Установка конфигурации выводов ЖК индикатора и микроконтроллера
Config Lcd – Установка разрешения ЖК индикатора
Initlcd – Инициализация ЖК индикатора
Lcd – Вывод текста на ЖК индикатор, пример: Lcd ”Hello”
Cls – Очистка ЖК индикатора
Locate y, x – Установить курсор в позицию x, y
Lowerline – Переместить курсор на нижнею строку
Upperline – Переместить курсор на верхнею строку
Shiftlcd Right – Сдвинуть изображение ЖК индикатора вправо на одно знакоместо
Shiftlcd Left – Сдвинуть изображение ЖК индикатора влево на одно знакоместо
Cursor Off – Отключить курсор
Cursor On – Включить курсор
Cursor On Blink – Включить мерцающий курсор
Cursor On Noblink – Отключить мерцающий курсор

Внимание! При использовании ЖК индикатора c разрешением 8x2 в BASCOM-AVR конфигурируйте его как 16x2, так как в BASCOM-AVR нет конфигурации на ЖК индикатор с разрешение 8x2.

Пример программы в BASCOM-AVR для вышеизложенной схемы:

$regfile = "attiny2313.dat" $crystal = 8000000 Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2 Config Lcd = 16 * 2 Initlcd Cls Locate 1 , 1 Lcd "Hello," Lowerline Lcd "world!" End

Вот как всё это работает с ЖК индикатором 8x2:

Фьюз биты для прошивки:

Скачать файлы для урока (проект в , исходник, прошивка) вы можете ниже

Похожие статьи