ASCIMathML.js

Monday 6 February 2012

Shift Register - Hello World


I've just got some shift registers.

NXP 74HC595N


These little chips are very useful for controlling lots of outputs from your 'duino.  Using three pins you can control a massive number outputs.

This chip has 16 pins,  for the sake of this demo, eight of these are the outputs, Vcc & ground, The Master Reset (which we won't use) and then the three pins which are used to control the eight output pins.

OK, this example is very simple indeed.  We'll just get some LEDs to light up to show that we are indeed causing the outputs to change as we expect.


First off, let's look at the datasheet to see what pins do what (look at section 6, "Pinning Information").

  • Q1 (Pin 1) to Q7 (Pin 7) and Q0 (Pin 15), on the other side, are our output pins, we can set these to high or low.  (Q7S is a special output which I'll tackle in another post)
  • Vcc (Pin 16) and GND (Pin 8) 
  • DS (Pin 14), this is the serial input.  This is the pint we use to set the value of each output (Qn).
  • SHCP (Pin 11), this is the clock pin.  This tells the register to accept a new value and shift all the other values over one space.
  • STCP (Pin 12) This is the the 'Storage Register Clock Input', but is commonly refereed to as the latch pin.  This tells the shift register to make the values you've given it live.


OK... First off... acknowledgement!  There's an tutorial here which is for the Arduino.  To be honest, I've done little more than port it to Netduino and re-explain it in my own words.

Speaking of which, let's move on.

Each output pin (Q0 to Q7) has a register which can store a high or low value.   I'm going to call them R0 to R7.  You set these registers one at a time, and each time you set one, all the others shift along one, with whatever was the far end falling off and disappearing.

The clock pin controls this process.  When the clock pin it taken high and then low again it will read whether the data pin is high or low, store this in the first register (Q0's register) and shift all the others along one.  So R1 becomes whatever R0 was previously, until R7's original value is lost completely replaced by whatever R6 was previously.

At the moment, this won't change the value of the output pins; to cause the output pins to reflect what you've loaded into the registers we use the latch pin.  When  this pin is set high, all the values in the output pins are set to reflect the registers.  When it is low, you're free to set registers without changing the outputs.

Wiring

First things first, we'll wire up the LED array which will light up as the output pins go high.

Wiring for the LED array
In this, A through H are the output pins Q0 to Q7 (Don't forget, Q0 is actually on the opposite side of the IC to the other outputs).

Now, Connect the Ground to GND on your 'duin and Vcc to 3.3V.

Now, the tree interesting pins!  Data, clock and latch.  Connect these to your favourite digital IO pins on the 'duino and we're good to move onto the code.

I used the following pins:

  • Latch    D8
  • Data     D12
  • Clock   D11
public static void Main() 
{
        //Pin connected to ST_CP of 74HC595
        OutputPort latchPin = new OutputPort(Pins.GPIO_PIN_D8, false);
        //Pin connected to SH_CP of 74HC595
        OutputPort clockPin = new OutputPort(Pins.GPIO_PIN_D12, false);
        ////Pin connected to DS of 74HC595
        OutputPort dataPin = new OutputPort(Pins.GPIO_PIN_D11, false);

        for (int i = 0; i < 8; i++)
        {
            dataPin.Write(false);
            TickClock(clockPin);
        }

        ReleaseLatch(latchPin);

        for (int j = 0; j < 60; j++)
        {
            Debug.Print(j.ToString());
            dataPin.Write(j % 2 == 0);

            for (int i = 0; i < 8; i++)
            {
                Debug.Print("j = " + j + "\tdataPin = " + dataPin.Read());
                   
                dataPin.Write(!dataPin.Read());
                clockPin.Write(true);
                TickClock(clockPin);
            }
            ReleaseLatch(latchPin);
            Thread.Sleep(499);
        }
    }

    private static void ReleaseLatch(OutputPort latchPin)
    {
        latchPin.Write(true);
        Thread.Sleep(1);
        latchPin.Write(false);
    }

    private static void TickClock(OutputPort clockPin)
    {
        clockPin.Write(true);
        Thread.Sleep(1);
        clockPin.Write(false);
    }
}

The code is quite simple, We load up our registers, alternating high and low.  The TickClock method tells the shift register to accepts the current value of the data pin, save it and shift everything along one.  Once we've written to all 8 registers we call the ReleaseLatch method to activate the state, i.e. make the values in the registers go live.

The end result?


OK, I only had 5 LEDs and as you can see, the rightmost red one is much brighter...  I'll get a better video done at some point.  That is, is the LEDs ever arrive from CHina!

No comments:

Post a Comment