Динамическая индикация: экономим выводы МК

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

Рассмотрим самый обычный светодиод. Чем-то он похож на обычную лампочку накаливания — если через него пропустить ток, то он начнет излучать свет. На этом сходство заканчивается. У светодиода есть анод и катод, и для того, чтобы он начал излучать свет, необходимо анод подключить к плюсу источника тока, а катод к минусу. Если перепутать полярность, то ни чего страшного не произойдет (кроме отдельных случаев, которые мы сейчас рассматривать не будем), просто светодиод не будет светиться. Это, собственно, и демонстрирует следующая картинка, не первой схеме светодиод не горит, так как неправильно установлена батарейка, на второй это поправили:

Следует обратить внимание на токоограничивающий резистор R1 (или R2). Для чего он нужен, расскажу в одной из следующих статей.

Возьмем теперь восемь светодиодов и соединим их катоды вместе, а аноды от каждого оставим свободными. Или наоборот, аноды светодиодов соединим в одной точке, а катоды трогать не будем. Каждый светодиод обзовем своей буквой, а именно A, B, C, D, E, F, G и DP. Затем, расположим их так, как показано на рисунке и засунем в корпус:

Вот у нас и получился светодиодный семисегментный индикатор с десятичной точкой, которая обозначается как DP или H, с общим катодом или общим анодом.

Рассмотрим индикатор с общим катодом (Common Cathode). Чтобы вывести, например, цифру «1», нужно зажечь сегменты B и С (см. картинку выше). Для этого общий провод (тот, к которому все светодиоды подключены одним концом) цепляем на минус источника тока, а сегменты B и C на плюс, т.е. сегменты в таком индикаторе зажигаются плюсом источника тока. При этом остальные сегменты можно ни куда не подключать, либо повесить на минус. Таким образом, включая нужные сегменты, можно отобразить любую цифру от 0 до 9, некоторые символы и буквы.

 

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

Давайте теперь посчитаем ноги. Для управления одним семисегментным индикатором нужно 8 ног микроконтроллера (7 сегментов и 1 десятичная точка). 2 индикатора — 2*8=16 ног, 4 индикатора — 4*8=32. Как-то грустно… Для того, чтобы сделать электронные часы, нужно минимум 4-ре индикатора, а у AVR-ке в большом корпусе DIP-40 как раз 32 порта ввода-вывода. Даже кнопки прицепить некуда. Но выход есть! (нет, не в окно)

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

Все одноименные сегменты соединены вместе, а общие выводы оставлены как есть. А как же теперь управлять этими индикаторами? На просторах интернета нашел 2 отличные gif-ки, которые отображают суть процесса:

То есть, на общем проводе интересующей нас цифре устанавливаем активный уровень (для Common Cathode подключаем к минусу, Common Anode к плюсу) и зажигаем нужные сегменты. Такой тип индикации называется динамический. Возникает вопрос: а как сделать, чтобы горели все цифры, а не только одна, да еще чтоб каждая показывала что-то свое? Ведь одновременно мы уже не модем зажигать все цифры в таком включении. Да, одновременно не можем, но это и не надо. Если мы будем очень быстро переключать цифры, как показано на gif-ках, то для глазу человека будет казаться, что все они горят одновременно! Уже при 25 герцах можно без проблем прочитать все значение целиком. А если сделать частоту 100 Гц, то проблемы вообще не будет.

Посчитаем теперь количество выводов микроконтроллера, которое необходимо задействовать в такой схеме включения индикаторов. На 2-е цифры на мнужно 8+2=10 выводов, 8 для сегментов (7, если нам не нужна десятичная точка) и 2 общих провода от каждой цифры; для 4-х цифр 8+4=12 выводов. То есть каждая дополнительная цифра прибавляет только один дополнительный вывод, а не 8. Промышленностью выпускаются готовые индикаторы на 2, 3, 4 и так далее цифр, имеющие внутри все необходимые соединения для динамической индикации, наружу торчит только то, что надо, самому что-то соединять нет необходимости. Красота!

Правда есть один небольшой минус. Если у нас 4-ре цифры, то каждая будет гореть только 1/4 времени от полного цикла обновления (эдакий ШИМ с заполнением 25%), что негативно сказывается на яркости индикации, поэтому, если стоИт задача получить максимально яркое свечение индикатора, этот способ не прокатит. Устранить эту проблему можно уменьшением номинала токоограничительных резисторов каждой группы сегментов, но тут нельзя выходить за максимальное импульсное значение силы тока через сегмент.

Так, с принципами разобрались, перейдем теперь к схемотехнике и программированию.

  • Исходные условия: в наличии имеем семисегментный индикатор на 4-ре цифры для динамической индикации и микроконтроллер AVR ATMega16.
  • Задача: подключить этот индикатор к AVR-ке, написать управляющую программу, которая будет иметь возможность вывода произвольного числового значения на дисплей.

Поехали. Для начала в Proteus-e нарисуем вот такую схему:

Проще некуда: сегменты подключены к выводам PD0-PD7 микроконтроллера, цифры к PC0-PC3.

Перейдем теперь в Atmel Studio. Создадим новый проект, выберем микроконтроллер atmega16.

Где-нибудь вначале файла напишем define-ы, которые будут определять, куда подключен наш индикатор

Теперь поговорим немного об алгоритме. Я предлагаю следующий. У нас будет функция, которая будет вызываться с частотой 400 Гц. В ней мы будем выполнять следующие действия:

  1. гасим все индикаторы;
  2. выводим на порт, к которому подключены сегменты, необходимое значение, которое должна отображать цифра с номером led_index;
  3. зажигаем цифру led_index;
  4. увеличиваем led_index на единицу;
  5. если led_index стал больше количества цифр индикатора, то обнуляем его.

Таким образом, мы будем перебирать все цифры индикатора с частотой 400 Гц, и так как у нас 4-е цифры, то частота обновление всего дисплея полностью будет составлять 100 Гц.

Напишем необходимые функции

Ну и функция main:

Смотрим результат в симуляторе:

Все работает!

Однако, такой способ заполнения буфера дисплея не очень удобен, надо помнить, какие сегменты куда подключены и вообще, из каких сегментов состоит тот или иной символ. Давайте решим это неудобство одной простой функцией, которая на вход будет принимать 2 параметра: номер цифры и число от 0 до 9, которое мы хотим вывести.

 

Теперь main выглядит так:

 

Ну и демонстрация работы:

Теперь можно даже так:

Результат:

На этом пока все! В следующей статье разберемся с кнопками и посмотрим, как там можно сэкономить.

Архив с программой и моделями Proteus: https://yadi.sk/d/s-E3BAQL3NkGnz

 

Метки: , , . Закладка Постоянная ссылка.

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *