Схема динамической индикации для цифровых индикаторов. Ардуино: динамическая индикация. Способ с регистрами

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

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

Этому способствуют следующие их качества.

  • Низкая цена. В средствах индикации нет ничего дешевле светодиодных цифровых индикаторов.
  • Разнообразие размеров. Самые маленькие и самые большие индикаторы – светодиодные. Мне известны светодиодные индикаторы с высотой цифры от 2,5 мм, до 32 см.
  • Светятся в темноте. В некоторых приложениях это свойство чуть ли не решающее.
  • Имеют различные цвета свечения. Бывают даже двухцветные.
  • Достаточно малые токи управления. Современные светодиодные индикаторы могут подключаться к выводам микроконтроллеров без дополнительных ключей.
  • Допускают жесткие условия эксплуатации (температурный диапазон, высокая влажность, вибрации, агрессивные среды и т.п.). По этому качеству светодиодным индикаторам нет равных среди других типов элементов индикации.
  • Неограниченный срок службы.

Типы светодиодных индикаторов.

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

Сегменты обозначаются латинскими буквами от ”A” до ”H”.

Аноды или катоды каждого светодиода объединяются в индикаторе и образуют общий провод. Поэтому существуют индикаторы с общим анодом и общим катодом.

Светодиодный индикатор с общим анодом.

Светодиодный индикатор с общим катодом.

Статическое управление светодиодным индикатором.

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

Расчет резисторов такой же, как для отдельных светодиодов.

R = (U питания - U сегмента) / I сегмента

Для этой схемы: I сегмента = (5 – 1,5) / 1000 = 3,5 мА

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

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

Засветится сегмент, на управляющем выводе которого будет сформирован высокий уровень (5 В).

Мультиплексированный режим управления светодиодными (LED) индикаторами.

Для подключения каждого семисегментного индикатора к микроконтроллеру требуется восемь выводов. Если индикаторов (разрядов) 3 – 4, то задача становится практически не выполнимой. Просто не хватит выводов микроконтроллера. В этом случае индикаторы можно подключить в мультиплексированном режиме, в режиме динамической индикации.

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

Для подключения трех индикаторов потребовалось 11 выводов, а не 24, как при статическом режиме управления.

При динамической индикации в каждый момент времени горит только одна цифра. На общий вывод одного из разрядов подается сигнал высокого уровня (5 В), а на выводы сегментов поступают сигналы низкого уровня для тех сегментов, какие должны светиться в этом разряде. Через определенное время зажигается следующий разряд. На его общий вывод подается высокий уровень, а на выводы сегментов сигналы состояния для этого разряда. И так для всех разрядов в бесконечном цикле. Время цикла называется временем регенерации индикаторов. Если время регенерации достаточно мало, то человеческий глаз не заметит переключения разрядов. Будет казаться, что все разряды светятся постоянно. Для исключения мерцания индикаторов считается, что частота цикла регенерации должно быть не менее 70 Гц. Я стараюсь использовать не менее 100 Гц.

Схема динамической индикации для светодиодов с общим катодом выглядит так.

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

Расчет элементов динамической индикации светодиодных (LED) индикаторов.

Расчет несколько сложнее, чем для статического режима. В ходе расчета необходимо определить:

  • средний ток сегментов;
  • импульсный ток сегментов;
  • сопротивление резисторов сегментов;
  • импульсный ток общих выводов разрядов.

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

Выберем средний ток сегмента 1 мА.

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

I сегм. имп. = I сегм. средн. * N

Для нашей схемы I сегм. имп. = 1 * 3 = 3 мА.

Рассчитываем сопротивление резисторов, ограничивающих ток.

R = (U питания - U сегмента) / I сегм. имп.

R = (5 – 1,5) / 0.003 = 1166 Ом

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

I разряда имп. = I сегм. имп. * 8

Для нашей схемы I разряда имп. = 3 * 8 = 24 мА.

  • сопротивление резисторов выбираем 1,1 кОм;
  • выводы микроконтроллера управления сегментами должны обеспечивать ток не менее 3 мА;
  • выводы микроконтроллера выбора разряда индикатора должны обеспечивать ток не менее 24 мА.

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

Схемы с дополнительными ключами.

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

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

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

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

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

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

Ключи для индикаторов с повышенным напряжением питания .

Бывают индикаторы больших размеров, в которых каждый сегмент состоит из нескольких светодиодов, соединенных последовательно. Для питания таких индикаторов требуется источник с напряжением большим, чем 5 В. Ключи должны обеспечивать коммутацию повышенного напряжения с управлением от сигналов уровней микроконтроллера (обычно 5 В).

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

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

Между переключением разрядов индикатора на короткое время (1-5 мкс) должны выключаться все сегменты. Это время необходимо на завершение переходных процессов коммутации ключей.

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

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

Рубрика: . Вы можете добавить в закладки.

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

Количество соединительных проводников можно уменьшить, если заставить индикаторы работать в импульсном режиме. Человеческий глаз обладает инерционностью и если заставить индикаторы отображать информацию поочередно с достаточно большой скоростью, то человеку будет казаться, что все индикаторы отображают свою информацию непрерывно. В результате можно по одним и тем же проводникам поочередно передавать отображаемую информацию. Обычно достаточно частоты обновления информации 50 Гц, но лучше увеличить эту частоту до 100 Гц.

Давайте рассмотрим структурную схему включения семисегментных светодиодных индикаторов, приведенную на рисунке 1. Эта схема может обеспечить динамическую индикацию выдаваемой цифровой информации.


Рисунок 1. Структурная схема динамической индикации

В схеме, приведенной на рисунке 1, отображаются четыре цифровых разряда. Каждый разряд кратковременно подключается к своему входу коммутатора. Генератор служит для задания скорости обновления информации на индикаторах. Двоичный счетчик последовательно формирует четыре состояния схемы, а через ключи обеспечивает поочередную подачу питания на семисегментные индикаторы.

В результате, когда коммутатор подает двоично-десятичный код с входа A на входы семисегментного дешифратора, то этот код отображается на индикаторе HL1. Когда коммутатор подает на входы семисегментного дешифратора двоично-десятичный код с входа B, то этот код отображается на индикаторе HL2, и так далее, по циклу.

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

Во сколько же раз мы в результате уменьшили количество соединительных проводников? Это зависит от того, где мы проведем сечение схемы. Если мы на плате индикации оставим только индикаторы, то для их работы потребуется 7 информационных сигналов для сегментов и четыре коммутирующих сигнала. Всего 11 проводников. В статической схеме индикации нам потребовалось бы 7×4=28 проводников. Как видим, выигрыш налицо. При реализации 8-ми разрядного блока индикации выигрыш будет еще больше.

Еще больший выигрыш будет, если сечение схемы провести по входам индикаторов. В этом случае для четырехразрядного блока индикации потребуется только шесть сигнальных проводников и два проводника питания схемы. Однако такая точка сечения схемы динамической индикации применяется очень редко.

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


Как уже упоминалось ранее, для нормальной работы светодиода требуется ток от 3 до 10 мА. Зададимся минимальным током светодиода 3 мА. Однако при импульсном режиме работы яркость свечения индикатора падает в N раз, где коэффициент N равен скважности импульсов тока, подаваемых на этот индикатор.

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

I сег дин = I сег стат ×N = 3мА×8 = 24мА.

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

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

I кл = I сег дин ×N сег = 24мА×7 = 168мА.

Как вам такой ток?! В радиолюбительских схемах я часто встречаю решения, где коммутирующий ток берется непосредственно с выхода дешифратора, который не может выдать ток больше 20 мА, и задаю себе вопрос — а где смотреть такой индикатор? В полной темноте? Получается «прибор ночного видения», то есть прибор, показания которого видны только в полной темноте.

А теперь давайте рассмотрим принципиальную схему полученного блока индикации. Она приведена на рисунке 3.



Рисунок 3. Принципиальная схема блока динамической индикации

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

В качестве недостатка следует привести наличие больших импульсных токов, а так как любой проводник является антенной, то динамическая индикация служит мощным источником помех. Еще одним путем распространения помех является источник питания.

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

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

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

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

Литература:

Вместе со статьей "Динамическая индикация" читают:

Индикаторы предназначены для отображения различных видов информации для человека. Простейший вид информации - это...
http://сайт/digital/Indic.php

Газоразрядные индикаторы используются как для индикации битовой информации, так и для отображения десятичной информации. При построении десятичных индикаторов катод...
http://сайт/digital/GazIndic/

В настоящее время практически везде для отображения двоичной информации используются светодиоды. Это обусловлено тем...
http://сайт/digital/LED.php

Принципы работы жидкокристаллических индикаторов... Режимы работы жидкокристаллических индикаторов... Формирование цветного изображения...
http://сайт/digital/LCD.php

В одном из предыдущих уроков мы научились зажигать сегменты светодиодного индикатора. Хотя это можно сделать только с помощью Ардуино, мы использовали в нашем уроке дополнительный компонент — . Эта полезная микросхема сэкономила нам несколько ценных выводов микроконтроллера. Но один семисегментный индикатор почти бесполезен. Он ведь отображает всего одну цифру. А что если мы хотим вывести большое число, скажем, от 0 до 500? Нам потребуется целых три цифры, а значит и три индикатора. Как будем подключать их к контроллеру? Можем напрямую, но тогда мы займем 7*3 = 21 вывод! Это очень расточительно. К тому же, нужна будет уже другая плата, так как у Ардуино Уно просто не хватит цифровых выводов. Попробуем использовать сдвиговый регистр? Уже лучше. Теперь нам понадобится три регистра, объединенных в цепочку, а также три вывода Ардуино для управления ими. В общем то на этом можно бы было и остановить оптимизацию нашей схемы, но мы пойдем дальше. Обойдемся всего одним сдвиговым регистром!

Динамическая индикация

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

Подключение к Ардуино

В этом уроке мы используем три семисегментных индикатора с общим катодом. Нам также потребуется один сдвиговый регистр, подключенный одновременно ко всем индикаторам. Чтобы в каждый момент времени включать только один индикатор, используем три полевых транзистора, которые будут в нужный момент подключать катод к земле. Кстати, вместо трёх отдельных индикаторов лучше применять один трехцифровой индикатор. Суть схемы от этого не изменится, но проводов будет меньше! Принципиальная схема
Внешний вид макета
В качестве электронных ключей рекомендуем использовать транзисторы в корпусе TO92, например 2N7000. Для подключения каждого транзистора понадобится два резистора: на 100-150 Ом и на 2.2-10 кОм. Первый резистор призван защитить вывод контроллера от бросков тока, возникающих на затворе во время создания поля. Второй же резистор поможет быстро выключить ключ, когда мы подадим низкий уровень на соответствующий вывод контроллера (через него на землю сольется остаточный заряд затвора). На каждой линии от регистра к индикатору необходим токозадающий резистор 200-300 Ом, чтобы светодиоды в индикаторе не перегорели. Этот нюанс работы со светодиодами мы рассмотрели на . Тщательно собираем схему и переходим к программе. Программа для динамической индикации const byte digit_pins = {5,6,7}; const byte data_pin = 2; const byte sh_pin = 4; const byte st_pin = 3; unsigned long tm, next_flick; const unsigned int to_flick = 1; byte digit = 0; unsigned int counter = 125; const byte digits = { B11101110, B10000010, B11011100, B11010110, B10110010, B01110110, B01111110, B11000010, B11111110, B11110110 }; void fill(byte d){ for(char i=0; i<8; i++){ digitalWrite(sh_pin, LOW); digitalWrite(data_pin, digits[d] & (1< next_flick){ next_flick = tm + to_flick; digit++; if(digit == 3) digit = 0; setDigit(digit, counter); } } Часть этой программы, включая переменные data_pin , sh_pin , st_pin и функцию fill уже известны нам из . Массив digits хранит десять комбинаций сегментов для цифр от 0 до 9. Для экономии памяти мы храним каждую комбинацию в одном байте, а для лучшего понимания мы записали их в бинарном виде. Чтобы переключать индикаторы воспользуемся . Будем каждую миллисекунду заполнять регистр нужной комбинацией и включать соответствующий индикатор. Для этого мы используем функцию setDigit . Аргумент digit — это индекс включаемого в данный момент индикатора, а counter — трехзначное число, которые мы хотим высветить. Параметр to_flick отвечает за период переключения индикатора. Он равен 1, а значит смена цифр для отображения происходит каждую миллисекунду. Что если увеличить этот параметр? Скажем до 100мс, или даже до 500мс. Эффект инерции зрения пропадет и мы начнем замечать смену цифр. Программа счетчика с динамической индикацией В предыдущем примере переменная counter хранила число 125 по-умолчанию. Попробуем теперь добавить в программу счетчик секунд, чтобы counter увеличивался на единицу каждую секунду, вплоть до числа 999. const byte digit_pins = {5,6,7}; const byte data_pin = 2; const byte sh_pin = 4; const byte st_pin = 3; unsigned long tm, next_sec, next_flick; const unsigned int to_sec = 1000; const unsigned int to_flick = 1; unsigned int counter = 0; byte digit = 0; const byte digits = { B11101110, B10000010, B11011100, B11010110, B10110010, B01110110, B01111110, B11000010, B11111110, B11110110 }; void fill(byte d){ for(char i=0; i<8; i++){ digitalWrite(sh_pin, LOW); digitalWrite(data_pin, digits[d] & (1< next_sec){ next_sec = tm + to_sec; counter++; if(counter == 1000) counter = 0; } tm = millis(); if(tm > next_flick){ next_flick = tm + to_flick; digit++; if(digit == 3) digit = 0; setDigit(digit, counter); } } Загружаем программу на Ардуино и наблюдаем работу счетчика!

Задания

  1. Цифровой секундомер. Собрать схему с трехцифровым индикатором. Добавить в схему . При нажатии на кнопку, секундомер должен запускать отсчет. При повторном нажатии — останавливать. Дополнительно, к секундомеру можно добавить дробную часть, отображаемую на третьем индикаторе через точку.
  2. Цифровой вольтметр для напряжений от 0 до 10 Вольт. Собрать схему с трехцифровым индикатором. Добавить в схему делитель напряжения из двух резисторов на 10 кОм, подключенный к аналоговому входу Ардуино. Написать программу, которая будет каждые 100 мс считывать значение на аналоговом входе, переводить его в Вольты и выводить на индикатор. Для правильного отображения дробной части, необходимо подключить восьмой сегмент — точку.

Заключение

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

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


Для отображения четырехразрядного числа необходимо завести одну общую переменную в которой будет лежать число которое хотим вывести (переменная W ), четыре переменные в которых будут храниться данные для каждого знака (N ) и еще четыре переменные для промежуточных преобразований (M ), чтобы не трогать главную переменную. Переменная должна соответствовать тому значению, которое будет в ней хранитс я. Так для переменной W достаточным будет тип integer , так как переменная такого типа способна хр анить значения от -32768 до +32767 (или word если не планируется использование отрицательных чисел). В переменных N будут лежать числа от 0 до 9 поэтому достаточным будет использование переменной типа byte
. А в переменных M будут находиться те же значения что и в переменной W , поэтому ставим тип integer .

Dim W As Integer
Dim N1 As Byte
Dim N2 As Byte
Dim N3 As Byte
Dim N4 As Byte
Dim M1 As Integer
Dim M2 As Integer
Dim M3 As Integer
Dim M4 As Integer


После объявления переменных настраиваем порты на выход которые будут использоваться для подключения индикатора:

DDRC = &B11111111
DDRD = &B11111111


DDRC =& B 00001111 и DDRD = & B 01111111 (четыре первых ноги порта С под аноды и шесть первых порта D под сегменты).

Затем присваиваем переменной W то значение, которое собираемся вывести на индикатор:

W = 1234

"Arial","sans-serif""> В основном цикле программы присваиваем переменным М значение переменной W , я делаю так:

M1 = W
M2 = M1
M3 = M1
M4 = M1


"Arial","sans-serif""> Это не паранойя)), это сделано с той целью, чтобы в во всех переменных М лежало одно и тоже число, так как во время операции присваивания легко может ворваться прерывание (если такое имеется и не отключено), в обработчике которого переменная W может измениться. И в случае если присваивание шло таким образом: М1= W , M 2= W , M 3= W , M 4= W в переменных М будут лежать разные значения что приведет к каше в показаниях.

После присвоения переменным значения начинаем работать с
каждой из них, преобразуя таким образом, чтобы в переменную N попало то значение, которое будет
отображаться на индикаторе: в переменной
N 1 должна оказаться «1», в N 2 – «2», в N 3 – «3», а в N 4 – «4».

M1 = M1 / 1000 " M1 = 1234/1000 = 1,234
N1 = Abs (m1) " N1 = Abs (1,234) = 1

Abs – функция возвращающая целое число переменной.В переменную N 1 попала единица, что собственно и требовалось.

Для присвоения двойки переменной N 2 операция будет немного сложнее:

M2= M2 Mod 1000 " M2 =1234 Mod 1000 = 234
M2 = M2 / 100 " M2 = 234 / 100 = 2,34
N2= Abs (m2) " N2 = Abs (2,34) = 2

"Arial","sans-serif""> Для начала функцией Mod мы возвращаем переменной первые три
цифры числа (остаток от деления на 1000), а дальше все как в первом случае.

С двумя последними разрядами практически тоже самое:

M3 = M3 Mod100
M3 = M3 / 10
N3 = Abs (m3)

M4 = M4 Mod 10
N4= Abs (m4)


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

"Arial","sans-serif"">

Gosub Led

"Arial","sans-serif"">Процессор перепрыгнет на подпрограмму с меткой Led :

Led:

Portc = &B00001000

"Arial","sans-serif""> Здесь подаем высокий уровень на PORTC .3 , к этой ноге у нас подсоединен анод первого разряда. Затем выбираем, какие сегменты необходимо зажечь, чтобы отобразить значение первой переменной. Она у нас единица поэтому ноль будет на ногах Portd .1и Portd .2, что соответствует сегментам B и С индикатора.

Select Case N1









End Select
Waitms 5

"Arial","sans-serif""> После того как зажгли нужные сегменты ждем 5 мс и переходим к отображению следующих чисел:

Portc = &B00000100
Select Case N2
Case 0 : Portd = &B11000000
Case 1 : Portd = &B11111001
Case 2 : Portd = &B10100100
Case 3 : Portd = &B10110000
Case 4 : Portd = &B10011001
Case 5 : Portd = &B10010010
Case 6 : Portd = &B10000010
Case 7 : Portd = &B11111000
Case 8 : Portd = &B10000000
Case 9 : Portd = &B10010000
End Select

Waitms 5

Portc = &B00000010

Select Case N3
Case 0 : Portd = &B11000000
Case 1 : Portd = &B11111001
Case 2 : Portd = &B10100100
Case 3 : Portd = &B10110000
Case 4 : Portd = &B10011001
Case 5 : Portd = &B10010010
Case 6 : Portd = &B10000010
Case 7 : Portd = &B11111000
Case 8 : Portd = &B10000000
Case 9 : Portd = &B10010000
End Select

Waitms 5

Portc = &B00000001

Select Case N4
Case 0 : Portd = &B11000000
Case 1 : Portd = &B11111001
Case 2 : Portd = &B10100100
Case 3 : Portd = &B10110000
Case 4 : Portd = &B10011001
Case 5 : Portd = &B10010010
Case 6 : Portd = &B10000010
Case 7 : Portd = &B11111000
Case 8 : Portd = &B10000000
Case 9 : Portd = &B10010000
End Select

Waitms 5

"Arial","sans-serif""> После отображения информации на индикаторе необходимо возвратится в основной цикл программы, где нужно завершить цикл и обозначить конец программы.

"Arial","sans-serif"">Вот что получим в итоге:

"Arial","sans-serif"">

"Arial","sans-serif""> За счет маленькой задержки переключения не будут заметны человеческому глазу и мы увидим целое число 1234.

Скачать исходник и проект в протеусе можно ниже: "Arial","sans-serif"">

Программирование работы многоразрядного семисегментного индикатора



Алгоритм работы программы

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

Подключение многоразрядного семисегментного индикатора

Давайте еще раз посмотрим схему подключения многоразрядного семисегментного индикатора к микроконтроллеру:

На этой схеме выводы порта РВ (РВ0 — РВ7) микроконтроллера через токоограничительные резисторы подключены к соответствующим сегментам (a-g) многоразрядного семисегментного индикатора. Соответствующие сегменты всех разрядов индикатора соединены параллельно. Катоды (аноды) каждого разряда индикатора подключены через транзисторы к выводам порта PD.

Организация динамической индикации

Работа многоразрядного индикатора осуществляется следующим образом:

1. На управляющий транзистор первого разряда индикатора (7Seg1), с вывода порта микроконтроллера PD0 подается логическая единица, которая открывает транзистор, в результате чего подается напряжение питания на данный разряд индикатора. На базах остальных транзисторов — логический ноль, транзисторы закрыты.
2. На выводах порта РВ0-РВ7 выставляется двоичный код соответствующей десятичной цифры — высвечивается нужная цифра в первом разряде.
3. На управляющий транзистор второго разряда (7Seg2) с вывода порта PD1 подается логическая единица (на остальные транзисторы — логический ноль) — подается питание на второй разряд индикатора.
4. На выводах порта РВ0-РВ7 выставляется двоичный код следующей (второй) десятичной цифры — высвечивается нужная цифра во втором разряде.
5. На управляющий транзистор третьего разряда (7Seg3) с вывода порта PD2 подается логическая единица (на остальные транзисторы — логический ноль) — подается питание на третий разряд индикатора.
6. На выводах порта РВ0-РВ7 выставляется двоичный код следующей (третьей) десятичной цифры — высвечивается нужная цифра во втором разряде.
7. И так, по кругу

Такая работа многоразрядного семисегментного индикатора называется —динамическая индикация .
Частота переключения разрядов должна быть в пределах 100 герц, тогда не будет заметно мерцание разрядов.

Для переключения разрядов можно задействовать (на примере микроконтроллера ATtiny2313) таймер «TIMER 0 «.
Настройка таймера производится следующим образом (при тактовой частоте 1 мГц — заводская установка):
— предделитель таймера устанавливаем в СК/8
— вызов прерывания по переполнению счетчика таймера

Вот так настройка таймера выглядит в программе:
Где:
— SP — настройка стека
— Timer 0 — настройка параметров таймера
— TIMSK — настройка прерывания

Алгоритм работы программы

Рассмотрим алгоритм программы для осуществления динамической индикации и вывода данных в многоразрядный семисегментный индикатор:

Этот алгоритм, в принципе, иллюстрирует организацию динамической индикации данных на многоразрядном индикаторе. При этом надо учитывать, что при первом прерывании выполняется первый «прямоугольник», а затем происходит выход из подпрограммы, при втором прерывании выполняется второй «прямоугольник» и тоже выход из подпрограммы и при третьем прерывании — нижний «прямоугольник» с выходом из подпрограммы, и далее по кругу.

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

Программа индикации на многоразрядном семисегментном индикаторе

Как я уже писал в другой статье — , и чем продуманнее он будет написан, тем легче будет писать программу.

Назначение переменных:

Давайте посмотрим какие переменные для работы подпрограммы вывода данных на индикатор назначил я:

Data0, Data1 и Data2 — переменные, в которые основная программа записывает вычисленное значение (трехзначное)
Data — переменная, в которой записан адрес первой переменной данных — Data0
@Data — эта запись означает, что в переменной Data будет храниться адрес первой переменной данных — Data0
DataIndex — эта переменная хранит текущий номер переменной данных, которая выводилась на индикацию последней (0, 1 или 2, соответственно для Data0, Data1 или Data2)
PortDigits — эта переменная хранит данные о том, какой разряд индикатора зажигался последним

Настройка стека:

Стек настраивается в самом начале основной программы, мы его рассматривать не будем, так как к нашей подпрограмме он не относится

Настройка восьмиразрядного таймера Taimer0:

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

Настроенный таймер через определенные промежутки времени вызывает прерывание, в результате чего происходит остановка основной программы и осуществляется переход в подпрограмму обработки прерывания. В нашем случае — вызывается подпрограмма вывода данных на индикатор.
Как настраивается таймер: Частота переключения разрядов должна быть в пределах 100 Гц для предотвращения мерцания индикаторов при их поочередном зажигании (дело это в принципе индивидуальное, и зависит от особенностей вашего зрения).
Тактовая частота микроконтроллера — 1 мГц, или 1 000 000 Гц
Устанавливаем внутренний делитель частоты таймера в СК/8 — рабочая частота таймера будет в 8 раз меньше тактовой частоты микроконтроллера
Получаем: 1000 000/8 = 125 000 Гц, или 125 кГц — тактовая частота таймера
Настраиваем вызов прерывания по переполнению счетчика таймера (счетчик таймера восьмиразрядный и считает до 255, после этого сбрасывается в ноль и вызывается прерывание)
Получаем: 125 000/255 = 490 Гц (что соответствует времени приблизительно в 2 миллисекунды)
Мы поочередно зажигаем три разряда:
Получаем: 490/3 = 163 Гц — разряды индикатора будут переключаться с частотой 163 Гц.
Настройка таймера производится соответствующей настройкой соответствующих регистров таймера.
Давайте посмотрим как это происходит в Algorithm Builder:

Инициализация индикатора

Инициализация индикатора — эта фраза подразумевает настройку разрядов портов, к которым подключены выводы индикатора на вывод, а также обнуление переменных данных Data0…2 и запись первоначальных данных в остальные переменные. Процесс инициализации индикатора прописывается в начале основной программы.
Назовем подпрограмму инициализации Ini_Indikator2/
Давайте посмотрим этот процесс на примере:


В первой строке разряды порта РВ с 0 по 6 (к которым подключены семь сегментов индикатора) настраиваются на вывод информации (десятичную точку индикатора не используем).
Во второй строке разряды порта PD с 0 по 2 (к которым подключены управляющие транзисторы) также настраиваются на вывод.
Третьей строкой на выходах порта РВ устанавливается логический ноль — сегменты индикатора погашены для индикаторов с общим катодом).
Четвертая строка — обнуляем переменную DataIndex
Пятая строка — в переменную PortDigits записываем единицу
Следующие три строки — обнуляем переменные данных

Теперь нам необходимо куда-то записать которые будут подаваться на разряды порта PB для высвечивания соответствующей цифры на индикаторе.
В статье по программированию работы одноразрядного семисегментного индикатора, мы эти коды записывали программным путем в ОЗУ микроконтроллера. Сейчас мы сделаем по-другому — запишем двоичные коды в теле самой программы.
Для этого создадим таблицу двоичных кодов и присвоим ей имя, к примеру D0_9:

В этой таблице размещены двоичные коды (хотя и записаны в шестнадцатиричной системе) цифр от 0 до 9.

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

Подпрограмма вывода данных на многоразрядный семисегментный индикатор

Присвоим подпрограмме имя, к примеру Indikator2 , посмотрим на нее и разберем построчно:


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

В переменной DataIndex храниться номер ячейки памяти (0, 1 или 2) с данными (Data0, Data1 или Data2) которые необходимо вывести на разряд индикатора в текущий момент. Первоначально мы записали в нее ноль.
Первой строкой мы записываем содержимое DataIndex в регистр R20 , теперь в нем соответственно то-же ноль.
Во второй строчке мы увеличиваем содержимое регистра R20 на единицу (r20++) , теперь в R20 записана единица, означающая, что данные мы будем брать из переменной Data1. При втором прерывании R20 увеличится еще на единицу, станет равным 2, и соответственно следующие данные мы будем брать из переменной Data2. При следующем прерывании R20 станет равным 3.
Следующей строчкой (r20<3) мы проверяем какая цифра записана в регистре R20 — если меньше трех (0,1 или 2), то переходим по стрелке, а если равно трем, то обнуляем регистр R20 и данные теперь берем из переменной Data0.
Далее записываем содержимое R20 в переменную DataIndex .
Следующей командой @Data -> Y записываем адрес переменной Data0 в двойной регистр Y (R28, R29).
Затем складываем содержимое двойного регистра Y с содержимым R20 (0,1 или 2).
Командой [Y] -> r21 записываем содержимое переменной данных (или Data0, или Data1, или Data2 — в зависимости от значения r20) в рабочий регистр R21. Теперь в регистре R21 записана цифра из соответствующей переменной данных (к примеру цифра 5).
Следующей командой @D0_9*2 -> Z мы загружаем начальный адрес таблицы с двоичными кодами в двойной регистр Z (R30, R31). По начальному адресу у нас находится двоичный код для цифры 0.
Теперь мы складываем содержимое Z с R21 (с пятеркой) и получаем в регистре Z адрес в таблице двоичного кода с цифрой 5.
Следующей командой LPM[Z] -> R21 мы записываем двоичный код цифры 5 в рабочий регистр R21.
Команду NOP — холостой ход , можно и не прописывать — она вставлена для разделения отдельных кусков программы для наглядности.
Следующей командой PortDidgit -> R20 мы загружаем в рабочий регистр R20 содержимое переменной PortDidgit, а в нее мы предварительно записали единицу. Теперь в R20 записана единица (#b 0000 0001).
Следующей командой <Следующей командой R20 -> PortD мы подаем напряжение на второй разряд индикатора. При следующем прерывании произойдет еще один сдвиг влево (#b 0000 0100) и будет подключен третий разряд индикатора.
С помощью команды R20.3=1 записанной в овале, мы проверяем — достигла ли логическая единица при сдвигах третьего разряда регистра, и если — да, то записываем в R20 единицу (начинается новый круг).
Командой R21 -> PortB мы выводим двоичный код соответствующей цифры на подключенный разряд индикатора.
Командой R20 -> PortDigits — мы сохраняем текущее значение в переменной (последний зажженный разряд индикатора).