Joshua LI
Joshua LI

Reputation: 4733

Detect Button Signal on Microcontroller ATmega328P Using C Language

Microcontroller : ATmega328P

I encounter a problem with the following codes. It is used to control the LED light with a button connected to PB0.

There are 2 state :
1. state_0 - All LEDs are OFF.
2. state_1 - All LEDs are ON.

#include <avr/io.h>

int main(void)
{
    DDRB = 0x00;    //set PINB as a input port for receiving PB0 signal
    DDRD = 0xFF;    //set PORTD as a output port for driving the LEDs
    unsigned char state_0 = 0x00;   //all LED bits are off
    unsigned char state_1 = 0xFF;   //all LED bits are on

    PORTD = state_0 //initialize the state  <----Still work here, Not work after this instruction.

    while(1)
    {   
        if(PINB0 == 0 && PORTD == state_0)      //when the button is not pressed and the LEDs are off
        {
            PORTD = state_0;                    //the LED states remain all off 
        }
        else if(PINB0 == 0 && PORTD == state_1) //when the button is not pressed and the LEDs are on
        {
            PORTD = state_1;                    //the LED states remain all on
        }
        else if(PINB0 == 1 && PORTD == state_0) //when the button is pressed and the LEDs are off
        {
            PORTD = state_1;                    //the LED states are turned to all on
        }
        else                                    //when the button is pressed and the LEDs are on
        {
            PORTD = state_0;                    //the LED states are turned to all off
        }
    }
}

After some testing, I find that the microcontoller cannot detect any signal from PB0. When I directly connect Vcc to PB0 or directly connect GND to PB0, I get the same result. When I press the button, nothing is changed.

while(1)
{
    if (PINB0 == 0)
        PORTD = 0x00;
    else
        PORTD = 0xFF;
}

Connection for the above codes : enter image description here
Not work enter image description here


To test the button, I try the following. It is work so the botton work properly.
enter image description here


Do you know what is wrong?
Thank you for your help.

Upvotes: 1

Views: 3308

Answers (1)

Esse
Esse

Reputation: 3298

Problem is that your program doesn't actually detect change of state - if while loop is operating fast enough (and probably is) even brief push to button will trigger both if(PINB0 == 0 && PORTD == state_0) and else part.

Consider adding some kind of checking state - like this:

int old_state = 0;

while(1) {   
    if (old_state != PINB0) {
        if(PINB0 == 0 && PORTD == state_0)      //when the button is not pressed and the LEDs are off
         {
            PORTD = state_0;                    //the LED states remain all off 
        }
        else if(PINB0 == 0 && PORTD == state_1) //when the button is not pressed and the LEDs are on
        {
            PORTD = state_1;                    //the LED states remain all on
        }
        else if(PINB0 == 1 && PORTD == state_0) //when the button is pressed and the LEDs are off
        {
            PORTD = state_1;                    //the LED states are turned to all on
        }
        else                                    //when the button is pressed and the LEDs are on
        {
            PORTD = state_0;                    //the LED states are turned to all off
        }
      }
      old_state = PINB0;
    }

(sorry about bad indentation, it's quite hard to get it right here)

Upvotes: 3

Related Questions