# 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, 2014 at 23:03
• I tried that. I did a __delay_cycles(1000) between them and it didn't help. :/ Sep 6, 2014 at 23:08

The code and logic analyzer output looks okay. It would not hurt to put a NOP or two before driving the clock high.

The 74ACT299 is a pretty fast chip (100MHz clock at 5V). I'm guessing you're getting ground bounce between your SR and the driving circuit. This should be suspected especially if you have long wires between the two (make sure the ground wire as well as the signal wires are short and direct).

You should also have the 74ACT299 power supply bypassed close to the chip with 0.1uF to 1uF ceramic. This is non-optional in general, but especially when you're driving a lot of current into the LEDs. If all the LEDs switch at once you've got ~100mA flying around with nanosecond edges.

• How long would you define as "long wires"? My wires between the MSP430 and the breadboard with the SR are 3-5 inches in length. Sep 6, 2014 at 23:50
• @TwistedTech That's not short. If you don't have a bypass cap, add one. If there still is an issue then try increasing the LED resistors by 10:1 and see if the problem persists. Sep 7, 2014 at 0:07
• I didn't figure they were was short. I was just curious how short I needed to make them. Unfortunately I don't have a bypass cap on hand at the moment, I'll need to get one. Sep 7, 2014 at 0:37
• I found a cap to use as the bypass and it works now. Thanks! Sep 7, 2014 at 0:47
• Good to hear it's working now. It will be hard to forget this the next time. ;-) Sep 7, 2014 at 1:17