goofy interrupts

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was using the following interrupts (triggered by diddling the joystick of my AVR Butterfly with an ATMEGA169P on board) to switch on 2 leds alternately. Each of the led is connected to a PORTE pin of the Butterfly board.

ISR(PCINT0_vect) //left and right
{
sei();
control=1;
}

ISR(PCINT1_vect) //up, down, and push
{
sei();
control=0;
}

In my main loop, I have the following code:

while(1)
{
while(control == 0)
{
PORTB=0b00000001;
control=0;
}

while(control == 1)
{
PORTB=0b00000010;
control=1;
}

}

The problem is that the leds don't seem to respond well to the joystick. Sometimes it does respond immediately, sometimes it is sluggish, sometimes it just doesn't budge.

I have verified that there is no problem with the joystick connection by testing the AVR butterfly code from ATMEL's website on my butterfly board.

Can anyone help?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Butterfly User Guide shows no hardware for debouncing the joystick signals. So I guess you have to do this by software. You can look at the butterfly firmware to see how Atmel implemented debouncing. The firmware ported to GCC can be downloaded here.

BTW. You don't need to reenable interrupts inside the ISR with the sei() instruction. Every ISR is terminated by the RETI instruction automatically. And the RETI instruction does enable interrupts. What you do is using nested interrupts. Usually not really what you want.

You have not posted how you have declared the variable "control". It should be declared as volatile.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't sei() in an interrupt - you open the potential to flood the stack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Cliff,

Congratulations you have posted 10k times!!!!
Thank you for being there and helping out so many people!!!!

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh bugger it, I thought that if I slipped in by the back door no one would notice it!

Thanks for the "congrats".

(it's partly because I've got a meeting in 10 minutes but wanted to have a quick read - but didn't want to clear all my message read counters as would have happend if I logged in as "clawson" - well that's my excuse and I'm sticking to it. Operation Grande Canal went well by the way!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is also not the best way to do things.

Yes I agree, first remove the SEI from the interrupt code. Then make sure the variable "control" is declared volatile, so the compiler knows it can change anytime.

Third thing is that what happens if your interrupt happens in the most inappropriate place:

while(control == 0)
{
PORTB=0b00000001;
 // WHAT IF INTERRUPT HAPPENS AND SETS CONTROL = 1 HERE??? NOTHING!!
control=0;
} 

See the problem in the logic there?

So I would remove the control=0 and control=1 from the loops too. If they are 0, they do not need to be set to 0 again (or 1 if 1), since you want to know if it has changed instead of actively ignoring the change.

So basically, it has nothing to do with goofy interrupts - it's goofy way to code.

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I fixed the problem after I did what was suggested...I also realized that I had disabled pull-up on some pins when I did PORTB=0b00000001 and after I fixed that, the interrupts worked without a glitch.

Thanks guys!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

...I also realized that I had disabled pull-up on some pins when I did PORTB=0b00000001

True enough, that would disable pullups--but ONLY if DDRB is 0. From your other thread, you post DDRB = 0xff.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.