Interfacing shift register with AVR

Shift register is one of the important thing to learn while designing any embedded system. Using shift registers one can increase the number of input as well as output pins available in any microcontroller. There are situations, where you want to interface many peripherals together and also keep the system low cost as well as reliable. This is where shift register come into picture. For example, in a joystick used to play games, instead of running all the pins from the console to the joystick buttons, he used a shift register which reduces the number of pins almost by half.  This not only increases the reliability of the joystick, but also has helped in saving a lot of money in the long run.

74HC595  shift register

Another advantage of using shift register is that only 3 pins mainly control, latch and serial input/output can drive virtually any number of outputs or can take inputs from large number of device all at once. 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 suggest, the shift register is based on CMOS technology. Also, the output shift registers mainly converts 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, that is 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 on the LSB (least significant place i.e. BIT0). On next pulse this bit moves to BIT1 location. After 8 clock pulses this bit is moved to BIT7 (MSB place). After 8 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 setup and nothing on the display pins will change. Then when you are done, and everything is how you want, you pull the pin HIGH and the 74HC595 will display the new settings. So 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 8 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
   HC595_DDR|=((1<<HC595_SH_CP_POS)|(1<<HC595_ST_CP_POS)|(1<<HC595_DS_POS));
}
// 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
   HC595_PORT|=(1<<HC595_SH_CP_POS);//HIGH
   HC595_PORT&=(~(1<<HC595_SH_CP_POS));//LOW
}
//Sends a clock pulse on ST_CP line
void shiftLatch()
{
   //Pulse the Store Clock
   HC595_PORT|=(1<<HC595_ST_CP_POS);//HIGH
   _delay_loop_1(1);
   HC595_PORT&=(~(1<<HC595_ST_CP_POS));//LOW
   _delay_loop_1(1);
}
/*
Main High level function to write a single byte to
Output shift register 74HC595. 
Arguments:
   single byte to write to the 74HC595 IC
Returns:
   NONE
Description:
   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
         HC595DataHigh();
      }
      else
      {
         //MSB is 0 so output high
         HC595DataLow();
      }
      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
   shiftLatch();
}
/*
Simple Delay function approx 0.5 seconds
*/
void Wait()
{
   for(uint8_t i=0;i<50;i++)
   {
      _delay_loop_2(0);
   }
}
void main()
{
   uint8_t led[2]={
                        0b10000001,
                        0b11000011,
                     };
   shiftInit(); //Initialise
   while(1)
   {
      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

Read

Bookmark the permalink.
Add Comment Register



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>