74HC595 Shift Register LED Array

-1

Estoy un poco atascado con mi registro de turnos, entendiendo qué está pasando. Cargué un programa vacío para probar la conexión y lo que veo son 8 LED en mi matriz, todos encendidos. No llamo a ninguna función y todavía todo se ilumina. ¿Cómo es esto posible?

MAIN

// AVR
#include <avr/io.h>
#include <util/delay.h>

// CUSTOM
#include <systemDefinitions.h>
#include <pinDefinitions.h>
#include <HC595.h>


int main(void)
{   
    while (1) {
    }

    return (0);
}

HC595.h

#define HC595_PORT PORTB
#define HC595_DDR DDRB
#define HC595_DS_POS PB0
#define HC595_SH_CP_POS PB1
#define HC595_ST_CP_POS PB2

#define HC595DataHigh() (HC595_PORT |= (1 << HC595_DS_POS))
#define HC595DataLow() (HC595_PORT &= (~(1<<HC595_DS_POS)))

void HC595Init() {
    // Make DS, SHCP and STCP output
    HC595_DDR |= ((1 << HC595_SH_CP_POS) | (1 << HC595_ST_CP_POS) | (1 << HC595_DS_POS));
}

// Sends a clock pulse on SHCP Line
void HC595Pulse() {
    // Pulse shift clock
    HC595_PORT |= (1 << HC595_SH_CP_POS); // HIGH
    HC595_PORT &= (~(1<<HC595_SH_CP_POS)); // LOW
}

// Sends a clock pulse on STCP Line
void HC595Latch() {
    // Pulse the store clock
    HC595_PORT |= (1 << HC595_SH_CP_POS); // HIGH
    _delay_loop_1(1);

    HC595_PORT &= (~(1<<HC595_ST_CP_POS)); // LOW
    _delay_loop_1(1);
}

/*

Main High level function to write a single byte to
Output shift register 74HC595. 

Arguments:
   single byte to write to the 74HC595 IC

Returns:
   NONE

Description:
   The byte is serially transfered to 74HC595
   and then latched. The byte is then available on
   output line Q0 to Q7 of the HC595 IC.

*/

void HC595Write(uint8_t data) {
    // Send each 8 bits serially
    // Order is MSB first
    for (uint8_t i = 0; i < 8; i++) {
        // Output the data on DS line according to the value of MSB
        if (data & 0b10000000) {
            // MSB is 1 so output HIGH
            HC595DataHigh();
        } else {
            // MSB is 0 so output LOW
            HC595DataLow();
        }
        HC595Pulse(); // Pulse the clock line
        data = data << 1; // Now bring the next bit at MSB Position
    }

    // Now all 8 bits have been transferred to shift register and move them to output latch at ones
    HC595Latch();
}

Entiendo cómo debería funcionar, pero no veo que mi configuración sea incorrecta. He intentado ahora este código:

int main(void)
{
    uint8_t led = 0b100000001;
    HC595Init();    

    HC595Write(led);

    return (0);
}

Incluso para una configuración básica, iluminando los 8 LED, la lógica debería ser simple pero no puedo asociar la salida a mi entrada.

Como ejemplo:

  • Datos: 0b11111111
  • Espero que el 585 se lea en cada bit, de acuerdo con la función que se encuentra a continuación
  • Los LED que se iluminan son 0b10101010

Por lo que veo, mi función 595Write funciona correctamente leyendo cada bit por pulso y luego de 8 pulsos, retiene los datos. Así que no veo ninguna conexión con el patrón de LED (11111111 - > 10101010)

    
pregunta sesc360

1 respuesta

0

Algunos problemas:

  •   

    "No llamo a ninguna función y aún así todo se ilumina. Cómo   ¿Es esto posible? "

    Probablemente porque el registro DDR se ingresa por defecto, de modo que si no lo configura en las salidas, los pines quedan en estado flotante. Si es importante que esto nunca suceda, debería considerar agregar resistencias de tracción externas en estos pines, para mantenerlos siempre en un estado conocido.

  • Según la hoja de datos de 74HC595: "± 6-mA Salida Drive a 5 V". Usted está conduciendo 5/220 = 22mA por pin. 22mA * 8 = 181 mA. Esto está más allá de las calificaciones máximas absolutas del IC. Es bastante seguro asumir que has frito el chip.

    Considere agregar un poco de IC de búfer con más fuerza de unidad entre el registro de desplazamiento y los LED. Controlador MOSFET de cuatro canales o similar.

  • Las aplicaciones de microcontroladores de metal desnudo ("independientes") no regresan de main() . Volver a donde? Si regresa de main() , su programa está prácticamente garantizado que se volverá loco. Siempre necesitas un bucle eterno como for(;;) . La forma correcta de main es probablemente void main (void) , consulte el manual de su compilador.

Algunas cosas generales:

  • Los literales enteros binarios no son estándar. Como tal, no está claro a qué tipo están predeterminados. Lo que significa que podría obtener varios problemas de promoción de tipo implícito en su código. Para resolver esto, apégate a la norma C pura.
  • Debería colocar una tapa de desacoplamiento de 100 nF cerca del pin Vcc.
  • La tapa 1uF es muy sospechosa. ¿Sirve un propósito? ¿Está tratando de obtener alguna pendiente en los datos binarios o qué?
respondido por el Lundin

Lea otras preguntas en las etiquetas