# Unable to read a pull-resistor activated input pin in avr

I am trying to read the pin PB0 which is connected to internal pull-up resistor. In my code logic,

• if PB0 is HIGH then execute if-block
• if PB0 is LOW then execute else-block

But when I connect PB0 to GND pin, it is still executing the if-block.

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

int main(void)
{
//For testing
DDRD = 0b11111111;
PORTD = 0b00000000;

/*
OLD CODE
DDRB  |= (0<<PB0|1<<PB1);// PB0 -input, PB1 -output
PORTB |= (1<<PB0|0<<PB1);//activated pullup in PB0
*/

//CORRECTED CODE
DDRB  |=  (1 << PB1); // PB1 -output
DDRB  &= ~(1 << PB0); // PB0 -input
PORTB |=  (1 << PB0); // Activated pullup in PB0
PORTB &= ~(1 << PB1); // PB1 low

while(1)
{
_delay_ms(100);
if( PINB & (1<<PB0))
{
PORTD = 0x00;
}
else
{
PORTD = 0xFF;
}

_delay_ms(500);
}
}


EDIT : There was an error in my bitwise operation. Corrected and mentioned as NEWCODE. Kept the old code as OLD CODE for reference. But, the code is still not working as it should when I connect PB0 to GND.

• how do you know that it's executing? Dec 26, 2016 at 0:58
• Possible duplicate of How do I read digital input on ATmega16? Dec 26, 2016 at 6:31
• @Jasen because,as per IF block, the LEDs connected to PORTD is turned OFF. So, i know that IF block executes. Dec 26, 2016 at 17:08
• Not an answer, but, please get into the habit of putting a "return 0;" line at the end of a non-void main() function. Anyway, rest of your code seems correct. Maybe the problem comes from some configuration (clock etc) registers. Dec 26, 2016 at 19:08

You sure left shifting zero and ORing it works for clearing a bit? From what I can see in your programme​ is that your pin never turns into an input pin because you are ORing it with zero.

How to set,clear and check bits

This answer might tell you how to clear a bit and set the pin as an input and may be you can get your code running.

Sorry. Took a bit long but I executed your code in my system and I get this warning Warning 1 #warning "F_CPU not defined for <util/delay.h>" [-Wcpp] c:\program files (x86)\atmel\atmel toolchain\avr8 gcc\native\3.4.1061\avr8-gnu-toolchain\avr\include\util\delay.h 90 3 Test  But that doesn't really bother the execution of the code. It worked perfect and normal.

And even i tried it in the simulation.

I believe either your hardware is not up and running or else your chip is resetting. Could you provide a schematic?

• You are right about the zero shift. But even if it is wrong in this code example, it should work because the reset state of ATMega IO pins is Hi-Z input. So PB0 will just stay an input, while the pull-up activation is properly performed in the following line. From what I see the code "should" actually work, even if the zero shifts are sematically useless.
– Rev
Dec 26, 2016 at 12:13
• @MaNyYaCk : Have a look into this : maxembedded.com/2011/06/port-operations-in-avr . Setting DDR to 0 at PB0 makes it Input. I guess it explains you.. Dec 26, 2016 at 17:13
• @PraveenMax which part do you want me to specifically look at? Dec 26, 2016 at 17:16
• @Rev1.0 I suggested a safety measure since you know I didn't have a right to comment, I thought I would write an answer to help. Dec 26, 2016 at 17:17
• @PraveenMax: ManYYaCk is correct, that is what he wanted to pointed out with his answer in the first place. Judging from your first comment you seem to miss that a shifted 0 (zero) does NOTHING in that context. You are not explicitly making PB0 an input, however it its configured as an input as default, it does not really matter in this example.
– Rev
Dec 26, 2016 at 17:42