Introduction to 74HC595 shift register - Controlling 16 LEDs by

domingo, 25 de julho de 2010 0 comentários

This tutorial shows you how to control 16 LEDs with just 3 control lines. We do this by daisy chaining 74HC595 shift registers

Image

The 74HC595 shift register has an 8 bit storage register and an 8 bit shift register. Data is written to the shift register serially, then latched onto the storage register. The storage register then controls 8 output lines. The figure below shows the 74HC595 pinout.

Image

Pin 14 (DS) is the Data pin. On some datasheets it is referred to as "SER".

When pin 11 (SH_CP or SRCLK on some datasheets) goes from Low to High the value of DS is stored into the shift register and the existing values of the register are shifted to make room for the new bit.

Pin 12 (ST_CP or RCLK on some datasheets) is held low whilst data is being written to the shift register. When it goes High the values of the shift register are latched to the storage register which are then outputted to pins Q0-Q7.

The timing diagram below demonstrates how you would set the Q0-Q7 output pins to 11000011, assuming starting values of 00000000.

Image

The circuit we are building is showed below, followed by the build steps

Image

We will start with an Atmega8 breadboard circuit which we have used for many of our other tutorials. We add 2 extra breadboards and route power to these.

Image

We add the Shift Register and connect it to +5V and Ground.

Image

We now run the following control lines between the microcontroller and Shift Register
  • PC0 to DS
  • PC1 to ST_CP
  • Pc2 to SH_CP

These are the blue wires shown below.

Image

Next we connect up the LEDs and resistors. I used 510 Ohm resistors, but a range of other sizes are acceptable. ohmslawcalculator.com has a great LED Resistor Calculator that you can use.

Image

To demonstrate the circuit, I wrote a small bit of code which produces a knight rider pattern on the 8 LEDs.
Code:
#include
#include

#define DS_PORT    PORTC
#define DS_PIN     0
#define ST_CP_PORT PORTC
#define ST_CP_PIN  1
#define SH_CP_PORT PORTC
#define SH_CP_PIN  2

#define DS_low()  DS_PORT&=~_BV(DS_PIN)
#define DS_high() DS_PORT|=_BV(DS_PIN)
#define ST_CP_low()  ST_CP_PORT&=~_BV(ST_CP_PIN)
#define ST_CP_high() ST_CP_PORT|=_BV(ST_CP_PIN)
#define SH_CP_low()  SH_CP_PORT&=~_BV(SH_CP_PIN)
#define SH_CP_high() SH_CP_PORT|=_BV(SH_CP_PIN)

//Define functions
//======================
void ioinit(void);
void output_led_state(unsigned char __led_state);
//======================

int main (void)
{
   ioinit(); //Setup IO pins and defaults

   while(1)
   {
      /*
        Output a knight rider pattern
       
        10000000
        01000000
        00100000
        00010000
        00001000
        00000100
        00000010
        00000001
        00000010
        00000100
        00001000
        00010000
        00100000
        01000000
      */
    
      for (int i=7;i>=0;i--)
      {
         output_led_state(_BV(i));
         _delay_ms(100);
      }
    
      for (int i=1;i<7;i++)
      {
         output_led_state(_BV(i));
         _delay_ms(100);
      }
   }
}


void ioinit (void)
{
    DDRC  = 0b00000111; //1 = output, 0 = input
    PORTC = 0b00000000;
}

void output_led_state(unsigned char __led_state)
{
   SH_CP_low();
   ST_CP_low();
   for (int i=0;i<8;i++)
   {
      if (bit_is_set(__led_state, i))
         DS_high();
      else 
         DS_low();
    

      SH_CP_high();
      SH_CP_low();
   }
   ST_CP_high();
}

This is all very impressive, but didn’t I say we were controlling 16 LEDs? To do this we need to add another 74HC595 shift register, more LEDs, more resistors and more orange and blue wires.

We use the Q7’ pin to daisy chain the shift registers together.

The modified circuit is shown below.

Image

Image

To code to produce the 16 LED knight rider pattern is
Code:
#include
#include

#define DS_PORT    PORTC
#define DS_PIN     0
#define ST_CP_PORT PORTC
#define ST_CP_PIN  1
#define SH_CP_PORT PORTC
#define SH_CP_PIN  2

#define DS_low()  DS_PORT&=~_BV(DS_PIN)
#define DS_high() DS_PORT|=_BV(DS_PIN)
#define ST_CP_low()  ST_CP_PORT&=~_BV(ST_CP_PIN)
#define ST_CP_high() ST_CP_PORT|=_BV(ST_CP_PIN)
#define SH_CP_low()  SH_CP_PORT&=~_BV(SH_CP_PIN)
#define SH_CP_high() SH_CP_PORT|=_BV(SH_CP_PIN)

//Define functions
//===============================================
void ioinit(void);
void output_led_state(unsigned int __led_state);
//===============================================

int main (void)
{
   ioinit(); //Setup IO pins and defaults

   while(1)
   {
      // Output a knight rider pattern
    
      for (int i=15;i>=0;i--)
      {
         output_led_state(_BV(i));
         _delay_ms(50);
      }
      for (int i=1;i<15;i++)
      {
         output_led_state(_BV(i));
         _delay_ms(50);
      }
   }
}


void ioinit (void)
{
    DDRC  = 0b00000111; //1 = output, 0 = input
    PORTC = 0b00000000;
}

void output_led_state(unsigned int __led_state)
{
   SH_CP_low();
   ST_CP_low();
   for (int i=0;i<16;i++)
   {
      if ((_BV(i) & __led_state) == _BV(i))  //bit_is_set doesn’t work on unsigned int so we do this instead
         DS_high();
      else 
         DS_low();
    

      SH_CP_high();
      SH_CP_low();
   }
   ST_CP_high();
}

We just stopped at 16 LEDs, but we can continue daisy chaining more shift registers. This technique is not just limited to LEDs of course and we can use it to multiply output ports to drive many other kinds of devices.

One word of warning regarding this technique. When you power on the circuit, the output lines are set to some arbitrary value. Now it takes less than a microsecond to set them to your desired values, but for some circuits this may cause problems. In that case you can use to MR and OE pins to reset the storage registers.
Last edited by protostackadmin on Sat May 29, 2010 2:14 am, edited 6 times in total.
Share this article :

Postar um comentário

 
Support : Creating Website | Johny Template | Mas Template
Copyright © 2011. kvolts - All Rights Reserved
Template Created by Creating Website Published by Mas Template
Proudly powered by Blogger