Electronic – How to make a latch in AVR without interrupts

avrc

I want to make a simple circuit that when you press a pushbutton, an LED lights up stays lit until the button is pressed again. I haven't delved into interrupts yet on AVR, and was wondering whether it is possible to do in a while loop.

This is my code:

#include <avr/io.h>

#define INPUT (1 << PINB3)
#define OUTPUT (1 << PINB0)

int main(void)
{
    DDRB = 0x00;        //everything input
    PORTB = 0x00;       //no pud

    DDRB |= 0x1;        //PB0 is an output
    PORTB = 0x00;       //PB0 is low and PUD is off

    uint8_t prev = PINB;

    while(1)
    {
        if ((prev & INPUT) < (PINB & INPUT)) {      //rise edge
            if ((PORTB & OUTPUT) == 0x0) {      //if output was low
                PORTB |= OUTPUT;        //make output high
            } else {
                PORTB &= ~OUTPUT;       //make output low
            }
        }
        prev = PINB;
    }
}

The switch only partially works, I'm guessing because of the nature of the while loop and it storing the previous input really fast.

I believe the problem lies in my method of detecting a rising edge of the push-button. What would be a better method?

Best Answer

Your problem might be bouncing. When you press or release a button, it bounces. (see picture). This is due to mechanical bounces of the electrical contacts inside the button itself. enter image description here

You have to take this into account and reject the bounces. This can be done in software. A lot of method exists, using timer, interrupts, wait loops etc. Google the web and choose the implementation that fits your system best.

You can also have a look here: debouncing-buttons