Interfacing shift register with AVR

The shift register is one of the vital things to learn while designing an embedded system. Using shift registers, one can increase the number of input and output pins available in any microcontroller. There are situations where you want to interface many peripherals together and keep the low system cost and reliable.

This is where the shift register come into the picture. For example, in a joystick used to play games, instead of running all the pins from the console to the joystick buttons, a shift register reduces the number of pins almost by half.  This increases the reliability of the joystick and has helped in saving a lot of money in the long run.

74HC595 shift register

Another advantage of using shift register is that only three pins mainly control, latch and serial input/output can drive virtually any number of outputs or take inputs from a large number of the device. You might have seen different led cubes available in sizes of 4×4 or 6×6. The LED’s in those cubes are all driven by using shift registers.

In this tutorial, we will be using an output shift register 74HC595.  As the name suggests, the shift register is based on CMOS technology. Also, the output shift registers mainly convert serial input to parallel output, while an input shift register converts parallel input to serial output.

 The pin diagram of the shift register is as follows:

74HC595 shift register pin diagram

The above pin diagram has three signal lines which get connected to any microcontroller.

  • Serial Data Input (DS):- This pin is connected to any port of the microcontroller. This pin is responsible for getting the data serially from the microcontroller.
  • Shift Clock (SH_CP):- On this pin, the clock signal is applied. On the rising edge, when the clock rises from negative to positive, the data on the DS line is sampled, and it gets stored in the shift register. The bit on DS line is stored in the LSB (least significant place, i.e., BIT0). On next pulse this bit moves to BIT1 location. After eight clock pulses, this bit is transferred to BIT7 (MSB place). After eight clock pulses, the Shift Register has all 8 bits of a byte and is ready to convert them to parallel.
  • Store Clock (ST_CP):– You can hold this pin LOW while you get everything set up and nothing on the display pins will change. When you are done, and everything is how you want, you pull the pin HIGH, and the 74HC595 will display the new settings. Even though we are changing values in the register in 8 steps, it looks like it was just one step.
  • MR: – Will empty the whole shift register, if pulled low, must be pulled high to enable.
  • OE: – This pin enables the output when tied to ground, & disabled when HIGH.

The rest Q0-Q7 are the output pins to control eight output.

Vcc and ground should be connected to +5v and ground respectively.

Source code:-

#include <avr/io.h>
#include <util/delay.h>
#define HC595_PORT   PORTB
#define HC595_DDR    DDRB
#define HC595_DS_POS PB0      //Data pin (DS) pin location
#define HC595_SH_CP_POS PB1      //Shift Clock (SH_CP) pin location
#define HC595_ST_CP_POS PB2      //Store Clock (ST_CP) pin location
void shiftInit()
   //Make the Data(DS), Shift clock (SH_CP), Store Clock (ST_CP) lines output
// change data (DS)lines
#define HC595DataHigh() (HC595_PORT|=(1<<HC595_DS_POS))
#define HC595DataLow() (HC595_PORT&=(~(1<<HC595_DS_POS)))
//Sends a clock pulse on SH_CP line
void shiftPulse()
   //Pulse the Shift Clock
//Sends a clock pulse on ST_CP line
void shiftLatch()
   //Pulse the Store Clock
Main High level function to write a single byte to
Output shift register 74HC595.
   single byte to write to the 74HC595 IC
   The byte is serially transfered to 74HC595
   and then latched. The byte is then available on
   output line Q0 to Q7 of the HC595 IC.
void shiftWrite(uint8_t data)
   //Send each 8 bits serially
   //Order is MSB first
   for(uint8_t i=0;i<8;i++)
      //Output the data on DS line according to the
      //Value of MSB
      if(data & 0b10000000)
         //MSB is 1 so output high
         //MSB is 0 so output high
      shiftPulse();  //Pulse the Clock line
      data=data<<1;  //Now bring next bit at MSB position
   //Now all 8 bits have been transferred to shift register
   //Move them to output latch at one
Simple Delay function approx 0.5 seconds
void Wait()
   for(uint8_t i=0;i<50;i++)
void main()
   uint8_t led[2]={
   shiftInit(); //Initialise
      for(uint8_t i=0;i<2;i++)
         shiftWrite(led[i]);   //Write the data to shift register
         Wait();                 //Wait

Circuit diagram:-

74HC595 circuit digram with AVR

AvrStudio project code here: OutputShiftRegPROJ

Bookmark the permalink.

Comments are closed.