I was recently trying to make an interrupt on my atmega328p using atmelstudio to make a LED that is connected to digitalpin 13/PB5/PCINT5 blink four times as slow as normal when the button that is connected to a 5V output and digitalpin 2/PD0/PCINT18 is pressed down.
But whenever I run the code and press the button it will never(as far as i can tell) go true the interrupt code.
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int t = 1;
int main(void)
{
init();
Serial.begin(9600);
DDRB = (1 << 5);
DDRD &= ~(1 << DDD2); // Clear the PD2 pin
// PD2 (PCINT0 pin) is now an input
PORTD |= (1 << PORTD2); // turn On the Pull-up
// PD2 is now an input with pull-up enabled
EICRA |= (1 << ISC00); // set INT0 to trigger on ANY logic change
EIMSK |= (1 << INT0); // Turns on INT0
sei(); // turn on interrupts
Serial.println("loop started");
while(1)
{
PORTB ^= (1 << 5);
delay(500*t);
}
}
ISR (INT0_vect)
{
Serial.println("interrupt");
if(t=1){
t=4;
}
else{
t=1;
}
}
I went through the datasheet multiple times and eventually stumbled onto this code online (yea yea i know i'm a real piece of work) and added my own pieces to it. but it even this does not work, does anybody know why?
if(t=1)enable/read compiler warnings. There is no way this compiles cleanly with gcc. Also, drop printing from inside an ISR, toggle a pin or something instead. - LundinSerial.printlnin an interrupt is pretty risky and unlikely to work unless the library was designed to be called from interrupts like that. For instance, theprintlnfunction probably waits in a loop for all the bytes to be sent, but they can't be sent because the USART interrupt sends them and only one interrupt can happen at a time. I suggest just writing to avolatilevariable in your interrupt and returning. Your main loop can check the value of the variable and change it back after detecting that the ISR wrote to it. - David Grayson