Using a 74HC595N with an Atmel AVR
From Wiki
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.
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);
}
