Arduino connected to 74C164
Fig. 1 electrical connections to Arduino.

Arduino Controlling 74C164 Shift Register

by Lewis Loflin

This sample circuit and program demonstrate the use of a shift register with an Arduino Microcontroller. Instead of using some pre-made library, the idea here is use ones own code and learn some electronics.

For more on differing LED configurations see Using the 74HC165 Shift Register with the PICAXE Micro-Controller

This demonstration will use 8 light emitting diodes (LEDs) to count in binary from 0 to 255. This will require eight bits or one byte. How this count is displayed depends on how the LEDs are connected and how the bits are shifted into the shift register.

connections to the 74HC164
Fig. 2 internal block diagram of the 74HC164.

Fig. 2 above shows a typical internal block diagram of a eight-bit shift register. In the case of the 74HC164 we have eight clocked "D" type flip-flops with common clock line (CP) and common reset line (MR NOT) that will set outputs Q0 - Q7 to all LOW or binary 0. Note in the electrical sense a HIGH or binary 1 will output (source) +5-volts while a binary 0 will switch (sink) the pin to ground.

The 74HC164 8-Bit Serial-In - Parallel-Out Serial Shift Register has three inputs:

  1. Input A-B (pins 1, 2) is for data bit to be shifted in. They can be tied together or the one not used ties to +Vcc.
  2. CP or clock pin 8 data is shifted into the 8-bit register during the positive going transition of clock pulse. That is, whatever the state of input A-B will be shift one-bit right during each clock cycle and will continue to be shifted right during each consecutive pulse.
  3. Clear (pin 9) is independent of the clock and when taken LOW (0 volts), Q0 - Q7 will all go LOW (ground) on the corresponding output pin. This pin must be initialized/held HIGH for the register to operate.



/*

 Demo to shift byte into 74HC164
 8-Bit Serial-In - Parallel-Out Serial Shift Register
 Will count from 0 to 255 in binary on eight LEDs
 
 The 74HC164 has three inputs: 
 
 Input A-B (pins 1, 2) is for data. they can be tied 
 together or the one not used tied to +Vcc
 
 Clock pin 8 data is serially shifted in and 
 out of the 8-bit register during
 the positive going transition of clock pulse. 
 
 Clear (pin 9) is independent of the clock 
 and accomplished by a low level at the
 clear input.
 
 As far as LSB first or MSB bit first is up to software 
 and electrical connections on the output
 
 */

#define OFF 0
#define ON 1


#define Bit_out 12
#define CLK 11
#define CLR 10
#define LEDON 9

byte i, j , temp, val;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(Bit_out, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(CLR, OUTPUT);
  pinMode(LEDON, OUTPUT);

  pinMode(13, OUTPUT);  // used to test-debug various sections of code

  digitalWrite(LEDON, OFF);  //HIGH tuns on LEDs
  digitalWrite(CLK, OFF); 
  digitalWrite(CLR, HIGH); // active LOW
}

void loop() {

  for (i=0; i<=256; i++)  {
    digitalWrite(13, ON);
    val = i;
    for (j=1; j<=8; j++)  {
      // to right change B00000001 to B10000000
      temp = val & B00000001; // to count in binary from left 
      // to invert the output bit pattern change temp to !temp
      digitalWrite(Bit_out, temp); 
      pulsout(CLK, 10); 
      // to count in binary from left to right change the above to val = val << 1;
      val = val >> 1; // shift one place right same as divide by 2
    
    }  // next j

    digitalWrite(13,OFF);
    digitalWrite(LEDON, ON);
    delay(400);
    digitalWrite(LEDON, OFF);
  } // next i// inverts state of pin, delays, then reverts state back
void    pulsout(byte x, int y)   {
  byte z = digitalRead(x);
  z = !z;
  digitalWrite(x, z);
  delayMicroseconds(y);
  z = !z; // return to original state
  digitalWrite(x, z);
  return;
} // end pulsout()


74C164 Connected to Microchip PIC


74C164 connected to Arduino

Connected to 7-segment Display

/* Comment

Uses a 74C164 shift register to count from 0 t0 F (HEX) 
on a 7 segment common anode LED display.

To use a common cathode display change line
digitalWrite(data_bit, !k); ->   digitalWrite(data_bit, k); 

connect common to GND

 This program assumes a seven segment display with a bit pattern:
 
Q7 segment a
Q6 segment b
Q5 segment c
Q4 segment d
Q3 segment e
Q2 segment f
Q1 segment g
Q0 segment dp
 
*/
 
 #define data_bit 13 
 #define clk 12 // pin connected to display segment 'a'  
 #define mc 11 // pin connected to display dp pin
 
 
// segment patterns 0 - 9, A - F Hex + dp
byte Digit[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 
0x6d, 0x7d, 0x07, 0x7f, 0x67, 0x77, 0x7c, 0x39, 
0x5e, 0x79, 0x71, 0x80};




void setup()   {
  

 
  pinMode(mc, OUTPUT); 
  pinMode(clk, OUTPUT);  
  pinMode(data_bit, OUTPUT);
  

  digitalWrite(mc, 1);  
  digitalWrite(clk, 0); 
  digitalWrite(data_bit, 0);
 
  
 } // end setup


void loop()   {
  int i, j;

  for (i=0; i<= 15; i++)   {
    digitOut(Digit[i]);
    delay(500);
  }

}

void   digitOut(byte j)   {
  byte k;
  for(int i=0; i < 8; i++)   {
    k = j & 0x01;
    digitalWrite(data_bit, !k); 
 // use just k instead of !k for common cathode displays.


    pulsout(clk,1);

    j = j >> 1;
   }
  
}



// toggle the output state on a pin
void toggle(int pinNum) 
{  
  byte pinState = digitalRead(pinNum);
  pinState = !pinState;
  digitalWrite(pinNum, pinState); 
}


// inverts state of pin, delays, then reverts state back
void    pulsout(byte x, int y)   {
  byte z = digitalRead(x);
  z = !z;
  digitalWrite(x, z);
  delayMicroseconds(10* y);
  z = !z; // return to original state
  digitalWrite(x, z);
  return;
} // end pulsout()

Added September 20, 2013:


You Tube Arduino Microcontroller Video Series March 2012: