Драйвер 7-сегментного 4-знакового дисплея на двух 74HC595

Введение

При сборке электронных часов из моей предыдущей статьи мне несколько мешало то обстоятельство, что основная плата соединяется с платой дисплея аж целыми 12 проводами: 8 сигналов для переключения сегментов и 4 сигнала для переключения знакомест. В принципе, ничего особенного (шлейфы бывают и с гораздо большим количеством проводников), но я бы предпочёл это количество сократить.

Обычно в этих целях используют аппаратный драйвер, который размещается в непосредственной близости от дисплея и получает от микроконтроллера инструкции по 2-3 проводам (используются I2C, SPI или схожие протоколы, в том числе основанный на них бит бэнгинг). Итого вместе с проводами питания получается 4-5 проводников между платой контроллера и дисплеем. Например, популярным в наших краях вариантом для 7‑сегментных дисплеев является специализированная микросхема ТМ1637, которую можно приобрести отдельно или в составе модуля. Для неё, кстати, есть библиотека Ардуино от AlexGyver: https://alexgyver.ru/tm1637_display

Однако я решил сделать такой драйвер на двух микросхемах 74HC595 (как обычно, далее я буду называть их просто «595» или «микросхема 595»). Во-первых, они просты, универсальны, повсеместно распространены и есть под рукой у многих любителей микроконтроллеров (в том числе у меня). Во-вторых, мне просто интересно поработать с образованным двумя такими микросхемами 16-битным регистром, который будет переключать не только сегменты дисплея, но и знакоместа. В-третьих, в будущем я, возможно, буду использовать получившийся драйвер в качестве «игровой площадки» при изучении микроконтроллеров STM32 (для отработки передачи данных через аппаратный интерфейс SPI или его программно реализованный аналог).

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

Драйвер 7-сегментного 4-знакового дисплея на двух 74HC595, image #1

Соединение двух 74HC595

Вообще регистры по типу ввода и вывода разделяют на:

– SISO (serial in – serial out, последовательный вход – последовательный выход);

– SIPO (serial in – parallel out, последовательный вход – параллельный выход);

– PISO (parallel in – serial out, параллельный вход – последовательный выход);

– PIPO (parallel in – parallel out, параллельный вход – параллельный выход).

Каждая 595-я имеет два 8-битовых регистра: внутренний и внешний (выходной). Внутренний регистр работает по принципу SISO/SIPO, то есть принимает данные на последовательный вход и размещает их по 8 битам так, что они попадают на параллельные выходы, а со старшего бита – ещё и на последовательный выход. Внешний регистр работает по принципу PIPO, то есть принимает данные на параллельные входы и размещает их по 8 битам так, что они попадают на параллельные выходы. Данные параллельно передаются из внутреннего регистра во внешний при переключении уровня на 12 пине (LATCH) с низкого на высокий.

Такая структура, помимо прочего, позволяет соединять микросхемы между собой, удлиняя таким образом и соответствующие регистры. Для этого последовательный выход внутреннего регистра одной микросхемы (пин 9, Q7`) соединяется с последовательным входом внутреннего регистра другой микросхемы (пин 14, DATA). При этом пины 11-й (CLOCK, вход тактирующего сигнала, последовательно продвигающего данные во внутреннем регистре) и 12‑й (LATCH, вход сигнала защёлки, отправляющего данные из внутреннего регистра во внешний) каждой 595-й соединяются с источниками соответствующих сигналов (с выводами микроконтроллера), что обеспечивает синхронность cмещения данных в обеих микросхемах.

Так и сделаем. Теперь у нас есть два 16-битных регистра, всё так же внутренний и внешний. При этом верхняя по схеме микросхема (та, в которую поступают данные с микроконтроллера) хранит младший байт (биты 0-7) регистров, а нижняя по схеме – старший (биты 8-15). Поэтому я буду условно называть их «младшей» и «старшей» соответственно.

Управление дисплеем

В схеме аппаратного драйвера используется 7-сегментный 4-знаковый дисплей с общими катодами. В управлении дисплеем используется мультиплексирование, то есть в любой момент времени на дисплее в действительности включено только одно знакоместо, но из-за их быстрого переключения человеку кажется, будто цифры выводятся на все знакоместа одновременно. Знакоместа переключаются с помощью биполярных транзисторов, расположенных между «землёй» схемы и общими катодами дисплея.

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

4 из 8 выходов младшей микросхемы соединены с базами транзисторов, соединяющих общие катоды дисплея с «землёй» схемы. Таким образом, комбинация нулей и единиц, подаваемых на эти выходы, определяет, какие из четырёх знакомест дисплея включены, а какие выключены.

Битовые маски и их загрузка в регистр

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

Для управления дисплеем нужно загрузить битовую маску в регистр. Оба байта маски (сперва старший, затем младший) последовательно загружаются во внутренний регистр и затем одновременно выводятся во внешний. Для этого используется функция Ардуино shiftOut(), если вы используете бит бэнгинг, или метод SPI.transfer() из стандартной библиотеки Ардуино SPI.h, если вы используете аппаратный SPI.

Если смотреть на нумерацию битов в 16-битном регистре, то биты 0-7 переключают сегменты дисплея, а биты 9, 11, 13 и 15 переключают знакоместа. Биты 8, 10, 12 и 14 не имеют значения (соответствующие пины старшей 595-й ни к чему не подключены).

Однако здесь следует оговориться, что shiftOut() и, по умолчанию, SPI.transfer() передают по одному байту за раз. Поэтому в моём коде нумерация битов дана в пределах отдельно взятых байтов (старшего и младшего). Соответственно, по такой нумерации биты 0-7 младшего байта переключают сегменты дисплея, биты 1, 3, 5 и 7 старшего байта переключают знакоместа, а биты 0, 2, 4 и 6 старшего байта не имеют значения.

Прототип

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

Драйвер 7-сегментного 4-знакового дисплея на двух 74HC595, image #2
Драйвер 7-сегментного 4-знакового дисплея на двух 74HC595, image #3

Заметки на полях

Вообще говоря, китайцы умудряются делать модули драйвера 7-сегментного 4‑символьного дисплея из двух 595-х и без всяких транзисторов, и они вроде бы даже работают и не сгорают, несмотря на превышение указанных в даташите предельных токов. Не знаю, чем это обусловлено – то ли запасом прочности микросхемы, то ли тем, что такие модули строго рассчитаны на применение мультиплексирования и, соответственно, на снижение рабочего цикла каждого выходного пина. Лично я предпочитаю использовать коммутирующие транзисторы, поскольку они гарантированно и преспокойно выдерживают нужный ток.

45 views·2 shares