Сдвиговый регистр - логическая схема, которая позволяет хранить данные и "сдвигать" их вдоль ячеек. В данном случае рассматриваем 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:
- Подать на CS
LOW
сигнал - Для всех битов данных:
- Подать на DATA соответствующий биту сигнал (
HIGH
/LOW
) - "Дёрнуть" CLOCK вверх и вниз (
HIGH
,LOW
)
- Подать на 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);
}
Полезные страницы #
- Набор GyverKIT – наш большой стартовый набор Arduino, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
- Поддержать автора за работу над уроками