0
\$\begingroup\$

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.

Logic Analyser Wave Form

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.

schematic

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.

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Laszlo Valko Sep 6 '14 at 23:03
  • \$\begingroup\$ I tried that. I did a __delay_cycles(1000) between them and it didn't help. :/ \$\endgroup\$ – TwistedTech Sep 6 '14 at 23:08
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – TwistedTech Sep 6 '14 at 23:50
  • \$\begingroup\$ @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. \$\endgroup\$ – Spehro Pefhany Sep 7 '14 at 0:07
  • \$\begingroup\$ 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. \$\endgroup\$ – TwistedTech Sep 7 '14 at 0:37
  • 2
    \$\begingroup\$ I found a cap to use as the bypass and it works now. Thanks! \$\endgroup\$ – TwistedTech Sep 7 '14 at 0:47
  • \$\begingroup\$ Good to hear it's working now. It will be hard to forget this the next time. ;-) \$\endgroup\$ – Spehro Pefhany Sep 7 '14 at 1:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.