Problemas al conducir un registro de desplazamiento

0

Estoy tratando de conducir un registro de desplazamiento 74ACT299 con un Microcontrolador. Mirando la hoja de datos pensé que era bastante simple. Ajuste el bit de datos y luego pulse el reloj, repita. Después de que escribí el código, configuré un circuito de prueba con un LED en cada salida. Cuando ejecuto el código para encender cada led en orden, obtengo algunos resultados extraños. Los LEDs generalmente se encienden de dos en dos. Lo hacen en orden creciente, pero algo en un patrón como el siguiente. Vivo ligeramente cada iteración.

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...

Pensé que tal vez mi código no estaba cambiando las brocas correctamente, así que conecté un analizador lógico y produje la siguiente forma de onda.

Cadapulsoderelojes~7.80µsyeltiempoentrelospulsosderelojes~37.5µs.

Elcircuitoestáconfiguradocomoseveacontinuación.LaslíneasData,ClockyEnableestánsiendocontroladasporunMSP430a3.3v.

simular este circuito : esquema creado usando CircuitLab

El código que se ejecuta en el MSP430 se lista a continuación.

#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;
    }
}

He luchado con esto durante unos días y no puedo encontrar ningún error. Supongo que me estoy perdiendo algo sobre el registro de turnos o algo así. Estaría muy agradecido si alguien pudiera indicarme la dirección correcta sobre dónde podría estar el error. Estoy en la pérdida de dónde mirar a continuación.

    
pregunta TwistedTech

1 respuesta

2

El código y la salida del analizador lógico se ven bien. No estaría mal poner un NOP o dos antes de subir el reloj.

El 74ACT299 es un chip bastante rápido (reloj de 100MHz a 5V). Supongo que está obteniendo un rebote en tierra entre su SR y el circuito de conducción. Esto se debe sospechar, especialmente si tiene cables largos entre los dos (asegúrese de que el cable de tierra y los cables de señal sean cortos y directos).

También debe tener la fuente de alimentación 74ACT299 omitida cerca del chip con cerámica de 0.1uF a 1uF. Esto no es opcional en general, pero especialmente cuando está conduciendo mucha corriente hacia los LED. Si todos los LEDs se encienden al mismo tiempo, tienes ~ 100 mA volando con bordes de nanosegundos.

    
respondido por el Spehro Pefhany

Lea otras preguntas en las etiquetas