View Categories

Сдвиговый регистр 74HC595

Сдвиговый регистр - логическая схема, которая позволяет хранить данные и "сдвигать" их вдоль ячеек. В данном случае рассматриваем 74HC595 - сдвиговый регистр с последовательным входом и параллельным выходом. Её можно использовать как расширитель пинов для Arduino - микросхема подключается к трём пинам МК и образует 8 цифровых выходов. Микросхемы можно подключать друг к другу "паравозиком", что даёт возможность получить практически неограниченное количество цифровых выходов, управляемых по трём проводам!

В наборе GyverKIT START IOT EXTRA
Сдвиговый регистр

Характеристики:

  • Интерфейс: SPI
  • Макс. скорость: 25 MHz (VCC 4.5V), 5 MHz (VCC 2V)
  • Напряжение питания: 0.. 7 V
  • Макс. ток пина: 35 мА
  • Макс. ток всего чипа: 70 мА

Подключение к Arduino #

Связанные уроки

  • Пины DS и SHCP (передача данных, дата и клок) подключаются к любым цифровым пинам, либо к выводам MOSI и CLK аппаратной шины SPI для более высокой скорости передачи данных. Далее по тексту буду называть их DATA и CLOCK, как в SPI
  • Пин STCP (скопировать из регистра сдвига в регистр хранения) - на любой цифровой пин. По сути он тут играет роль CS, как в SPI, дальше буду называть его так
  • Дополнительно пин OE (отвечает за состояние выходов) я подключил к GND - сразу их включим
  • Пин MR (сброс памяти) - подключаем к VCC, чтобы регистр запоминал отправленные ему данные

Вот так может выглядеть подключение вместе со светодиодами для демонстрации работы:

Я подключил дату и клок на SPI для примера (пины MOSI D11 и CLK D13 на Нано) - будем управлять и так и так.

И вот в симуляторе (ссылка на проект) я подключил два сдвиговика к тем же пинам - можно открыть проект и поэкспериментировать. Светодиоды подключены слева направо к выходам 0.. 7. Слева находится сдвиговик, подключенный в цепочку первым:

Программирование #

Вручную #

Связанные уроки

Отправка происходит следующим образом, как по шине SPI:

  1. Подать на CS LOW сигнал
  2. Для всех битов данных:
  • Подать на DATA соответствующий биту сигнал (HIGH/LOW)
  • "Дёрнуть" CLOCK вверх и вниз (HIGH, LOW)
  1. Подать на CS HIGH сигнал - в этот момент отправленные данные появятся на выходных пинах
#define CS_595 10
#define DAT_595 11
#define CLK_595 13

void setup() {
  pinMode(CS_595, OUTPUT);
  pinMode(DAT_595, OUTPUT);
  pinMode(CLK_595, OUTPUT);

  // данные для отправки
  bool data[] = {1, 1, 0, 0, 1, 0, 0, 1};

  digitalWrite(CS_595, LOW);    // #1

  for (int i = 0; i < sizeof(data); i++) {  // #2
    digitalWrite(DAT_595, data[i]);
    delayMicroseconds(5);
    digitalWrite(CLK_595, HIGH);
    delayMicroseconds(5);
    digitalWrite(CLK_595, LOW);
  }

  digitalWrite(CS_595, HIGH);   // #3
}

void loop() {
}

При отправке каждого бита данные "сдвигаются" вдоль регистра, поэтому отправленные первыми биты будут в конце (справа):

А вот что получится, если отправить массив {1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}:

ShiftOut #

Связанные уроки

В Arduino есть готовая функция для отправки байтов данных по программному SPI - внутри там почти то же самое, что мы написали выше:

#define CS_595 10
#define DAT_595 11
#define CLK_595 13

void setup() {
  pinMode(CS_595, OUTPUT);
  pinMode(DAT_595, OUTPUT);
  pinMode(CLK_595, OUTPUT);

  digitalWrite(CS_595, LOW);
  shiftOut(DAT_595, CLK_595, MSBFIRST, 0b11001111);
  shiftOut(DAT_595, CLK_595, MSBFIRST, 0);
  digitalWrite(CS_595, HIGH);
}

void loop() {
}

SPI #

Теперь то же самое через аппаратный SPI:

#define CS_595 10
#define DAT_595 11
#define CLK_595 13

#include <SPI.h>

void setup() {
  pinMode(CS_595, OUTPUT);

  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));  // 1 MHz

  digitalWrite(CS_595, LOW);
  SPI.transfer(0b11100001);
  digitalWrite(CS_595, HIGH);

  SPI.endTransaction();
}

void loop() {
}

Библиотеки #

Для более удобной работы в качестве расширителя пинов можно использовать мою библиотеку GyverShift - она хранит в буфере текущие состояния пинов и позволяет удобно их менять, а отправка происходит сильно быстрее shiftOut. Также есть вариант с работой через аппаратный SPI:

#define CS_595 10
#define DAT_595 11
#define CLK_595 13

#include <GyverShift.h>
GyverShift<OUTPUT, 1> reg(CS_595, DAT_595, CLK_595);

void setup() {
  reg.write(0, 1);
  reg.write(1, 1);
  reg.write(7, 1);
  reg.update();
}

void loop() {
}

Можно для примера выводить динамические эффекты:

Переключать по очереди
void loop() {
  for (int i = 0; i < 8; i++) {
    reg.clearAll();
    reg.write(i, 1);
    reg.update();
    delay(200);
  }
}
Включать и выключать по очереди
void loop() {
  for (int i = 0; i < 8; i++) {
    reg.write(i, 1);
    reg.update();
    delay(200);

    reg.clear(i);
    reg.update();
    delay(200);
  }
}
Включить все по очереди
void loop() {
  for (int i = 0; i < 8; i++) {
    reg.set(i);
    reg.update();
    delay(200);
  }
  reg.clearAll();
  reg.update();
  delay(200);
}

Полезные страницы #

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх