Программное управление простым семиcегментным ЖКИ

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

Вопрос целесообразности такого применения я здесь не затрагиваю и оставляю читателю возможность ответить на него самому.

часы-будильник

Цель статьи – показать возможность управления ЖКИ без применения специализированных аппаратных средств на примере реализованной конструкции. Автору удалось изготовить в конце 2013 года часы-будильник (фото справа) со встроенным термометром на базе Atmega8515L, который выполнает все функции устройства, кроме измерения температуры. Для этой цели применен цифровой датчик температуры ADT7301.

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

Собственно, что же побудило меня взяться за изготовления комнатного термометра, да еще и таким извратным способом? Этому способствало наличие свободного времени и соответствующих даровых компонентов, т.е. «спасенных» из радиохлама ЖКИ, МК и некоторой прочей мелочи. Семисегментный четырехзначный ЖКИ извлечен из напольных бытовых весов, МК AT90S8515 — из вышедшего из строя многоканального модуля АЦП.

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

Один из них — применение переменного электрического поля для исключения деградации дисплея. Кратко остановимся на этом моменте.

диаграмма напряжений на электродах ЖКИ

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

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

Исходя из приведённых графиков формулируем задачу:

  1. 1) напряжение на общем электроде (COM) всегда симметрично-переменное, в нашем случае имеет форму меандра (т.е. прямоугольного сигнала с равными длительностями высокого и низкого значения);
  2. 2) напряжение на электроде неактивного (невидимого) сегмента имеет ту же фазу, что и напряжение на ОЭ;
  3. 3) напряжение на электроде активного (видимого) сегмента имеет противоположную фазу, относительно ОЭ.

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

схема подключения ЖКИ к микроконтроллеру

Соединения между МК и ЖКИ выбраны из удобства разводки в одном слое, поэтому имеет место «каша» в соответствии выходных портов отдельным сегментам ЖКИ. Четвертое (самое левое) знакоместо сокращено до трех сегментов для вывода «1» или «Минус».

Конечно было бы намного проще управлять сегментами, если бы они были подключены по принципу: одному знакоместу — один порт ввода-вывода, одинаковым сегментам – одинаковые биты. А поскольку выбран другой путь, то придется вводить в программу МК специальные функции преобразования.

Давайте рассмотрим, какие же програмные функции необходимы вообще для всего устройства и в частности – для управления ЖКИ.

Не заостряя внимание на все начальные инициализации самого МК, вырисовываются такие основные задачи:

  1. управление и обмен данными с датчиком температуры;
  2. усреднение и преобразование значений температуры;
  3. преобразование чисел в символы семисегментного индикатора;
  4. и самое главное – программный драйвер ЖКИ.

Собственно, пункты 2 и 3 — довольно банальная задача для конструкторов цифровых термометров, публикаций которых в интернете предостаточно. Пункт 1 относится к ним же, с той лишь разницей, что применен не широкораспространенный DS18x20 или LM75, а ADT7301. Поэтому я заострю все внимание на последнем пункте, который придется разложить еще на несколько.

Как я уже упоминал выше, для точного по времени переключения выходов МК задействован аппаратный таймер Т0, переполнения которого (а значит и прерывания) происходят около 64 раз в секунду, таким образом обеспечивая частоту регенерации ЖКИ в примерно 32 Гц, которая вписывается в рекомендуемый многими производителями диапазон.

Я безуспешно пытался задействовать «часовой» кварцевый резонатор (32768 Гц) с этим МК, чтобы получить точную частоту, поэтому-то и «около 64» из-за использования кварца на 2 МГц – самого низкочастотного из имевшихся в наличии, который стабильно заработал.

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

Выводимые данные представлены двумя наборами: прямым и инверсным, для каждого полупериода и хранятся они в младших регистрах общего назначения (РОН). То есть для каждого из портов имеется пара регистров, например RPB и _RPB (регистр порта Б). Понятно, что содержимое _RPB является битовой инверсией RPB. А вот его значения имеют непростую историю!

Вернемся же к началу цепочки данных — к их источнику. Как я уже упоминал выше, числовое представление температуры преобразовывается в соответствующие коды семисегментного индикатора. Теперь нам нужно перенести биты этих кодов в соответствующие позиции регистров RPA, RPB, RPC и RPB. Чтобы этот перенос упростить, насколько это возможно, нужно внимательно изучить таблицу соответствия. Я ее получил при помощи экспорта Netlist из EAGLE-схемы. Увы, много совпадений не оказалось, но и та малая их часть несколько упростит преобразование: сегменты 1A и 2A соответствуют 5 биту своих портов. Также довольно удачно попало самое правое знакоместо, оно полностью подключено в порту С, хотя значения сегментов не подряд. Я в определениях проекта эту особенность учту, приписывая сегментам нужные битовые значения. Все остальные значения придётся перетасовывать, маскируя и сдвигая на нужную позицию, либо применять команды копирования битов через флаг Т регистра состояния SREG. Второй путь в моем примере оказался даже короче.

Это и есть самая емкая по времени задача. В предыдущем проекте она занимает 56 инструкций.

В конечном итоге необходимо еще учесть текущее состояние линий, используемых для прочей периферии, здесь PB2 – PB7. Это нужно для того, чтобы при выводе значений на ЖКИ не сменить состояние, например, канала связи с датчиком.

Ну и под конец – создать инверсные пары, так же с учетом текущего состояния PB2 – PB7. Временной момент записи этих пар регистров (RPx и _RPx) немаловажен. Их состояние должно смениться до прихода прерывания Т0, т.е. до вывода в ЖКИ, поскольку неполностью завершенная конвертация нарушит регенерацию дисплея. Поэтому имеет смысл производить запись в ответственные регистры сразу после их вывода. Для этого в главном цикле я предусмотрел точку «сна», из которой МК пробуждается таймером и последующие операции цикла выполняются непосредственно за обработчиком прерывания. Мало того, я еще ввел сравнение результатов последних двух измерений, чтобы не производить лишних преобразований в случае равенства текущей и предыдущей температур. Это сокращает время выполнения главного цикла и увеличивает время «сна» МК, а так же уменьшает потребление энергии.

Теперь обработчик прерывания таймера может попеременно выводить в порты прямые и инверсные значения. В оставшееся время в обработчике еще будет производиться подсчет времени, чтобы в заданные моменты будить и опрашивать датчик температуры, и другие возможные события.

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

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

Скачать архив с исходниками

В архиве есть также фотографии процесса разработки и конечного устройства.

Вопросы, как всегда, в форум.

Добавить комментарий