1
votes

I'm trying to read a value from an avr pin but it doesn't work.

I'm trying to read a value that is coming from a push button and this button is connected to 5V DC cell.

When I press the button the 5V should go to the atmega32 and reads it as 1, then the if statement becomes true and the led goes on.

However, when the value becomes true the led will turn on but its not.

bit 1 is the button bit 0 is the led

Code

#define DDRA (*((volatile unsigned char *)0x3A))
#define PORTA (*((volatile unsigned char *)0x3B))
#define PINA (*((volatile unsigned char *)0x39))

int main(void) {
   DDRA |= 0b00000001;         // pin 0 output

    while (1) {
        if ((PINA&0b00000010) == 1) {  // button pressed
            PORTA |= 0b00000001;   // turn led on
        }
    }
}
3

3 Answers

3
votes

I find one logic error here:

if ((PINA&0b00000010) == 1)  // button pressed

when the bit 1 is set, (PINA&0b00000010) == 2. Normally, when you do bit check, just do this:

if (PINA&0b00000010)  // button pressed
1
votes

Just to make sure, your button has to have a pull-up / pull-down resistor connected to ground. Without it, you can't correctly read whether the pin is on or off.

https://learn.sparkfun.com/tutorials/pull-up-resistors

1
votes

You should change your hardware setup, and make your button active low, which means that pushing the button connects your GPIO pin to ground. Instead of connecting your button to positive side of the 5V cell, connected it to the negative side. That will let you take advantage of the internal pull resistor that you can active on your GPIO. Once you do that, your code should be changed to look something like this:

#define DDRA (*((volatile unsigned char *)0x3A))
#define PORTA (*((volatile unsigned char *)0x3B))
#define PINA (*((volatile unsigned char *)0x39))

#define LED_BIT 0
#define BTN_BIT 1

int main(void) 
{
    DDRA  = (1 << LED_BIT); // PA0 output
    PORTA = (1 << BTN_BIT); // enable internal pull up on PA1

    while (1) {
        if (!(PINA & (1 << BTN_BIT))) {  // button pressed
            PORTA |= (1 << LED_BIT);   // turn led on
        }
    }
}

Notice that the if statement now checks to see if the PA1 is a 0 because the button is set up to connect to ground when it is pushed. Also notice that there is a new line in there that enables an internal pull-up, which makes PA1 read a 1 while the button is not pressed. If you don't change your button an active low configuration, you will have to use an external pull-down resistor in order for your code to work correctly.