0

I have a small task to program the following using C, for an ATmega48 controller:

In the beginning, all (6) LEDs are turned on. When button SW1 is pressed, LEDs are only allowed to be turned off with the respective buttons. When button SW2 is pressed, LEDs are only allowed to be turned on with the respective buttons.

Here is what I came up with:

#define F_CPU 1000000UL
#include <asf.h>
#include <util/delay.h>

volatile unsigned char r,d;
ISR(INT0_vect)
{
    if (d = 0)
    {
        PORTB = PORTB | 1<<1;
        d = 1;
    }
    else
    {
        PORTB = PORTB | 0<<2;
        d = 0;         
    }
}
int main (void)
{
    d = 0;
    DDRC = 0x00;
    PORTC = 0xFF;
    DDRB= 0xFF;
    PORTB = 0x00;
    PCICR = 0b00000001;
    sei();
    while(1)
    {
        PCMSK0 = 0b00000100;
        while (d == 0) 
        {
            for (int i=0; i<6; i++)
            {
                if(!(PINC & (1<<i)))
                    PORTB = PORTB | i<<1;
            }
        }
        PCMSK0 = 0b00000010;
        while (d == 1)
        {
            for (int i=0; i<6; i++)
            {
                if(!(PINC & (1<<i)))
                    PORTB = PORTB | i<<0;
                r = r<<1;
            }
        }
    }
}

When I tried to simulate in Atmel AVR Studio, wrong LEDs were turning on when I pressed the respective buttons (e.g. LED2 for SW4), and interrupts never happened.

Please explain what I've done wrong, as I have already scoured several resources, and each one gives a different approach, which I fail to comprehend.

2
  • 1
    You're not being very clear with how things are connected. There seems to be more switches than the two you name (SW1 and SW2). Also, did you consider switch bounce? Commented May 20, 2015 at 6:51
  • What do you mean with PORTB = PORTB | 0<<2;? This code does nothing! ... If you want to turn off the bit 2 you have to use PORTB = PORTB & ~(1<<2); Commented May 20, 2015 at 10:24

1 Answer 1

2

Though since you have not initialied interrupts in a proper way, These lines of code here which are not being executed at all, have two issues.

if (d = 0)
{
    PORTB = PORTB | 1<<1;
    d = 1;
}
else
{
    PORTB = PORTB | 0<<2;
    d = 0;         
}

One issue that is clearly visible is: if (d = 0) does not check if d is equal to 0, instead it assigns 0 to d every single time.

Are you trying to set and clear the pins? If yes, this is not the way it is supposed to be done. Usually in Embedded we set the pins this way: PORTB |= (1<<1); //you have got this right
and clear the pins by PORTB &= ~(1<<1);


You stated that interrupts never happened. It is then a valid conclusion that d remains 0 all the time and you loop in while (d == 0) {} all the time. So r is never modified unless from elsewhere/apart from the code you have shown. Does this r have any implementation related to GPIO for LEDs? If Yes, then you have to first fix the issues in interrupts.


The reason behind interrupts never happened is that you have not initialized the External interrupts at all.

You need to configure EICRA – External interrupt control register A register.

enter image description here enter image description here enter image description here

Then you need to configure the EIMSK – External interrupt mask register enter image description here

Then you need to configure the EIFR – External interrupt flag register enter image description here


Reading the datasheet always helps to understand the implementation details.

Sign up to request clarification or add additional context in comments.

1 Comment

In AVR, interrupts are disabled while an interrupt handler is running, (unlike on some other chips). They are enabled again on return from the interrupt handler. There is no need to call cli() in the handler. Nested interrupts are not allowed by default. You can allow them, but you have to call sei() in the handler explicitly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.