Найти тему
Разумный мир

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

Оглавление

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

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

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

Устройство и работа матричных индикаторов

Внутренний мир таких индикаторов прост, если не рассматривать модели с встроенным контроллером. Светодиоды действительно собраны в матрицу

-2

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

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

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

В результате можно получить изображение различных символов, например так (для матрицы 8х5)

Пример формирования символов из отдельных точек. Иллюстрация моя
Пример формирования символов из отдельных точек. Иллюстрация моя

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

Вывод символьной информации

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

Аппаратное решение для отображения символа на матричном индикаторе. Иллюстрация моя
Аппаратное решение для отображения символа на матричном индикаторе. Иллюстрация моя

Генератор G и двоичный счетчик СТ2 обеспечивают динамическую индикацию непрерывно перебирая строки индикатора через дешифратор DC. У нас индикатор состоит из 8 строк, поэтому счетчик 3-разрядный. Код символа поступает на старшие разряды адреса ПЗУ, которое выполняет роль знакогенератора. Младшие разряды адреса ПЗУ перебираются счетчиком динамической индикации.

У нас индикатор состоит из 8 столбцов, поэтому и выход ПЗУ должен быть 8-разрядным. И каждый символ в ПЗУ-знакогенераторе занимает 8 байт. А всего емкость ПЗУ должна быть 2048 байт, если нужно отображение всех 256 символов.

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

Здесь нет ничего сложного. Определяется таблица знакогенератора, которая соответствует ПЗУ в аппаратном решении. Отображаемый символ хранится в глобальной переменной. Предполагается, что есть два 8-битных порта, которые подключены к индикатору (возможно, через дополнительные ключи). Так же предполагается, что микроконтроллер уже настроен.

Вся работа выполняется в процедуре обработки прерывания от таймера. Так как у нам 8 строк, а минимальная частота динамической индикации 50 Гц (20 мс), то период между прерываниями таймера не должен превышать 2.5 мс.

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

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

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

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

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

Второй, выделить в ОЗУ дополнительный буфер размером 8 байт (для нашего примера). В этот буфер основная программа скопирует информацию о символе. Теперь не нужен ни код символа, ни дополнительный указатель. Мы будем в DispSrv использовать этот буфер в ОЗУ.

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

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

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

Немного о схемотехнике управления индикатором

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

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

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

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

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

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

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

Действительно, если взять 4-разрядный дисплей, то, с учетом того, что для одного разряда индикация уже 1:8, кратность составит 32. Это уже не получится скомпенсировать увеличением тока через светодиоды.

Нам на помощь приходят сдвиговые регистры с параллельным выходом. Можно использовать классические популярные 74HC595, но еще лучше будут MBI5167, MBI5168, STP08DP05 (и им подобные), о которых я говорил в статье "Драйверы светодиодов и 7-сегментные светодиодные индикаторы". Они и предназначены для подобного применения.

Построение многоразрядного дисплея на матричных индикаторах. Иллюстрация моя
Построение многоразрядного дисплея на матричных индикаторах. Иллюстрация моя

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

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

COL_PORT=buf[cnt];

на цикл сдвига для загрузки в регистры.

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

А что насчет быстродействия. Специализированный драйвер STP08DP05 допускает частоту тактирования до 50 МГц, так что тут особых проблем не будет. А вот для микроконтроллера не все так радужно. Да, можно использовать максимальную тактовую частоту, на которой он может работать, но количество машинных циклов, которые использует обработчик прерывания существенно возрастает с увеличением разрядности дисплея.

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

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

Многострочные многоразрядные дисплеи и графические дисплеи

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

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

Что же касается графических дисплеев, то это надмножество многострочных многоразрядных дисплеев, в которых знакогенератор, обычно, отсутствует. Зато есть большое ОЗУ, которое непрерывно сканируется контроллером дисплея для вывода ни индикатор. Так же, как я описал выше.

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

И вот такой "дисплей из кусочков", только небольшого размера, вполне можно построить используя то, что написано в статье. Только вот стоит ли это делать? По моему - нет. Большой или графический дисплей лучше приобрести готовый.

Заключение

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

До новых встреч!