# Issue driving a shift register

I am trying to drive a 74ACT299 shift register with a Microcontroller. Looking at the datasheet I thought it was pretty simple. Set the data bit then pulse the clock, repeat. After I wrote the code, I set up a test circuit with on LED on each output. When I run to the code to light each led in order, I get some weird results. The LEDs generally light two at a time. They do so in increasing order, but something in a pattern like the following. I varies slightly each iteration.

loop 1: none
loop 2: none
loop 3: LED 1
loop 4: LED 1, 2
loop 5: LED 2, 3
loop 6: LED 3
loop 7: LED 4, 5
loop 8: LED 5, 6
etc...


I figured maybe my code wasn't shifting the bits out properly so I connected a logic analyser and it produced the following waveform.

Each clock pulse is ~7.80 µs and the time between clock pulses is ~37.5 µs.

The circuit is setup as seen below. The Data, Clock, and Enable lines are being driver by an MSP430 at 3.3v.

simulate this circuit – Schematic created using CircuitLab

The code running on the MSP430 is listed below.

#include <msp430.h>

#define OUTPUT_ENABLE BIT5
#define DATA BIT4
#define CLOCK BIT3

void shift_out(unsigned char data, unsigned char data_pin, unsigned char clock_pin);

int main(void) {
WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer

P1DIR |= OUTPUT_ENABLE | DATA | CLOCK;

// set everything low
P1OUT &= 0xFF - (OUTPUT_ENABLE | DATA | CLOCK);

int x;
for (;;) {
for (x = 0; x < 8; x++)
{
// Disable the outputs
P1OUT |= OUTPUT_ENABLE;

int out = 1 << x;
shift_out(out, DATA, CLOCK);

// Enable the outputs
P1OUT &= 0xFF - OUTPUT_ENABLE;

__delay_cycles(500000);
}
}
}

void shift_out(unsigned char data, unsigned char data_pin, unsigned char clock_pin)
{
int i;
for (i = 0; i < 8; i++)
{
// set data pin to value
if ((1 << i) & data) {
P1OUT |= data_pin;
} else {
P1OUT &= 0xFF - data_pin;
}

// clock high
P1OUT |= clock_pin;

// clock low
P1OUT &= 0xFF - clock_pin;
}
}


I have fought with this for a few days and can't find any errors. I assume I am either missing something about the shift register or something. I would be most appreciative if someone could point me in the right direction about where the error might be. I am at loss of where to look next.

• Just a quick idea: Put a small (10-100us) delay after every I/O operation. If it makes a difference, then your CPU is way to fast and you have some race condition on your output lines. Sep 6 '14 at 23:03
• I tried that. I did a __delay_cycles(1000) between them and it didn't help. :/ Sep 6 '14 at 23:08