1
\$\begingroup\$

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);
    }
}
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Spot on, thanks! Kinda odd though, since I tested the IO with the leds and they turned on when the clock and data was high, though very dim. \$\endgroup\$
    – rfreytag
    Sep 10, 2016 at 3:52
  • \$\begingroup\$ Well, you might actually be turning the internal pull-ups on and off. So in that case the pins would alternate between really high impedance (G ohms) and medium impedance (K ohms). Which would make an LED light up dimly. But on a CMOS input, it would alternate between high and floating, which will do strange things. \$\endgroup\$ Sep 10, 2016 at 3:58
  • \$\begingroup\$ ah, didn't know that. thanks again for the info! \$\endgroup\$
    – rfreytag
    Sep 10, 2016 at 4:33
0
\$\begingroup\$

You forgot the current limiting resistors between the outputs of the HC164 and the LEDs. If the current drawn from the outputs is too high, strange behavoiur may result or the HC164 may be destroyed. You should not use more than 20 mA current from the outputs. There should be always a current limiting resistor for a LED.

\$\endgroup\$
1
  • \$\begingroup\$ oh, there actually are. Looks like I forgot to add them in the schematic. But thanks for the info! \$\endgroup\$
    – rfreytag
    Sep 12, 2016 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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