Сдвиговые регистры 74HC595 и 74HC165: подключение к Arduino

Как тремя выводами Arduino управлять сотнями выходов и опрашивать сотни датчиков: устройство, схемы включения и скорость работы регистров 74HC595 и 74HC165.
Когда выводов контроллера не хватает
Пока к Arduino подключено несколько светодиодов или реле, каждому достаётся свой вывод. Но с ростом проекта — десятки кнопок, индикаторов, шаговых двигателей, каждому из которых нужно минимум два сигнала, — 20 выводов Arduino UNO заканчиваются быстро, а со временем не хватает и MEGA. Сдвиговые регистры решают эту проблему: микросхема преобразует последовательный поток данных в параллельные уровни на выводах или наоборот, и для связи с контроллером достаточно трёх линий.
Самые распространённые регистры — выходной 74HC595 и входной 74HC165. Оба выпускаются в 16-выводных корпусах и имеют восемь разрядов. Больше выводов получают каскадированием: регистры соединяются цепочкой и передают данные друг другу. Теоретически длина каскада не ограничена.

| Разрядность параллельного входа (выхода) | 8 бит |
| Корпус | DIP-16 и SO-16 |
| Сигнальных линий для передачи данных | 3 |
| Время установки | 20 нс |
| Максимальная частота | 100 МГц |
| Напряжение питания | 5 В |
| Ток потребления | 40 мА |
Выводы 74HC595 и схема включения

- Q0–Q7 — выходы разрядов;
- VCC и GND — питание и земля;
- DS — вход последовательных данных (DATA): единица включает выход, ноль выключает;
- тактовый вход регистра сдвига (CLOCK) — отдельная линия синхронизации, которая избавляет от строгих таймингов, повышает помехоустойчивость и позволяет работать на любой скорости;
- тактовый вход регистра хранения, «защёлка» (LATCH) — после окончания передачи устанавливает уровни на всех восьми выходах одновременно;
- выход переноса — к нему подключается вход DS следующего регистра каскада; тактовые линии идут ко всем регистрам параллельно.

В примерах используются выводы Arduino 10 (DATA), 11 (LATCH) и 12 (CLOCK), но назначаются они программно и могут быть любыми. Порядок работы такой: защёлку опускают в низкий уровень один раз на весь каскад, по линии DATA синхронно с импульсами CLOCK передают по байту на каждый регистр, начиная с самого дальнего, затем защёлку поднимают. В этот момент биты появляются на выходах. Например, байт 0b01101001 установит единицу (+5 В) на Q0, нули на Q1 и Q2, единицу на Q3 и так далее — нулевой бит в записи байта находится справа.
Три способа передачи и их скорость
Самый простой вариант — встроенная функция shiftOut(): digitalWrite(LATCH_PIN, LOW), затем shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, x) и digitalWrite(LATCH_PIN, HIGH). Демонстрационный скетч раз в секунду выводит на восемь светодиодов очередной байт из набора шаблонов. На осциллограмме видно, как защёлка опускается и проходят восемь тактовых импульсов; вся передача занимает чуть более 101 мкс. Даже так каскад из 100 регистров, то есть 800 выходов, обновляется примерно за сотую долю секунды.

Быстрее работает прямое обращение к порту. На Arduino UNO с ATmega328 выводы 10, 11 и 12 соответствуют битам 2, 3 и 4 порта B; для других выводов или MEGA номера придётся изменить. Направление задаётся записью DDRB = 0b00011100, уровни меняются операциями вида PORTB |= 1 << NB и PORTB &= ~(1 << NB). Время передачи сокращается более чем в пять раз, но интервалы между тактами получаются неравными: функция bitRead() выполняется тем дольше, чем дальше бит от нулевой позиции.
Если заменить bitRead() сдвигаемой битовой маской, тактирование выравнивается, а байт передаётся за 8 мкс — в 12 раз быстрее стандартного способа. Каскад из 100 регистров обновляется менее чем за миллисекунду. Тем же приёмом делается бегущий огонь: единственный установленный бит сдвигается влево каждые 100 мс.
Входной регистр 74HC165
У 74HC165 вместо выходов восемь входов, к которым подключают бинарные датчики: кнопки, герконы, энкодеры, оптроны. Эти регистры тоже объединяются в каскады. Расположение выводов сильно отличается от 74HC595 — на прежних местах остались только выводы питания. Порядок работы: защёлку кратко опускают и сразу поднимают, фиксируя состояние входов, после чего каждый тактовый импульс выставляет на линии DATA очередной бит.
Стандартный способ чтения — функция shiftIn(DATA_PIN, CLOCK_PIN, MSBFIRST); вывод данных при этом настраивается как INPUT. Скетч раз в секунду считывает состояние восьми кнопок и печатает байт в двоичном виде в последовательный порт на скорости 9600. Чтение занимает 120 мкс; если расписать его через digitalRead() и digitalWrite(), оно становится даже немного быстрее. При работе напрямую через порт B (DDRB = 0b00011000, бит данных читается из PINB) время падает до 5,4 мкс, то есть в 22 раза. Сто регистров с 800 датчиками реально опрашивать около 2 тысяч раз в секунду.
Совместная работа и области применения
Входной и выходной регистры можно использовать вместе. Для динамического опроса двух матричных клавиатур 4х4 хватает по одной микросхеме каждого типа и четырёх выводов Arduino: линии DATA и CLOCK общие, LATCH у каждого регистра свой, а направление вывода DATA переключают между OUTPUT и INPUT. Полный цикл опроса 32 кнопок укладывается в 120 мкс. Тот же подход годится для нескольких каскадов на одном контроллере: общие DATA и CLOCK, выбор каскада — своей линией LATCH.
- Управление большим числом шаговых двигателей — например, в «часах из часов», где их от десятков до сотен и каждому нужны сигналы направления и шага.
- Динамическая индикация: у четырёхразрядного семисегментного индикатора от 11 до 13 выводов, и двух регистров хватает с запасом. Для светодиодных матриц регистры практически обязательны.
Описанные способы — программная имитация SPI. Аппаратным SPI регистрами тоже можно управлять, но на Arduino он один и привязан к конкретным выводам, поэтому его обычно оставляют для других устройств.