Correo: [email protected] - Teléfono: +56979962128

Project Working and Interfacing 74HC595 Shift Register with Arduino
  Una de las cosas buenas del Arduino es que tiene una cantidad razonable de pines de E/S con los que trabajar. Puedes conectar algunos botones, sensores, servos, etc., pero a medida que la lista crece, rápidamente te quedarás sin pines. La solución es usar un registro de desplazamiento, que te permite agregar más pines de E/S al Arduino (o a cualquier microcontrolador). El registro de desplazamiento más utilizado, con diferencia, es el 74HC595, también conocido simplemente como “595”.

El 74HC595 controla ocho pines de salida diferentes utilizando solo tres pines de entrada. Si necesitas más de 8 pines de E/S, puedes encadenar tantos registros de desplazamiento como sea necesario para generar una gran cantidad de pines de salida.

El 74HC595 logra esto mediante una técnica conocida como desplazamiento de bits (bit-shifting). Si te interesa aprender más sobre este concepto, este artículo de Wikipedia puede serte muy útil.

¿Cuándo deberías usar un registro de desplazamiento?

Los registros de desplazamiento se usan con frecuencia para aumentar el número de pines de E/S en un microcontrolador.

Por ejemplo, si tu proyecto necesita controlar 16 LEDs individuales, en teoría, requerirías 16 pines del Arduino, lo cual no es posible en la mayoría de los modelos. Aquí es donde el registro de desplazamiento resulta muy útil.

Con dos registros de desplazamiento conectados en serie, puedes controlar 16 LEDs utilizando solo tres pines de E/S. Esa es una gran diferencia y, cuanto más registros encadenes, más pines adicionales tendrás. En teoría, al encadenar registros de desplazamiento, puedes agregar un número infinito de pines de E/S.

Un ejemplo práctico de un registro de desplazamiento es el controlador original de Nintendo, lanzado en 1985. El microcontrolador principal de la Nintendo Entertainment System usaba registros de desplazamiento para recopilar las pulsaciones de los botones del control.

Nintendo Entertainment System NES Controller FL
Registros de Desplazamiento SIPO vs PISO

Existen dos tipos de registros de desplazamiento: SIPO (Serial-In Parallel-Out, entrada en serie y salida en paralelo) y PISO (Parallel-In Serial-Out, entrada en paralelo y salida en serie).

SIPO es útil para controlar una gran cantidad de salidas, como LEDs.
PISO es útil para recopilar una gran cantidad de entradas, como botones, similar al controlador original de Nintendo mencionado anteriormente.

El chip SIPO más popular es el 74HC595, mientras que el chip PISO más popular es el 74HC165.
   

¿Cómo funciona el registro de desplazamiento 74HC595?

El 74HC595 tiene dos registros de 8 bits (que se pueden considerar como “contenedores de memoria”). El primero se denomina Registro de Desplazamiento, y el segundo como el Registro de Almacenamiento/Retención.

Cada vez que el 74HC595 recibe un pulso de reloj, suceden dos cosas:

  • Los bits contenidos en el registro de desplazamiento se desplazan a la izquierda en una posición. El valor del bit 0 se mueve al bit 1, mientras que el valor del bit 1 se mueve al bit 2, y así sucesivamente.

  • El bit 0 en el registro de desplazamiento acepta el valor actual en el pin de DATOS. En el borde ascendente del pulso de reloj, si el pin de DATOS está alto, se introduce un 1 en el registro de desplazamiento; de lo contrario, se introduce un 0.

Este proceso continuará mientras el 74HC595 esté siendo impulsado por el reloj.

Cuando se habilita el pin de retención, el contenido del registro de desplazamiento se copia al registro de almacenamiento/retención. Cada bit del registro de almacenamiento está vinculado a uno de los pines de salida del IC, QA-QH. Como resultado, cada vez que el valor en el registro de almacenamiento cambie, la salida cambiará.

La animación a continuación te ayudará a entenderlo mejor.

74HC595 Shift Register Working

Pinout del Registro de Desplazamiento 74HC595

Es importante señalar que varias compañías fabrican el mismo chip 74HC595. En este artículo, vamos a hablar sobre el ubiquo SN74HC595N de Texas Instruments. Si por casualidad tienes uno diferente, lee cuidadosamente la hoja de datos y toma nota de cualquier diferencia.

Veamos su pinout:

Pinout 74HC595 Shift Register

 GND

es el pin de tierra.  VCC  es la fuente de alimentación para el registro de desplazamiento 74HC595, que debe estar conectada a 5V.  SER(Entrada Serial) se utiliza para enviar datos al registro de desplazamiento un bit a la vez.  SRCLK (Reloj del Registro de Desplazamiento)  es el reloj para el registro de desplazamiento y se activa en el borde ascendente del reloj. Esto significa que los bits se introducen en el registro en el borde ascendente del pulso de reloj.  RCLK (Reloj del Registro / Retención) es un pin muy importante. Cuando este pin se lleva a HIGH, el contenido del Registro de Desplazamiento se copia al Registro de Almacenamiento/Retención, lo que eventualmente aparecerá en la salida. Así que, el pin de retención puede verse como el último paso antes de ver los resultados en la salida.  SRCLR (Borrar Registro de Desplazamiento) nos permite restablecer todo el Registro de Desplazamiento, configurando todos los bits a cero. Debido a que este es un pin activo-bajo, debemos llevar el pin SRCLR a LOW para realizar el reinicio.  OE (Habilitación de Salida)  también es un pin activo-bajo: cuando se lleva a HIGH, los pines de salida se deshabilitan (se configuran en un estado de alta impedancia). Cuando se lleva a LOW, los pines de salida funcionan normalmente.  QA–QH son los pines de salida.  QH’  emite el bit 7 del registro de desplazamiento. Esto permite realizar un encadenamiento en cadena (daisy-chaining) de los 74HC595. Si conectas este pin al pin SER de otro 74HC595 y alimentas ambos ICs con la misma señal de reloj, se comportarán como si fueran un solo IC con 16 salidas. Por supuesto, con esta técnica, puedes encadenar tantos ICs como desees.    

Conexión de un Registro de Desplazamiento 74HC595 a un Arduino

Ahora que conocemos lo básico sobre cómo funciona el 74HC595, ¡podemos empezar a conectarlo a nuestro Arduino!

Comienza colocando el registro de desplazamiento en tu protoboard. Asegúrate de que cada lado del IC esté en un lado diferente de la protoboard. Con la pequeña muesca en forma de “U” hacia arriba, el pin 1 del chip está a la izquierda de esta muesca.

Conecta los pines 16 (VCC) y 10 (SRCLR) al pin de salida de 5V del Arduino, y los pines 8 (GND) y 13 (OE) a tierra. Esto debería mantener el IC en el modo de funcionamiento normal.

A continuación, conecta los tres pines que se usarán para controlar el registro de desplazamiento. Conecta el pin 11 (SRCLK), el pin 12 (RCLK) y el pin 14 (SER) del registro de desplazamiento a los pines 6, 5 y 4 del Arduino, respectivamente.

Lo que queda es conectar los LEDs a los pines de salida. Conecta el cátodo (pin corto) de cada LED a una tierra común, y el ánodo (pin largo) de cada LED a su respectivo pin de salida del registro de desplazamiento.

No olvides agregar una resistencia de 220Ω en serie para proteger los LEDs de sobrecarga.

Cuando conectes los LEDs, asegúrate de que QA esté conectado al primer LED y QH esté conectado al último; de lo contrario, los LEDs no se encenderán en el orden correcto.

El siguiente diagrama te muestra cómo conectar todo.

Arduino Wiring Fritzing Connections with 74HC595 Shift Register
Usar el registro de desplazamiento para suministrar energía de esta manera se llama suministrar corriente (sourcing current). Algunos registros de desplazamiento no pueden suministrar corriente, solo pueden hacer lo que se llama absorber corriente (sinking current).

Si tienes uno de estos, necesitarás invertir la dirección de los LEDs, conectando los ánodos directamente a la fuente de alimentación y los cátodos a las salidas del registro de desplazamiento.

Código de Ejemplo para Arduino

   

Aquí tienes un ejemplo de sketch que enciende cada LED por turno hasta que todos estén encendidos, luego los apaga todos y el ciclo se repite.

Primero, prueba el sketch y luego lo repasaremos en detalle.

int latchPin = 5;      // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 6;      // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 4;       // Data pin of 74HC595 is connected to Digital pin 4

byte leds = 0;         // Variable to hold the pattern of which LEDs are currently turned on or off

/*
 * setup() - this function runs once when you turn your Arduino on
 * We initialize the serial connection with the computer
 */
void setup() 
{
  // Set all the pins of 74HC595 as OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}

/*
 * loop() - this function runs over and over again
 */
void loop() 
{
  leds = 0;        // Initially turns all the LEDs off, by giving the variable 'leds' the value 0
  updateShiftRegister();
  delay(500);
  for (int i = 0; i < 8; i++)        // Turn all the LEDs ON one by one.
  {
    bitSet(leds, i);                // Set the bit that controls that LED in the variable 'leds'
    updateShiftRegister();
    delay(500);
  }
}

/*
 * updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again.
 */
void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

Después de cargar el código en el Arduino, deberías ver la siguiente salida:

74HC595 Shift Register Sketch Output

Explicación del Código:

El primer paso es definir los tres pines de control del 74HC595, a saber, el pin de latch, el pin de reloj y el pin de datos, los cuales están conectados a los pines digitales #5, #6 y #4 del Arduino, respectivamente.
int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
    A continuación, se define una variable llamada leds de tipo de dato byte. El tipo de dato byte puede almacenar ocho bits, lo cual es ideal para realizar un seguimiento del estado encendido/apagado de ocho LEDs.
// Variable to hold the pattern of which LEDs are currently turned on or off
byte leds = 0;
   
En la función ‘setup’, simplemente configuramos los tres pines como salidas digitales.
void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}
  La función loop primero apaga todos los LEDs al establecer todos los bits de la variable leds en 0 y llamar a una función personalizada updateShiftRegister(). Más adelante explicaremos cómo funciona updateShiftRegister().

El programa hace una pausa de medio segundo antes de contar de 0 a 7 usando el ciclo for y la variable i.

  Durante cada iteración, se llama a la función incorporada bitSet() para establecer el bit en la variable leds que controla un LED en particular, y luego se llama a la función updateShiftRegister() para cambiar el estado de los LEDs. Después, hay un retraso de medio segundo antes de incrementar i y encender el siguiente LED.
void loop() 
{
  leds = 0;
  updateShiftRegister();
  delay(500);
  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(500);
  }
}
 
 

La función updateShiftRegister() primero establece el pin latch en LOW y luego llama a la función incorporada shiftOut(), antes de establecer el pin latch nuevamente en HIGH.

El IDE de Arduino incluye una función shiftOut() que está diseñada específicamente para registros de desplazamiento. Esta función nos permite desplazar un byte de datos un bit a la vez.

La función shiftOut() acepta cuatro entradas, las dos primeras son los pines Data y Clock. El tercer parámetro especifica si los bits deben ser desplazados en el orden MSBFIRST (Most Significant Bit First) o LSBFIRST (Least Significant Bit First). El último parámetro es el dato real que se va a desplazar, en este caso leds.

Establecer el pin latch en HIGH copia el contenido del Shift Register en el Storage/Latch Register. Nota que se establece el pin latch en LOW antes de desplazar los bits, porque si no lo hacemos, los LEDs incorrectos parpadearían mientras se carga la información en el registro de desplazamiento.

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}
 
 

Ejemplo de Arduino 2: Controlando el Brillo Usando PWM

Aquí tienes otro proyecto basado en la misma configuración, pero con una ligera variación: ¡manipulamos el pin OE en el IC para controlar el brillo de los LEDs de salida!

Ya sabemos que el pin OE (Output Enable) funciona como un interruptor. Cuando este pin se establece en HIGH, los pines de salida se desactivan (recuerda, es activo-bajo). Cuando OE se establece en LOW, los pines de salida funcionan normalmente.

En nuestro ejemplo anterior, conectamos OE a tierra, lo que permitía que la salida estuviera activa en todo momento. Si conectamos este pin a cualquiera de los pines digitales del Arduino y lo programamos para cambiar su estado, podemos obtener el siguiente resultado.

74HC595 Shift Register Output Enable Toggle Output
Sin embargo, al conectar OE a cualquiera de los pines habilitados para PWM del Arduino, podemos controlar el brillo de los LEDs, como se muestra a continuación.
74HC595 Shift Register Output Enable PWM Output

Conexión

Todo lo que tienes que hacer es cambiar la conexión al pin 13 (OE) del 74HC595. En lugar de conectar OE a tierra, conéctalo al pin 3 del Arduino.

Arduino PWM Brightness Control Wiring Fritzing Connections with 74HC595 Shift Register

Código de Ejemplo

Este sketch funciona de manera similar al anterior, con la excepción de que, una vez que todos los LEDs estén encendidos, se desvanecerán gradualmente hasta apagarse.

int latchPin = 5;           // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 6;           // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 4;            // Data pin of 74HC595 is connected to Digital pin 4
int outputEnablePin = 3;    // OE pin of 74HC595 is connected to PWM pin 3

byte leds = 0;              // Variable to hold the pattern of which LEDs are currently turned on or off

/*
 * setup() - this function runs once when you turn your Arduino on
 * We initialize the serial connection with the computer
 */
void setup() 
{
  // Set all the pins of 74HC595 as OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT); 
}

/*
 * loop() - this function runs over and over again
 */
void loop() 
 
 

Cuando subas el código al Arduino, deberías ver la siguiente salida:

 
74HC595 Shift Register PWM Brightness Control Sketch Output

Preguntas frecuentes

¿Para qué sirve un registro de desplazamiento?

Para aumentar el número de pines de entrada/salida de un microcontrolador. El 74HC595 controla ocho pines de salida usando solo tres pines del Arduino, y encadenando varios se pueden obtener muchos más.

¿Cuántos LED puedo controlar con un 74HC595?

Ocho con un solo chip. Con dos registros de desplazamiento conectados en serie se pueden controlar 16 LED usando apenas tres pines de E/S; en teoría, encadenando registros se puede añadir un número casi ilimitado de salidas.

¿Cuál es la diferencia entre un registro SIPO y uno PISO?

SIPO significa entrada en serie y salida en paralelo, y sirve para controlar muchas salidas como LED. PISO es entrada en paralelo y salida en serie, y sirve para recoger muchas entradas como botones. El chip SIPO más popular es el 74HC595 y el PISO más popular es el 74HC165.

¿Qué es el desplazamiento de bits?

Es la técnica con la que el 74HC595 consigue manejar ocho salidas desde tres pines: los datos entran bit a bit de forma serial y el chip los va desplazando por sus registros internos hasta completar los ocho bits que luego presenta en paralelo.

¿Dónde se usan los registros de desplazamiento en la práctica?

Un ejemplo conocido es el control original de la Nintendo Entertainment System, lanzado en 1985: el microcontrolador principal usaba registros de desplazamiento para recoger las pulsaciones de los botones del mando.

Aprende esto en un curso

Si prefieres verlo en vivo y con alguien que resuelva tus dudas, estos cursos presenciales de MCI Educación cubren el tema de este tutorial: