Sorry for any noobiness, I'm more of a software engineer.
How do I use button interrupts in general?
As in, if I put my microcontroller to sleep, I'd like a button to wake it up.
How should I go about doing this?
Edit
Adding this to main, thanks to @jippie
DDRD &= ~(1<<PIND2)
PORTD |= 1<<PIND2
GICR |= ( 1 << INT0 ); // Enable INT0
MCUCR = (0<<ISC00)|(1<<ISC01);
sei();
And this outside of main
ISR(INT0_vect) {
sleep_disable(); // If ISR got called while it was sleeping, this would work
lcd.string("works");
};
ISR does work, but only if the device is not sleeping.
FIXED
Changing from INT0 to INT2 ( and moving from PIND2 to PINB2 ), it works…
According to documentation, INT0 and INT1 use level interrupts but PINB uses edge… so.. that's maybe why?
My voltage meter drops to .2 while in sleep mode, then wakes up from ISR.
Best Answer
\$\overline{\mathsf{RESET}}\$
A push button from \$\overline{\mathsf{RESET}}\$ to ground is the easiest way, but it forgets current state entirely.
Interrupts
For interrupts to work you need a pin that attributed as
INTn
and for ATmega32 you are limited toPB2
,PD2
orPD3
. Not all sleep modes support waking up by external interrupt and different sleep modes support edge or level triggered interrupts.For thes pins you have to:
GICR
;MCUCR
andMCUCSR
.You don't need to add an complete ISR (interrupt service routine) if all you want to do is wake up and continue where you left off, but you shouldn't rely on the default vector. It depends on the compiler what actually happens on a bad interrupt. Refer here for the name of the interrupt vector to use.
For details check the chapter titled 'External Interrupts' in the ATmega32 datasheet.
For a button to ground on PD2 (
INT0
) code might look a bit like this (untested):