Сдвиговый регистр 74HC595
Плата NodeMCU v3 CH340 имеет 13 контактов ввода/вывода общего назначения. Всё же, может возникнуть ситуация, когда этого не будет хватать и требуется увеличить количество выводов, с помощью которых можно управлять включением/выключением большего количества устройств. Подобная задача часто может возникать, если требуется управлять включением большого количества светодиодов. Для увеличения количества выходов используют микросхему сдвигового регистра 74HC595, которая входит в наш конструктор.
Для управления микросхемой 74HC595 надо задействовать 3 выхода на микроконтроллере NodeMCU. Количество устройств, которым можно будет управлять увеличивается до 8. Но сдвиговые регистры можно соединять каскадом до 24 устройств. Количество выходов для управления всеми ими не изменится. По-прежнему надо задействовать 3 выхода. Но количество устройств, которыми можно управлять увеличится с 8 до 184.
Назначение выводов микросхемы 74HC595 приведено на рисунке ниже
На VCC (16 ножка) и SRCLK (10 ножка) подаётся питание от 3 до 5 вольт. GND (8 ножка) и OE (13 ножка) должны быть подсоединены к земле. Ножка QH’ служит для каскадного соединения и требуется, если нужно добавить в схему следующий сдвиговый регистр. Через ножки SRCLK (11 ножка - синхронизирующий пин), RCLK (12 ножка – пин-защёлка) и SER (14 ножка – пин данных) осуществляется управление устройствами через микросхему. Через QA (15 ножка), QB, QC, QD, QE, QF, QG и QH (ножки с 1 по 7 соответственно) управляют подключёнными устройствами. Для этого в пин данных отправляют набор из 8 бит, в котором 1 соответствует включению, 0 – выключению сигнала. Так, последовательность 0 0 1 0 0 1 0 1 включит устройства на ножках QA, QC и QF (порядок ножек соответствует порядку байтов справа на лево).
Приведём пример использования микросхемы 74HC595 с микроконтроллером NodeMCU v3.
Соберите схему, в которой мы будем управлять тремя светодиодами, но их количество, при желании можно увеличить до 8.
В скетче с интервалом в 2 секунды включается один из трёх светодиодов: красный, жёлтый или зелёный. Одновременно каждые 2 секунды переключается встроенный светодиод на плате NodeMCU.
[VIDEO
Видео работы примера
/*
Программа поочередно включает светодиоды, подключенные к нескольким сдвиговым регистрам 74HC595.
i_led[0], i_led[1], ... массивы светодиодов на соответствующих регистрах
*/
// Встроенный светодиод
#define LED_BUILTIN 2 // NodeMCU v3 встроенный светодиод на 2 ножке
// Количество регистров
#define I_74HC595 1 // у нас пример с одним сдвиговым регистром
uint32_t tmr;
int tmr_blink = 2000;
// Массив регистров, по 8 выводов в каждом
boolean OnOff[I_74HC595][8];
// Количество светодиодов на регистрах.
int i_led[I_74HC595] = {3}; // Количество может меняться от 0 до 8, в нашем примере 3
// Состояние встроенного светодиода
// Используется для контроля работы ESP8266
boolean OnOffLed = LOW;
// Индекс текущего активного светодиода
int cur_i = 0;
int cur_j = 0;
//Пин подключен к SRCLK (11) входу 74HC595
int clockPin = 5; // выход D1 - это GPIO5 NodeMCU
//Пин подключен к RCLK (12) входу 74HC595
int latchPin = 4; // выход D2 - это GPIO4 NodeMCU
//Пин подключен к SER (14) входу 74HC595
int dataPin = 14; // выход D5 - это GPIO14 NodeMCU
void setup()
{
// Для тестовой выдачи в порт
Serial.begin(115200);
//устанавливаем режим OUTPUT
pinMode(LED_BUILTIN, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
for (int i=0; i < I_74HC595; i++)
{
for (int j=0; j < i_led[i]; j++)
{
OnOff[i][j] = LOW;
}
}
OnOff[0][0] = HIGH; // Включаем первый светодиод
WriteReg(); // Включаем нужный светодиод
digitalWrite(LED_BUILTIN, LOW); // Встроеный светодиод для контроля работы
tmr = millis();
}
// Функция заполняет сдвиговые регистры значениями по битам
void WriteReg()
{
digitalWrite(latchPin, LOW);
for (int i=0; i < I_74HC595; i++) {
for (int j=7; j >= 0; j--)
{
digitalWrite(clockPin, LOW);
digitalWrite(dataPin, OnOff[i][j]);
Serial.print(OnOff[i][j]);
digitalWrite(clockPin, HIGH);
}
Serial.println(";");
digitalWrite(latchPin, HIGH);
}
}
void loop()
{
if (millis() - tmr > tmr_blink) { // Пора переключить светодиод
tmr = millis();
WriteReg(); // Включаем нужный светодиод
OnOff[cur_i][cur_j] = LOW; // Выключили текущий светодиод
// Вычисляем индексы следующего зажигающегося светодиода
if (cur_j < i_led[cur_i] - 1) {
cur_j++;
}
else { // Дошли до конца блока
cur_j = 0;
if (cur_i < (I_74HC595 - 1)) {
cur_i++;
}
else { // Дошли до последнего светодиода
cur_i = 0;
}
}
OnOff[cur_i][cur_j] = HIGH; // Включили следующий светодиод
// Включаем-выключаем встроенный светодиод
// чтобы видеть как работает плата
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Переключаем состояние встроенного светодиода
}
}