-1

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.

PraveenMax
  • 109
  • 6
  • 1
    how do you know that it's executing? – Jasen Слава Україні Dec 26 '16 at 00:58
  • 2
    Possible duplicate of [How do I read digital input on ATmega16?](http://electronics.stackexchange.com/questions/5302/how-do-i-read-digital-input-on-atmega16) – MaNyYaCk Dec 26 '16 at 06:31
  • 1
    @Jasen because,as per IF block, the LEDs connected to PORTD is turned OFF. So, i know that IF block executes. – PraveenMax Dec 26 '16 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. – Rohat Kılıç Dec 26 '16 at 19:08

1 Answers1

1

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

Reading input on AVR

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.

1

2

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

MaNyYaCk
  • 1,448
  • 1
  • 13
  • 28
  • 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 '16 at 12:13
  • @MaNyYaCk : Have a look into this : http://maxembedded.com/2011/06/port-operations-in-avr/ . Setting DDR to 0 at PB0 makes it Input. I guess it explains you.. – PraveenMax Dec 26 '16 at 17:13
  • @PraveenMax which part do you want me to specifically look at? – MaNyYaCk Dec 26 '16 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. – MaNyYaCk Dec 26 '16 at 17:17
  • @Rev1.0 Yes. The code should work even though I am zero shifting(as I dont want assume things). Am I am missing something?? – PraveenMax Dec 26 '16 at 17:18
  • @PraveenMax How about trying the pin number instead of putting PB0 or PB1? – MaNyYaCk Dec 26 '16 at 17:19
  • @MaNyYaCk Since its a big article, i will post you the snippet below, `The following declarations are one and the same. PORTD = (1 << PD0)|(1 << PD3)|(1 << PD6); PORTD = (1 << 0)|(1 << 3)|(1 << 6); PORTD = 0b01001001; PORTD = 0x49;` – PraveenMax Dec 26 '16 at 17:20
  • @PraveenMax X|=(1<<0) and X|=(0<<1) is two different thing. The first one is shift one to the zeroth position from the right and OR it with X and save into X ,which means 0th position on the X will be 1 irrespective of what was there before OR operation. In other case , it won't change anything because you are ORing with a 0 on the first position, so ORing with 0 doesn't change the state of the bit and it doesn't make any sense to use it – MaNyYaCk Dec 26 '16 at 17:25
  • 1
    @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 '16 at 17:42
  • @MaNyYaCk Rev1.0 Exactly. So, should I perform AND instead of OR?? – PraveenMax Dec 26 '16 at 17:46
  • @MaNyYaCk I have updated the code but still its not working. – PraveenMax Dec 26 '16 at 18:37
  • @PraveenMax I updated my answer – MaNyYaCk Dec 29 '16 at 15:06
  • @MaNyYaCk : thanks for update. I am using Induino r5 (http://www.induino.com/2013/07/list-of-contents.html ) . I have connected LEDs for all the PINS in PORTD. Then, I have a Male-to-Female jumper wire connected with PB0 ( Male part). Now when I connect the female part of jumper wire(PB0) to GND, the value in PB0 changes from 1 to 0 (Am I right?). – PraveenMax Jan 02 '17 at 18:00
  • @PraveenMax yeah. – MaNyYaCk Jan 03 '17 at 05:00
  • @MaNyYaCk It seems that the fault resides in the board itself. I have tried the same code in another arduino Uno and it worked perfectly. Thanks for helping me out. – PraveenMax Jan 04 '17 at 09:59