Howto: Using a 74HC595N shift register latch with an Atmel AVR
Using a shift register latch can increase the number of output pins your AVR can use. It takes 3 avr pins to control a 74HC595N latch. The latch in turn controls 8 output pins. The latches can be daisy chained togther. So your 3 avr pins can control multiple latches greatly increasing the number of output pins available.
The 3 avr pins that connect to that latch are pins: 14 (serial input pin), 11 (clock pin) and 12 (latch). You must first shift the bits into the latch. First set pin 14 either high or low, then set pin 11 high. This sets the first bit. You repeat this 8 times to shift in all 8 bits. After the last bit you set pin 12 high and the output pins of the latch are activated. I also connected VCC to pin 16 of the latch. The diagram below doesn't show that. I used Eagle to design the circuit and their library did not show pin 16 for some reason.
Here is some sample code:
// code by chad http://www.windmeadow.com
#include <avr/interrupt.h>
int main (void)
{
DDRB = 0xFF;
// Shift in a 1
PORTB = (1<<PINB3);
PORTB = (1<<PINB1);
// Shift in a 0
PORTB = (1>>PINB3);
PORTB = (1<<PINB1);
// Shift in a 1
PORTB = (1<<PINB3);
PORTB = (1<<PINB1);
// Shift in a 0
PORTB = (1>>PINB3);
PORTB = (1<<PINB1);
// Shift in a 1
PORTB = (1<<PINB3);
PORTB = (1<<PINB1);
// Shift in a 0
PORTB = (1>>PINB3);
PORTB = (1<<PINB1);
// Shift in a 1
PORTB = (1<<PINB3);
PORTB = (1<<PINB1);
// Shift in a 0
PORTB = (1>>PINB3);
PORTB = (1<<PINB1);
// Set the latch so the bits are sent to
// the output pins of the latch
PORTB = (1<<PINB2);
while (1) {
}
}

To chain the latches together, connect the second latch to the same pins. The only wiring difference is, pin 14 of latch 2 needs to be wired to pin 9 latch 1. The avr code is almost the same. The only difference is you shift 16 times (8 per latch) then set the latch to move the bits to the output pins of both latches.
Sample code:
#include <avr/interrupt.h>
void setlatch(int,int);
int
main (void)
{
DDRB = 0xFF;
// These two numbers will be converted to bits
// and shifted to the two latches
int num1 = 143;
int num2 = 131;
setlatch( num1, num2 );
while (1)
{
}
}
void
setlatch (int num1, int num2)
{
// Conver num1 to bits and shift out
while (num1 != 0)
{
if (num1 % 2)
{
PORTB = (1
<< PINB3);
PORTB = (1
<< PINB1);
}
else
{
PORTB = (1
>> PINB3);
PORTB = (1
<< PINB1);
}
num1 = num1 / 2;
}
// Conver num2 to bits and shift out
while (num2 != 0)
{
if (num2 % 2)
{
PORTB = (1
<< PINB3);
PORTB = (1
<< PINB1);
}
else
{
PORTB = (1
>> PINB3);
PORTB = (1
<< PINB1);
}
num2 = num2 / 2;
}
// Now that all 16 bits have been moved to the latches.
// Set the latch and have the bits go to the output pins
PORTB = (1 << PINB2);
}


This is the best solution
This is the best solution that a man could find. Bravo!
could also use the usi...
you could simplify code and "standardize" (not that it
matters) by using the USI in (poorly named) 3-wire mode.
instead of PB3 use D0, instead of PB1 use UCSK. the code
supplied in the datasheet works more or less unchanged.
you still need to drive the latching explicitly, you could
view this as the 3-wire chip select.
as an aside, you should keep the data stable while creating
the clock edge, your code above seems to violate hold time
requirements...
look at the spokepov design (google it) for a cute design
that uses a trick similar to the above with some extra
complication (an spi eeprom that feeds data to the latches).
Yep, you are absolutely
Yep, you are absolutely right. When I made this program I didn't know about USI. But I think doing it this way helps to better understand how works.
But the next time I need to use a shift register I will use USI instead.
What about input ?
Can I use a 74HC595 to read bits into the avr or is it output-only ?
Re: What about input?
I haven't tried that, but I am pretty sure you can. My example was basically serial to parrallel and you should be able to do parallel-to-serial with the avr reading the serial input. Take a look at this web site.
http://www.play-hookey.com/digital/shift-out_register.html
thanks
chad
NIce
Nice, would it be possible to do something similar whit a 4015 witch don't have a latch pin?
Cool design
thanks
Post new comment