Подключаем ЖКИ на базе ks0066 к AVR. Программа на Си. Шаг № 4
Обновлено 23.02.15. Всем привет. Рассмотрев первую программу в статье №3на микроконтроллере, способы настройки Makefile (статья №2), заливки, а также имея «aрсенал» необходимой литературы (статья №1), приступаем чуть к более сложному этапу: подключим ЖКИ к AVR и разберем алгоритм «общения» с ним.
Итак начнем с того, что же такое ЖКИ ? Это жидкий кристалл который помещен в стеклянный кювет. Жидкокристаллический дисплей состоит из нескольких слоев, где ключевую роль играют две стеклянные панели, на которые наносится тонкий слой металла, образующий электроды. Последние, в свою очередь, наносятся в виде точек, пиктограмм или сегментов для отображения различных видов информации.
Как и во всех устройствах у индикатора есть свои параметры:
– важным является время релаксации — это то время, которое необходимо для возвращения молекул жидкого кристалла в исходное состояние после выключения поля, и составляет 30-50 мс. Приемлемо для индикаторов, но не достаточно для компьютерных мониторов. Данный параметр зависит от температуры;
— контрастность – зависит также от температуры, при повышении допустимой, четкость падает;
– угол обзора — зависит от скважности динамического режима индикации. Чем больше скважность – тем меньше получается угол обзора индикатора;
Особенностью работы жидкокристаллического индикатора является то, что на него следует подавать переменное напряжение.
Это связано с тем, что при подаче на жидкокристаллический индикатор постоянного напряжения происходит электролиз жидкого кристалла и индикатор выходит из строя. Собственно ЖКИ использовать довольно сложно — его управляющие сигналы многочисленны, сложны и, в отличие от простых логических уровней «ноль» и «единичка», имеют много градаций уровней напряжения и тока.
Поэтому для управления ЖКИ используются контроллеры.
От общей теории перейдем к практике. Рассмотрим ЖКИ фирмы RAYSTAR RC1602D-YKY-CSX, на базе контроллера ks0066 (Samsung), который является аналогом hd44780, за исключением алгоритма инициализации hd44780.Ну что ж разберем техничексое описание и напишем функции на Си..
На общей блок-диаграмме видно примерное взаимодействие элементов модуля. Контроллер управляет индикатором а мы будем управлять контроллером. Он имеет свой набор команд, определенные требования по задержкам. Кстати команды обоих контроллеров (hd44780 и ks0066) идентичны, также и по временным задержкам.
На рисунке ниже приведено описание выводов модуля.
С 4 по 14 пин — эти выводы непосредственно подключаются к микроконтроллеру. На блок-диаграмме (выше) пин №3 подключен к переменному резистору (подстроечному). Регулируя его мы регулируем контрасность. Однако если прибор используется в промышленности то используется другая схема включения для регулировки контрастности в зависимости от переменны температуры.
Interface Pin Function.
Для экономии «ножек» микроконтроллера, при подключениии к ЖКИ, существует два варианта подключения к шинам данных: 8-ми битная и 4-х битная.
Программа для 4-х битного подключения сложней, но зато экономия! В этом варианте байт передаётся в два приёма: на старшую половину шины данных ЖК-модуля, первым передают старший полубайт, затем – младший.
В даташите описаны алгоритмы для двух режимов работы.
Рассмотрим инициализацию для 4-х битного режима, которая кардинально отличается от аналогичногоконтроллера hd44780.
Напишем функции для работы с ЖКИ.
1.Инициализация 4 –битного интерфейса контроллера ks0066
На рисунке слева приведен порядок инициализации контроллера ks0066 . Как видно, алгоритм делится на четыре блока: инициализация самого дисплея и строчного режима(одно или двух); включение или выключение управления дисплеем; очистка дисплея; установка режима ввода.
Пусть выводы ЖКИ DB7, DB6, DB5, DB4 соответствуют ножкам PB7,PB6,PB5,PB4 , а выводы RS- PB0, R/W-PB2,Е-PB1. ЗАМЕТЬТЕ ЧТО ЭТО УСЛОВНОСТЬ, МОЖНА БРАТЬ ЛЮБЫЕ НОЖКИ МИКРОКОНТРОЛЛЕРА AVR.
Перед написанием функции используем макросы препроцессора define для настройки программы под другие ножки, т.е. используем приемы универсальности. Данный вопрос мы рассмотрели в статье №20. Итак что б не писать каждый раз строки, например посылки комманды
PORTB = 0×20;
_delay_us (2);
PORTB |= _BV (PB1);
_delay_us (2);
PORTB &= ~_BV (PB1);
Длинные строки PORTB |= _BV (PB1); мы упрощаем путем переопределения в define, а однотипный алгоритм запихиваем в функцию
#define PORTLC PORTB /*Порт подключения к ЖКИ*/
#define DDRLC DDRB /*Определяем направленность вход/выхода порта*/
#define poryd 0b11110011/*Определяем подключенные ножки порта к ЖКИ*/
#define E PB1 /*Нога подключенная для передачи строба подтверждения передачи данных*/
#define RS PB0 /*Нога для характера(команда или данные) передачи данных*/
#define E1 PORTLC |= _BV (E);
#define E0 PORTLC &= ~_BV (E);
#define RS1 PORTLC |= _BV (RS); /*RS=1: данные которые следует отобразить*/
#define RS0 PORTLC &= ~_BV (RS); /*RS=0: влияющая на режим работы дисплея*/
Все теперь мы можем легко поменять порт и применить программу к другому микроконтроллеру. Пропишем функцию передачи команды
void command_lcd (unsigned char cmd)
{
PORTLC = (cmd & 0xF0); /* Передаем старший полубайт *1111 0000 */
RS0; /*Для передачи комманды*/
E1; /*Подтверждение передачи данных*/
_delay_us (2); /* Небольшая задержки для обработки команды контроллером ЖКИ*/
E0; /*Окончание импульса строба*/
PORTLC = ((cmd & 0x0F) 1) {adr = x + 64;} /*если вторая строка, то переводим символ на вторую строку, 64- в десятичной ,соответствует 40 в 16-ричной*/
else { adr = x;} /* иначе присваиваем переменной позицию курсора в первой строке, добавляя максимальную длину строки*/
/*Передаем номер ячейки индикатору для этого проведем побитовое сложение*/
adr = adr|0×80; /*0xxx xxxx | 1000 0000*/
command_lcd (adr);
}
Адресса знакомест на дисплее.
3.Напишем функцию вывода строки, передачи данных и очистка дисплея
void PrintString (char *sign )
{
unsigned char i;
for (i=1;i
Источник: http://www.ap-impulse.ru/podklyuchaem-zhki-na-kontrollere-ks0066-shag-4/
Знакосинтезирующий ЖКИ 1602 и клавиатура: экономим выводы микроконтроллера
В рамках данной заметки мы рассмотрим, как можно сэкономить выводы микроконтроллера при использовании знакосинтезирующего жидкокристаллического индикатора совместно с кнопками управления меню устройства. Будет показано, что при использовании «обычного» ЖКИ (т.е.
собранном на контроллере типа HD44780) и «стандартном» способе управления меню (кнопки «MENU/SELECT», «UP», «DOWN», «+» и «-») для опроса кнопок не требуется каких-либо дополнительных ресурсов камня, кроме уже задействованных под управление индикатором:
Третьего дня накропал заметку на тему, указанную в названии данного топика. Честно говоря, на протяжении нескольких лет думал, что сии сведения на предмет непонятности и, главное, неочевидности стоя́т примерно в том же ряду, что и расчет резистора для светодиода. Однако, реальная жизнь показала, насколько глубоко я ошибался.
Полную версию заметки приводить здесь смысла не вижу, ограничусь только выдержками основных тезисов и расчетов.
Лирическое вступление
Лично для меня проблема экономии выводов камня при работе с ЖКИ и кнопками управления пунктами меню встала сразу же после первого опыта работы с кирпичом ATMega48 (ну, или какого-то другого пин-ту-пин совместимого с ним, сейчас не вспомню). Ранее для управления индикатором я «честно» выделял 7 выводов МК (см.
4-х битный режим), да еще минимум 5 выводов – на кнопки навигации по меню. Однако, быстро выяснилось, что для камней линейки ATMegaX8 подобный подход – непозволительная роскошь: бросать 12 из 20 «полноценных» выводов кирпича на вспомогательную, в общем-то, работу мне показалось совсем уж расточительным.
Я стал прикидывать, как бы мне сэкономить выводы кирпича, и вскоре оказалось, что в реальности для управления как индикатором, так и меню достаточно всего пяти выводов МК. От разницы между «12» и «5» я сперва несколько охерел и стал подозревать нехорошее.
Однако, опыты в железе показали, что все «бумажные» выкладки и расчеты действительно корректно работают и в реальной жизни. В общем, порадовался я за себя, что в который раз изобрел собственный велосипед, да и успокоился – просто начал применять «экономный» подход во всех своих поделках.
А тут в ходе очередной дискуссии поинтересовался у двух знакомых – как они подходят к данной проблеме. Их ответы меня несколько озадачили. Один сообщил, что подобные мелочи его вообще не па́рят – я, говорит, во все свои проекты ставлю Мегу128 и выше, да и вообще с ЖКИ работаю в 8-ми битном режиме.
Ну что тут скажешь – красиво жить не запретишь, да: засрать 128-ю мегу так, чтобы не хватило выводов отдельно на кнопки довольно сложно. А вот второй рассказал, что для экономии портов МК при работе с индикатором и кнопками использует такой же подход, какой реализован во всем известном шылде для ардуины «LCD1602»:Это меня удивило.
Человек далеко не первый год разрабатывает электронику, и при этом даже не задумался о какой-либо дальнейшей оптимизации подключения ЖКИ и кнопок. Я ему рассказал о том, как делаю я, и теперь настала очередь удивляться уже ему. Видя реакцию на свои слова, я в который раз понял, что очевидное для меня не является очевидным для всех, поэтому приступил к написанию заметки на данную тему.
Оптимизация управления ЖКИ
Тут всё просто и очевидно, наверное, даже для начинающих. Известно, что знакоситезирующие ЖКИ могут работать как в 8-ми битном режиме обмена данными, так и в 4-х битном (см. соответствующие даташыты).
В первом случае можно несколько ускорить скорость общения с индикатором, но зато во втором нам для связи с индикатором надо на 4 линии управления меньше – всего 7 линий вместо 11-ти для 8-ми битного режима: «R/W», «RS», «E», «DB7», «DB6», «DB5», «DB4» (т.е. в данном режиме работы линии «DB3»-«DB0» не используются).
И поскольку жидкий индикатор сам по себе далеко не быстродействующее устройство, то как-то так исторически повелось, что для экономии выводов МК все используют 4-х битный режим обмена данными с ЖКИ.
Далее, из вышеупомянутых 7 линий управления одна (это которая «R/W») отвечает только за режим обмена данными с индикатором. Если R/W=1, то можно считать инфу с ЖКИ, а если R/W=0, то инфу в индикатор можно записа́ть.
В подавляющем большинстве случаев режим чтения данных с ЖКИ не используется (в полной версии заметки объясняется почему), поэтому вывод «R/W» можно тупо заземлить.
В итоге со стороны микроконтроллера шина управления ЖК-модулем сокращается до 6 линий («RS», «E», «DB7», «DB6», «DB5», «DB4»), и это максимум, до чего ее вообще можно дооптимизировать.
Оптимизация подключения кнопок навигации по меню
Как было сказано ранее, в большинстве случаев основным режимом работы ЖКИ (который мы и рассмотрим далее) будет «4 бита + только запись» (в смысле – только запись данных в индикатор), поэтому для управления индикатором нам потребуется всего 6 линий микроконтроллера. Далее нам нужно вспомнить, что шина обмена данными с индикатором является стробируемой.
Это означает, что пока на линии «Е» не будет сформирован задний фронт импульса (хотя, возможно, существуют разновидности ЖКИ, стробируемые по переднему фронту), индикатору совершенно плевать, что́ происходит на других его линиях данных.
Иными словами, пока не будет выставлен нужный строб на линии «Е», мы можем творить что угодно (замыкать какую угодно линию на плюс или на массу) – соответствующие данные в ЖКИ всё равно не запишутся.
А это означает то, что мы можем подключить к линиям «RS», «DB7», «DB6», «DB5», «DB4» вышеупомянутые кнопки (естественно, названия кнопок даны условно; в реальности они могут иметь какой угодно функционал) и дрочить их как нам заблагорассудится, пока не нужно будет записать что-либо в ЖКИ (главное – не куролесить на линии строба).
Никакого влияния на информацию, отображаемую на ЖКИ, это дрочительство не окажет, а вот считать состояние кнопок камнем мы вполне сможем («стандартный» опрос входа в то время, когда на ЖКИ ничего отсылать не надо). Ну а когда нам понадобится вывести что-то новое на индикатор, мы просто выдадим на линии «RS», «DB7», «DB6», «DB5», «DB4» нужный код и дадим строб на линию «Е».
Общая схема
В железе для оптимизации связи с индикатором в данном случае наиболее бюджетно будет построить вот такую схему (сразу включив сюда и кнопки управления устройством):Обратите внимание на то, что, как и было оговорено ранее, индикатор работает в режиме «только запись» (т.е. в него можно только записывать информацию), поскольку вывод R/W у него заземлен.
Камень ATMega8, как и названия портов, к которым подключен индикатор и кнопки, взят просто для примера. Для других вариантов кирпичей тут важно лишь два момента: — соответствующие порты МК (PD1, PD7-PD4) должны уметь работать и как входы, и как «Push-Pull» выходы (пуш-пул — это важно, см.
комментарии к заметке); — порты камня, к которым подключаются кнопки, при работе в качестве входов должны иметь внутреннюю подтяжку к плюсу питания. Если в микроконтроллере на аппаратном уровне данная фича отсутствует, необходимо будет реализовать подобные подтяжки внешне. Принцип работы предлагаемой схемы (ра́вно как и алгоритм программы) достаточно прост.
Для опроса состояния кнопок выводы PD1, PD7-PD4 МК должны быть настроены на вход и подтянуты к плюсу питания резисторами (вывод PD0 лучше всегда делать выходом, и в те моменты времени, когда общения с индикатором нет, на нем должен присутствовать логический нуль). Данный опрос кнопок является «традиционным», т.е.
камень, например, просто поочередно проверяет сигнал на цифровых входах PD1, PD7-PD4 (можно также прикрутить сюда прерывания – вариантов реализации опроса масса). Поскольку эти входы подтянуты к плюсу, ненажатому состоянию кнопки будет соответствовать логическая единица, а нажатому – логический нуль (при обработке сигналов от кнопок не забываем о «дребезге» их контактов).
А поскольку строб для ЖКИ (линия «Е») отсутствует, всё, что происходит на линиях «RS» и «DB7»-«DB4» индикатором игнорируется, т.е. различная ахинея, соответствующая разным комбинациям нажатых/ненажатых кнопок, просто проходит мимо ЖК-модуля. Отметим, что т.к.
ЖКИ работает в режиме «только запись», линии его управления «DB7»-«DB4» являются входами, поэтому никакого влияния на выводы PD7-PD4 микроконтроллера оказывать не будут.
Как только появляется необходимость пообщаться с ЖКИ, линии PD1, PD7-PD4 камня должны быть переведены на выход.
Далее на этих линиях выставляется код, соответствующий передаваемой в индикатор информации, и даются стробы по линии «Е», т.е. производится обычная запись данных в ЖКИ по 4-х битной шине. Отметим, что код, выставляемый камнем на выходах PD1, PD7-PD4 никак не будет «испорчен» кнопками. Если кнопка не нажата, то на соответствующий выход МК не оказывается никакого влияния (т.е.
на нем будет именно то значение, которое мы выставили). А если кнопка нажата, то по этому выходу просто потечет дополнительный ток, значение которого будет ограничено за счет резисторов R1-R5, при этом состояние выхода тоже не изменится.
Выбор номиналов данных резисторов подробно рассмотрен в полной версии заметки, здесь же просто отметим, что для камней ATMega эти резисторы лучше выбрать равными 3,3…4,7кОм. Таким образом, получаем, что с одной стороны информация в индикатор будет передана верно, а с другой – выходы PD1, PD7-PD4 микроконтроллера заведомо не сгорят даже в том случае, когда соответствующая кнопка (или кнопки) будут нажаты. Ну а после передачи данных в ЖКИ нужно снова перевести выводы PD1, PD7-PD4 на вход и подтянуть их к плюсу питания для последующего опроса состояния кнопок.
Лирическое заключение
Вот, в принципе, и вся «наука». Честно говоря, я не совсем понимаю, почему в широко распространенном шылде «LCD 1602» применен не рассмотренный принцип опроса кнопок, а АЦП-шный. Ведь в том включении, который реализован в шылде, в общем случае невозможно даже определить одновременное нажатие нескольких кнопок.
Да и номиналы соответствующих резисторов разные, что с точки зрения массового изготовления не совсем корректно. В общем, одни вопросы к шылду «LCD 1602», да. Ну и последнее.
Бывает так, что для управления простеньким меню нам вполне будет достаточно и трех кнопок вместо пяти, а вот дополнительная светодиодная индикация (например, режимов работы устройства) не помешает.
В этом случае, конечно, никто не запрещает взамен «ненужных» кнопок воткнуть светодиоды, уменьшив сопротивление соответствующих резисторов из числа R1-R5. Однако, лучше так не делать. Сгореть, конечно, в данном случае ничего не сгорит, но.
Во время отправки инфы в индикатор те светодиоды, на которые будет подана логическая единица, начнут светиться. А если в другие моменты времени они не горят, то мы получим «паразитные» вспышки. Отмечу, что человеческий глаз легко замечает вспышки длительностью даже 60-70мкс на обычных «прозрачных» светодиодах.
Ну а при управлении индикатором наиболее распространен случай, когда для формирования «длины посылки» используется не флаг занятости BF, а тупые задержки, при этом длительность вывода на экран одного символа в 4-х битном режиме составляет обычно не менее 74мкс. Таким образом, светодиоды в любом случае начнут случайным образом мигать тогда, когда от них этого не требуется, поэтому заменять кнопки светиками категорически не рекомендуется.
Ну а на сегодня всё. Желаю удачи при работе с ЖКИ и кнопками!
Источник: http://we.easyelectronics.ru/lcd_gfx/znakosinteziruyuschiy-zhki-1602-i-klaviatura-ekonomim-vyvody-mikrokontrollera.html
WinAVR: работа с ЖКИ
Продолжая опровергать миф о том, что WinAVR сложен и неудобен, в этой статье я расскажу о том, как просто и легко организуется вывод информации на символьные ЖКИ.
{ads2}Как обычно, начнем с традиционного скачивания архива с парой файлов. Это свободно распространяемая библиотечка-модуль (информация об авторе в комментариях сохранена), в которой я исправил несколько серьезных ошибок.
Правда, эти ошибки проявляются в довольно экзотических случаях, но я на это попал, поэтому вам предлагаю уже свободную от (этих) проблем версию.
Собственно говоря, это проявление плюса свободного ПО, к которому относится и WinAVR: возможность исправления багов оперативно и самостоятельно, в отличие от закрытого кода библиотек CVAVR.
Файл lcd.
c должен быть включен в список компилируемых файлов. Любители makefile должны вручную вписать его в строку с перечнем файлов исходных текстов проекта, пользователи AVR Studio добавляют этот файл при помощи меню, ну а любителям Eclipse повезло больше всех – им достаточно просто скопировать оба файла в папку своего проекта.
Файл lcd.
h, как могут догадаться читавшие предыдущую статью, служит для «настройки» модуля: в нем выбираются необходимые порты ввода-вывода, конкретизируются аппаратные особенности выбранного ЖКИ и делается ряд некоторых других настроек. Этот файл обязан быть в папке проекта и, кроме этого, должен подключаться директивой #include во все файлы, где будет требоваться работа с ЖКИ. Рассмотрим его содержимое подробно.
До 61-й строки находится информация, котрая никакой принципиальной роли не играет. Я не рекомендую вносить в нее какие-то правки, но подробно на ней останавливаться не намерен.
А вот с 61-й строки начинаются действительно важные вещи. Первый макрос в этой строке служит для выбора типа управляющего контроллера ЖКИ.
Модуль поддерживает два типа контроллеров: популярный HD44780 и чуть более редкий KS0073.
К сожалению, контроллер второго типа в моих руках никогда не был, и поэтому я могу лишь доверять разработчику модуля, а вот ЖКИ с HD44780 я тестировал лично, и могу гарантировать полную работоспособность всех функций.
Даолее я перечислю все важные макросы из файла lcd.h.
LCD_CONTROLLER_KS0073
Если в ЖКИ использован контроллер KS0073, задать значение макроса 1.
LCD_LINES
Число строк ЖКИ, может принимать значение 1,2,3 или 4.
LCD_DISP_LENGTH
Число позиций в строке ЖКИ. Должно соответствовать реальности.
LCD_LINE_LENGTH
Количество байтов встроенного ОЗУ контроллера на 1 строку. Обычно изменять не требуется, хотя для надежности стоит свериться с документацией на ваш ЖКИ – если там будет указано иное значение, нужно ввести его.
LCD_START_LINE1
Адрес начала первой строки во встроенном ОЗУ контроллера. Для всех известных мне ЖКИ всегда равно 0.
LCD_START_LINE2
Адрес начала второй строки. Обычно связано со значением LCD_LINE_LENGTH, однако, могут быть исключения, поэтому для страховки рекомендую свериться с документацией на ваш ЖКИ и при необходимости изменить это значение.
LCD_START_LINE3
Адрес начала третьей строки. Обычно равно LCD_START_LINE1 + LCD_DISP_LENGTH. Обратите внимание, что треться строка начинается раньше второй, т. е. является как бы продолжением первой. Такая вот экзотика – сверьтесь с документацией, чтобы убедиться, что в вашем ЖКИ именно так и есть.
LCD_START_LINE4
Адрес начала четвертой строки. Обычно равно LCD_START_LINE2 + LCD_DISP_LENGTH. Снова экзотика: четвертая строка есть продолжение второй.
LCD_WRAP_LINES
Как видите по предыдущим значениям, размещение символов в ОЗУ не совсем логично увязано с реальными строками на дисплее. Функции модуля lcd.
c могут автоматически осуществлять перенос текста на следующую строку, если он выходит за пределы текущей – не по ячейкам ОЗУ, а по позициям дисплея.
Если вам нужен такой автоперенос, установите значение этого макроса в 1, если вы самостоятельно будете контролировать вывод, оставьте нулевое значение.
LCD_IO_MODE
Некоторые МК имеют возможность работы с внешним адресным пространством, например, для расширения ОЗУ. ЖКИ может быть включен в это адресное пространство, и тогда значение этого макроса вы должны установить в 0.
В этом случае программная работа с ЖКИ будет вестись, как будто это какие-то ячейки в ОЗУ микроконтроллера. Значение по умолчанию подразумевает более традиционный способ работы через обычные порты ввода-вывода.
LCD_PORT PORTD
Порт микроконтроллера, к которому подключены сигналы ЖКИ.
LCD_DATA0_PORT, LCD_DATA1_PORT, LCD_DATA2_PORT, LCD_DATA3_PORT
ЖКИ для рассматриваемого модуля всегда подключается по 4-проводной схеме обмена данными. Четыре рассматриваемых макроса позволяют задать 4 разных порта МК для каждой из этих линий – просто укажите наименование портов, если нужно. А если у вас все 4 линии подключены к одному порту – оставьте все, как есть, тогда будет использовано значение LCD_PORT
LCD_DATA0_PIN, LCD_DATA1_PIN, LCD_DATA2_PIN, LCD_DATA3_PIN
4 линии данных ЖКИ могут подключаться к портам МК в произвольном порядке. При помощи этих макросов вы должны указать правильную распиновку.
LCD_RS_PORT, LCD_RS_PIN
Линия RS для ЖКИ может подключаться так же к произволной линии любого порта МК. Пара этих макросов служит для этого.
LCD_RW_PORT, LCD_RW_PIN
Линия RW для ЖКИ может подключаться так же к произволной линии любого порта МК. Пара этих макросов служит для этого.
LCD_E_PORT, LCD_E_PIN
Линия E для ЖКИ может подключаться так же к произволной линии любого порта МК. Пара этих макросов служит для этого.
Все макросы в оставшейся части файла изменять не нужно, во всяком случае до тех пор, пока вы не созреете до глубинных переделок в коде модуля.
{ads1}
Как видите, гибкость в настройках весьма впечатляющая. Благодаря возможности разбросать сигналы управления ЖКИ по любым ножкам микроконтроллера, вы можете добиться идеальной трассировки печатной платы.
Однако, такая гибкость оборачивается объемом кода и скоростью его работы, правда, все эти прибавки незначительные и в большинстве случаев ими можно пренебречь.
Для достижения минимального объема кода и максимального быстродействия вы будете должны обязательно расположить все сигналы управления на одном порту МК, причем сигналы линий данных должны быть расположены последовательно от младшего бита к старшему.
Закончив возню с распределением сигналов, можно приступать к рассмотрению имеющихся в модуле функций. Их прототипы приведены в конце файла lcd.h.
void lcd_init(uint8_t dispAttr)
Инициализация ЖКИ. Эта функция должна быть вызвана до всех остальных обращений к ЖКИ. В качестве параметра функция принимает одну из следующих констант:
LCD_DISP_OFF – дисплей выключен
LCD_DISP_ON – дисплей включен, курсор невидим
LCD_DISP_ON_CURSOR – дисплей включен, немигающий курсор видим
LCD_DISP_ON_CURSOR_BLINK – дисплей включен, виден мигающий курсор.
void lcd_clrscr(void)
Очистка дисплея. Все позиции дисплея заполняются пробелами, курсор устанавливается в начало первой строки.
void lcd_home(void)
Установка позиции курсора в первую позицию первой строки ЖКИ.
void lcd_gotoxy(uint8_t x, uint8_t y)
Установка курсора в указанную позицию. Значения x и y должны быть в допустимых пределах (см. LCD_LINES и LCD_DISP_LENGTH). Нумерация строк и позиций начинается с нуля.
void lcd_putc(char c)
Вывод одного символа в позицию курсора. После вывода позиция курсора автоматически смещается в следующую позицию по строке, а если задано LCD_WRAP_LINES == 1, то при достижении конца текущей строки курсор сместится в начало следующей.
void lcd_puts(const char *s)
Вывод строки на ЖКИ, начиная с текущей позиции курсора. При выводе может осуществляться автоматический перенос текста на следующую строку, если задано LCD_WRAP_LINES == 1. Кроме этого, встреченный символ '
' автоматически переводит курсор в начало следующей строки ЖКИ. После вывода курсор оказывается в следующей за последним символом строки позиции.
void lcd_puts_p(const char *progmem_s)
То же самое, что и lcd_puts, но для строки, хранящейся во flash микроконтроллера, т. е. в PROGMEM.
void lcd_command(uint8_t cmd)
Низкоуровневая функция отправки управляющей команды в контроллер ЖКИ.
void lcd_data(uint8_t data)
Низкоуровневая функция отправки данных в контроллер ЖКИ.
lcd_puts_P(s)
Макрос для удобного вывода строк, которые надо сохранить в PROGMEM. Идеология работы с данными во flash, принятая в WinAVR, требует, чтобы для сохранения строки «HELLO» во flash и последующего вывода ее на ЖКИ, мы выполнили следующее:
{code}PROGMEM char str[] = “HELLO”;
lcd_puts_p(str);{/code}
Если строка, выводимая на ЖКИ, повторно не будет использована в программе, можно воспользоваться макросом PSTR и сократить запись до lcd_puts_p(PSTR(“HELLO”)). А воспользовавшись макросом lcd_puts_P можно упростить запись еще больше: lcd_puts_P(“HELLO”);
В принципе, это все функции и макросы. Немного, но достаточно для всех нужд. Если вы располагаете МК с достаточно большим объемом ОЗУ и FLASH, можно совместить стандартный вывод при помощи семейства функций printf с рассматриваемым модулем. Для этого нужно сделать следующее.
Создаем новый исходный файл с названием, например, lcd_io.c (намек на com_io.c), в котором подключаем модуль стандартного ввода-вывода stdio.h и модуль поддержки ЖКИ lcd.h:
{code} #include
#include “lcd.h”{/code}
Теперь нам необходимо определить функцию потокового вывода одного символа так, чтобы символ выводился на наш дисплей:
{code} static int lcd_putchar(char c, FILE *stream){ lcd_putc(c); return 0;
}{/code}
Источник: https://simple-devices.ru/articles/7-soft/128-winavr-lcd-interface
CodeVision AVR. Вывод информации на ЖКИ. Использование библиотечных функций
Заголовочный файл LCD.h имеет в своем наборе функции для работы с ЖКИ дисплеем, которые связаны с библиотекой LCD.lib, написанной на ассемблере. Поэтому записывая одну функцию, выполняется целый ассемблерный код. Библиотеки облегчают труд программиста от написания постоянного, повторяющегося кода.
LCD.h библиотека позволяет работать с ЖКИ дисплеями до 40х2. Для работы с ЖКИ 40х4 используется библиотека LCD4x40.h т.к. она поддерживает работу на вторую управляющую линию Е2 (LCD display dual controllers). Таковым ЖКИ индикатором является модель фирмы Winstar WH4004A.
Ниже программный код позволяет выводить текст на ЖКИ дисплей 16х2. Испытывался на макетной плате с индикатором WH1602D-YYB-CTK и Atmega8535:
/****************************************************************/
/******************** LCD тест ЖКИ 16х02 **********************/
/****************************************************************/
#include<\p>
#include<\p>
#asm
.equ __lcd_port=0x12; PORTD /* ЖКИ дисплей подключили к порту I/O D*/
#endasm
void main(void) /* Основная функция “main”, с которой начинается выполнение всей программой процедуры */
{
lcd_init(16); /* инициализация на 16 символов */
lcd_clear(); /* очистка дисплея */
lcd_gotoxy(4,0); /* верхняя строка, 4 позиция */
lcd_putsf(“LCD 16×02”);/* выводим надпись в указанных координатах */
lcd_gotoxy(0,1); /* нижняя строка, 0 позиция */
lcd_putsf(“CodeVision1.25.3”);
while(1){}; /* бесконечный цикл */
Перед тем, как выводить строку на ЖКИ дисплей его нужно инициализировать. Для этого используемфункцию lcd_init:
lcd_init(unsigned char lcd_columns);
В скобках указываем, на сколько символов подключили ЖКИ индикатор:
lcd_init(8); /* инициализация на 8 символов */
lcd_init(16); /* инициализация на 16 символов */
lcd_init(20); /* инициализация на 20 символов */
lcd_init(40); /* инициализация на 40 символов */
Выполняем очистку дисплея. Используем функцию lcd_clear();
Ну вот, выполнили инициализацию, очистили предварительно индикатор, теперь можно и выводить. Хотя, lcd_gotoxy: пока еще нельзя. Перед тем, как выводить текст нужно указать, в какой строке выводить и с какой позиции, поэтому используем функцию:
lcd_gotoxy(unsigned char x, unsigned char y);
х – с какой позиции выводить первый символ (зависит от типа индикатора)
y – в какой строке (зависит от типа индикатора)
По данным заголовочного файла LCD.h имеем возможность выводить текст от 0 до 39 символов, и от 0 до 3 строк. Но в процессе использования выяснилось, что работает с ЖКИ индикаторами до 40х2 (Тип Winstar WH4002A). Использовать на индикатор WH4004A как правило, не получится.
Если, например, взяли индикатор 20х4 (Тип Winstar WH2004A/B), то для вывода текста с 10 позиции и 2-ой строке указываем в функции:
lcd_gotoxy(10,2);
Текст более 10 символов переведется на следующую строку. Текст выводим при помощи функции lcd_putsf():
lcd_putsf(char flash *str);
Текст, являющийся аргументом функции можно записывать непосредственно:
Lcd_putsf(“Hello World!”);
Если использовать переменную для хранения текста и последующей записи в функцию, то компилятор CodeVisionAVR определит как ошибку – параметр #1 типа 'unsigned char' несовместим с типом 'flash unsigned char*' указанный в объявлении функции 'lcd_putsf':
Unsigned char *txt=”Hello World!”;
Lcd_putsf(txt);
Функция для вывода текста на ЖКИ индикатор требующая определения текста в переменной – функция lcd_puts:
lcd_puts(char *str);
Тип переменой | Название | Размер, байт | значение |
char | символ | 1 | -128…127 |
Unsigned char | ASCII символ | 1 | 0…255 |
В виде кода, функция записывается следующим образом:
Unsigned char *dt=”Hello World!”;
/*или char *dt=”Hello World!”; */
Lcd_puts(dt);
Функция lcd_putchar(char c); позволяет выводить символы из Таблицы кодов символов:
lcd_putchar(0x41); /* символ английской буквы А */
lcd_putchar(0x5b); /* символ квадратная скобка [ */
lcd_putchar(0xff); /* символ заполненного знакоместа */
Ниже приведен програмный код, который заполняет нижнюю строку с позицией от 0 до 15 символов заполненного знакоместа из таблицы кодов (код символа 0xFF).
/************************ LCDprogresBar *****************************/
#include<\p>
#include<\p>
#include<\p>
#asm
.equ __lcd_port=0x12; PORTD /* ЖКИ дисплей подключили к порту I/O D */
#endasm
unsigned char j=0; /* определяем переменную для хранения положительного числа от 0 до 255 */
void main(void) /* Основная функция “main”, с которой начинается выполнение всей программой процедуры */
{
lcd_init(16);
lcd_clear();
lcd_gotoxy(1,0);
lcd_putsf(“Initialization”);
while(1) /* выполняем цикл пока оператор iF не выполнит условие j==16 */
{
delay_ms(500);
j++;
lcd_gotoxy(j-1,1); /* заполняем символом 2-ую строку от 0 до 15 */
lcd_putchar(0xff); /* Символ заполненного знакоместа из таблицы кодов символов */
if (j==16) {break;} /* если условие if выполнилось, то прерываем выполнение цикла while */
}
while(1){/* бесконечный цикл */};
}
Для того, чтобы выводить на ЖКИ индикатор русские буквы, применяется директива #pragma rl+/rl-:
/***********************************************************************/
#include<\p>
#include<\p>
#asm
.equ __lcd_port=0x12; PORTD
#endasm
void main(void)
{
lcd_init(16);
lcd_clear();
#pragma rl+
lcd_gotoxy(0,0);
lcd_putsf(“Индикатор 16х02”);
lcd_gotoxy(0,1);
lcd_putsf(“Тестирование ЖКИ”);
#pragma rl-
while(1){};
}
По сути, директива работает по переключению кодировки и собственно позволяет выводить русские буквы.
В ходе практической работы выяснилось, что без этой директивы русский текст отображается как набор непонятных «казябликов».
Что касается программы – симулятора Proteus (по крайней мере, проверенно в версии 7.2 и 7.5), то отсутствует поддержка вывода русского текста и большинства табличных символов.
Файлы к статье:
Проект LCD16x2 CodeVision 1.25.3 и Proteus 7.5
Проект LCD16x4 CodeVision 1.25.3 и Proteus 7.5
Проект LCD20x4 CodeVision 1.25.3 и Proteus 7.5
Проект LCD40x2 CodeVision 1.25.3 и Proteus 7.5
Проект LCDprogresBar CodeVision 1.25.3 и Proteus 7.5
Источник: http://radioded.ru/programmirovanie-na-si/codevision-avr-vyvod-informatsii-na-zhki-ispolzovanie-bibliotechnyh-funktsiy
Управление мультиплексными ЖКИ
Источник: https://pro-radio.ru/it-works/3458
CodeVision AVR. Вывод информации на ЖКИ. Использование библиотечных функций
Источник: http://mega-avr.ucoz.ru/publ/codevisionavr_out_information_in_display_library_function/1-1-0-5
Библиотека AVR GCC для управления ЖК индикатором – использование различных выводов микроконтроллера. Часть 1
» Схемы » Применение микроконтроллеров
28-12-2011
Примечание. Выборки исходного кода, размещенные в тексте описания, использовать в своих проектах не рекомендуется. В конце описания имеется ссылка на архив с полным исходным кодом к проекту.
Как вы знаете, предшествующая версия программной библиотеки компилятора AVR-GCC, предназначеная для работы с символьными ЖК индикаторами в 4- и 8-битном режиме, прекрасно зарекомендовала себя в работе.
Однако, она имеет некоторые ограничения, которые для некоторых пользователей могут стать причиной отказа от работы с библиотекой. Одно из них – ЖК индикатор должен быть подключен к одному порту микроконтроллера.
Например, в 8-битном режиме выводы индикатора LCD_D0…LCD_D7 должны быть байт-синхронизированы и подключены, скажем, к линиям PORTB микроконтроллера.
Такая же ситуация и при 4-битном режиме: выводы данных ЖК индикатора должны быть подключены к одному порту микроконтроллера, биты 4, 5, 6 и 7. Для двух режимов управления, сигналы управления RS, RW, E должны быть подключены также к одному порту.
И так работают большинство других программных библиотек, которые можно найти в Интернет. В реальности все может немного по другому.
Каждая линия вода/вывода микроконтроллера имеет, как минимум, несколько альтернативных функций (каналы АЦП, внешние прерывания, линии шины I2C, линии UART), и если в проекте используется одна из них или несколько, и требуется использование ЖК индикатора, стандартная библиотека работать не будет, и вы не сможете получить доступ ко всем линиям порта, к которому подключен ЖК индикатор. Вы должны будете использовать те линии ввода/вывода, которые остались свободными.
Для такого случая и была модифицирована библиотека. Она не переписывалась с нуля, была лишь изменена ее функциональность.
Принципы работы в 8- и 4-битном режиме при стандартном подключении индикатора не изменились, но были добавлены два режима работы: 8-битный режим при использовании разных портов микроконтроллера и 4-битный режим при использовании разных портов микроконтроллера. Эти режимы позволят управлять ЖК индикатором при наличии любых свободных выводов микроконтроллера.
Конфигурирование библиотеки для 4-битного режима
Давайте посмотрим, что необходимо выполнить для начала использования этих возможностей. Рассмотрим на простом примере при использовании разных выводов разных портов микроконтроллера.
Как видно из схемы, выводы индикатора подключены к микроконтроллеру Atmel AVR ATmega328P в следующем порядке:
RS → PB5
RW → PD1
E → PD2
D4 → PD4
D5 → PC2
D6 → PD6
D7 → PB0
Таким образом мы получаем, что сигналы данных и управления берутся от разных портов микроконтроллера и не являются байт-синхронизированными. Прежде всего, нам необходимо отредактировать назначение выводов в заголовочном файле lcd_lib.h, а перед этим исключить из комментариев одну из строк, которая определяет какой режим работы выбран:
//используется 4-битный режмим работы ЖК индикатора (при стандартном подключении индикатора к МК)//#define LCD_4BIT //используется 8-битный режмим работы ЖК индикатора (при стандартном подключении индикатора к МК)
//#define LCD_8BIT //
используется 4-битный режмим работы ЖК индикатора (при использовании разных выводов МК)#define LCD_4BIT_M//используется 8-битный режмим работы ЖК индикатора (при использовании разных выводов МК)
//#define LCD_8BIT_M
В нашем случае мы работаем в 4-битном режиме со смешанными выводами. Нам необходимо связать выводы индикатора в выводами порта микроконтроллера. Если сигнал управления индикатора RS подключен к порту PB5, то мы напишем 5:
#define LCD_RS 5 //вывод порта МК 5 подключен к LCD RS#define LCD_RW 1 //вывод порта МК 1 подключен к LCD R/W#define LCD_E 2 //вывод порта МК 2 подключен к LCD E#define LCD_D0 0 //вывод порта МК 0 подключен к LCD D0#define LCD_D1 1 //вывод порта МК 1 подключен к LCD D1#define LCD_D2 2 //вывод порта МК 2 подключен к LCD D2#define LCD_D3 3 //вывод порта МК 3 подключен к LCD D3#define LCD_D4 4 //вывод порта МК 4 подключен к LCD D4#define LCD_D5 2 //вывод порта МК 2 подключен к LCD D5
#define LCD_D6 6 //
вывод порта МК 6 подключен к LCD D6
#define LCD_D7 0 //вывод порта МК 0 подключен к LCD D7
И теперь мы должны определить порт и регистр направления данных для каждого вывода микроконтроллера. Так как выводы индикатора могут быть подключены к разным портам, нам нужно работать с индивидуальными выводами. Редактируем следующую часть:
#ifdef LCD_4BIT_M || LCD_8BIT_M //8-битный или 4-битный режим работы (при использовании разных выводов МК)#define LDPRS PORTB //назначаем порт для сигнала RS#define LDDRS DDRB#define LDPRW PORTD //назначаем порт для сигнала RW#define LDDRW DDRD
#define LDPE PORTD //назначаем<\p>порт для сигнала E#define LDDE DDRD
#define LDPD0 PORTD //назначаем<\p>порт для сигнала D0#define LDDD0 DDRD
#define LDPD1 PORTD //назначаем<\p>порт для сигнала D1#define LDDD1 DDRD
#define LDPD2 PORTD //назначаем<\p>порт для сигнала D2#define LDDD2 DDRD
#define LDPD3 PORTD //назначаем<\p>порт для сигнала D3#define LDDD3 DDRD
#define LDPD4 PORTD //назначаем<\p>порт для сигнала D4#define LDDD4 DDRD
#define LDPD5 PORTC //назначаем<\p>порт для сигнала D5#define LDDD5 DDRC
#define LDPD6 PORTD //назначаем<\p>порт для сигнала D6#define LDDD6 DDRD
#define LDPD7 PORTB //назначаем<\p>порт для сигнала D7#define LDDD7 DDRB
#endif
Часть 2 – Настройка библиотеки при 8-битном режиме работы
Редакция отказалась от публикации – публикация отказывается от Редакции. Выкладываю после небольшого редактирования; таких матералов при поисках в Сети мне не попадалось, пришлось разбираться самому. Многоразрядные ЖКИ (например, используемые в телефонах (несотовых), калькуляторах, в дисплеях на панелях сложных приборов) конструктивно выполнены для применения динамической индикации. На таких индикаторах, кроме собственно цифр, имеются изображения других (служебных) символов; они, как правило, снабжены собственным контроллером, диалог с которым возможен по тому или иному стандартному протоколу.
ru/indicator.html есть описание принципа действия ЖКИ индикаторов вообще, а также рассмотрена конструкция мультиплексного индикатора. Двенадцатиразрядный индикатор такого типа применяется в калькуляторах «CITIZEN». Конструкция одного из разрядов такого индикатора показана на рис.1. Все сегменты A, B, F всех 12 разрядов конструктивно объединены одним общим (прозрачным) электродом, вывод которого обозначен COM1. Сегменты C, E, G объединены электродом COM2, а D, «точки» каждого разряда и один для всех цифр знак «минус» (на рисунке не показан) – COM3. Каждое знакоместо имеет три вывода: объединены сегменты B, C, «точка» – вывод обозначен SEG3; A, G, D – вывод SEG2; и F, E, «минус» – SEG1. Таким образом, сформирована матричная структура, которой можно управлять. Электроды COM возбуждаются трёхуровневым сигналами, один цикл индикации составляет 6 тактов.
Следовательно, сигналы управления также должны быть инвертированы.На временных диаграммах показаны сигналы, которые необходимы и достаточны для индикации всех возможных состояний индикатора. На диаграмме 4 показаны эпюры напряжений, которые, будучи поданы на выводы SEG1,2,3 приведут к гашению всех сегментов. Это состояние обозначено символом 0. Зажигание сегмента обозначено символом 1 и все восемь возможных вариантов приведены на диаграммах 4 – 11. Если сигналы 9 – 11 будут поданы на выводы SEG так, как указано на рисунке, будет индицироваться цифра 0 (с децимальной точкой). Индицируемые сегменты выделены красным цветом, сегмент G и знак «минус» не индицируется, они обозначены черным цветом. Легко заметить, что включение егмента происходит только в те моменты, когда сигналы на выводах COM и SEG находятся в противофазе. Если сигналы синфазны, происходит гашение сегмента.
Встречаются индикаторы, имеющие два или четыре, а не три общих электрода. При этом цикл индикации будет равен четырём или восьми тактам соответственно. Очевидно, что схему управления мультиплексными индикаторами лучше всего делать на микроконтроллерах. Собирать схему на простой логике неоправданно по причине трудоёмкости и увеличения габаритов изделия. |
Индикаторы ЖКИ являются неотъемлемой частью радиоэлектронной аппаратуры для вывода различной информации. В этой статье поговорим о некоторых, наиболее применимых функциях библиотеки LCD.h. Заголовочный файл LCD.h имеет в своем наборе функции для работы с ЖКИ дисплеем, которые связаны с библиотекой LCD.lib, написанной на ассемблере. Поэтому записывая одну функцию, выполняется целый ассемблерный код. Библиотеки облегчают 'программерный’ труд программиста от написания постоянного, повторяющегося кода. Таковым ЖКИ индикатором является модель фирмы Winstar WH4004A. Ниже программный код позволяет выводить текст на ЖКИ дисплей 16х02. Испытывался на макетной плате с индикатором WH1602D-YYB-CTK и Atmega8535. /************************************************************************************/ void void /* Основная функция “main”, с которой начинается выполнение всей /* программой процедуры */ while 1 /* бесконечный цикл */ Пример в программе – симуляторе Proteus 7.5 SP3
lcd_init( unsigned char lcd_columns ); В скобках указываем, на сколько символов подключили ЖКИ индикатор: lcd_init( 8 ); /* инициализация на 8 символов */ Выполняем очистку индикатора. Используем функцию lcd_clear( ); Ну вот, выполнили инициализацию, очистили предварительно индикатор, теперь можно и выводить. Хотя, пока еще нельзя. Перед тем, как выводить текст нужно указать, в какой строке выводить и с какой позиции, поэтому используем функцию lcd_gotoxy: lcd_gotoxy( unsigned char x, unsigned char y ); х – с какой позиции выводить первый символ (зависит от типа индикатора)y – в какой строке (зависит от типа индикатора) По данным заголовочного файла LCD. h имеем возможность выводить текст от 0 до 39 символов, и от 0 до 3 строк. Но в процессе использования выяснилось, что работает с ЖКИ индикаторами до 40х02 ( Тип Winstar WH4002A ). Использовать на индикатор WH4004A как правило не получится.
lcd_gotoxy(10,2); Текст более 10 символов переведется на следующую строкуТекст выводим при помощи функции lcd_putsf: lcd_putsf( char flash *str ); Текст, являющийся аргументом функции можно записывать непосредственно: lcd_putsf( “Hello World!” ); Если использовать переменную для хранения текста и последующей записи в функцию, то компилятор CodeVision AVR определит как ошибку – параметр #1 типа 'unsigned char' несовместим с типом 'flash unsigned char*' указанный в объявлении функции 'lcd_putsf' : unsigned char *txt= “Hello World!”; Другая функция для вывода текста на ЖКИ индикатор требует определения текста в переменной – функция lcd_puts: lcd_puts( char *str ); unsigned char “Hello World!” /* или char *dt=”Hello World!”; */ Функция lcd_putchar( char c ); позволяет выводить символы из Таблицы кодов символов:
#include unsigned char j=0; /* определяем переменную для хранения положительного числа от 0 до 255 */ void main( void ) /* Основная функция “main”, с которой начинается выполнение всей /*программной процедуры */ { lcd_init( 16 ); lcd_clear( ); lcd_gotoxy( 1,0 ); lcd_putsf( “Initialization” ); delay_ms( 500 ); j++; lcd_gotoxy( j-1,1 ); /* заполняем символом 2-ую строку от 0 до 15 */ lcd_putchar( ); /* Символ заполненного знакоместа из таблицы кодов символов */ while( 1 ){ /* бесконечный цикл */ }; Для того, чтобы выводить на ЖКИ индикатор русские буквы, применяется директива #pragma rl+/rl-: #include #endasm void main( void ) { lcd_init( 16 ); lcd_clear( ); #pragma rl+ lcd_gotoxy( 0,0 ); while( 1 ){ }; } По сути директива работает по переключению кодировки и собственно позволяет выводить русские буквы. В ходе практической работы выяснилось, что без этой директивы русский текст отображается как набор непонятных «казябликов».
5), то отсутствует поддержка вывода русского текста и большинства табличных символов. Файлы Проект LCD16x02 CodeVision ver.1.25.3 и Proteus 7.5 Проект LCD16x04 CodeVision ver.1.25.3 и Proteus 7.5 Проект LCD20x04 CodeVision ver.1.25.3 и Proteus 7.5 Проект LCD40x02 CodeVision ver.1.25.3 и Proteus 7.5 Проект LCDprogresBar CodeVision ver.1.25.3 и Proteus 7.5 |
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться. |
Фрагменты обсуждения: | Полный вариант обсуждения » |
- Библиотека хороша, но, на мой взгляд, есть недоработка функции LCDstring, в которую я добавил перенос строки на следующую строчку дисплея если она не влезает, и если вторая строка дисплея есть. Мой код коряв, сразу предупреждаю. К тому же функция переписана исходя из того, что курсор в (0,0) Код: void LCDstring(uint8_t* data, uint8_t nBytes) //Outputs string to LCD { register uint8_t i; register uint8_t j=0; // check to make sure we have a good pointer if (!data) return; // print data for(i=0; i1) { if ((i>0) & (i%LCD_LINE_LENGTH==0)) { if (j
Источник: https://www.rlocman.ru/shem/schematics.html?di=112664