Electronic – Shift register 74HC164 not working

atmega328pshift-register

I recently got started working with digital electronics as a hobby and gotten myself some parts and soldered together a test board for AVR µCs. I'm using an ATMega328P.

Now I wanted to play around with a shift register, specifically a 8-bit SIPO of type 74HC164.

I wired it up as the pinout says, wired the clock to pin 0 on port B(pinb0) of the atmega and one data line(a) is wired to pin 7 on port D(pind7).
As a first test I wanted to set one bit and shift it over, visualizing the result with four LEDs. To do so I set pind7 high, then set pinb0 high then set pinb0 low again as well as pind7. I do that in a loop every 5th run, the other four times I just keep setting pinb0 high and then low again to get a clock and let the shift register shift.

Now the problem is, that the leds are just all on and shortly turn off when the clock signal is there.

Also weirdly it also does react to my proximity to the cables on the breadboard, making the leds flicker about.

Anyway, heres the schematic, should be correct, excuse my shoddy schematic skills:

schematic

btw, I always have only one µC inserted at a time, so please ignore the ATTiny.

And here's the code:

#define F_CPU 20000000UL

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


int main(void)
{
    /* Replace with your application code */
    uint8_t i = 0;
    uint8_t j = 0;
    while (1) 
    {

        if (i == 0)
        {   
            //clear register
            PORTD &= ~(1 << PIND7); 
            for(j = 0; j < 8; ++j)
            {
                PORTB |= (1 << PINB0);
                _delay_ms(1);
                PORTB &= ~(1 << PINB0);
                _delay_ms(1);
            }

            //set first bit to high
            PORTD |= (1 << PIND7);  
            _delay_ms(1);   
            PORTB |= (1 << PINB0);
            _delay_ms(1);
            PORTB &= ~(1 << PINB0);     
            _delay_ms(1);
            PORTD &= ~(1 << PIND7); 
            _delay_ms(1);
        }
        else
        {
            PORTB |= (1 << PINB0);
            _delay_ms(1);
            PORTB &= ~(1 << PINB0); 
        }



        i = (i+1)%5;

        _delay_ms(1000);
    }
}

Best Answer

Looks like you forgot to set the pins as outputs. You'll need to write to DDRB and DDRD at the start of your main method. The shift register input pins are probably picking up stray electric fields right now as they are very high impedance. Now, it's possible there's something else going on too, but getting the pins turned on is the first step.