Hey all,
I'm having trouble with a variable modified in the ISR but not being updated in the main code. A couple comments:
- My variable is volatile
- My ISR is being called (in the code below, if the LED toggling is moved to the ISR it works just fine)
- I don't think I have any other interrupts enabled, so I don't think the whole unit is resetting as I saw suggested in another thread
- I've actually got the code working on an ATmega328p, but "translated" for an ATtiny1616 it doesn't work
Here's the code I'm having trouble with. I've got a button that connects ground to PC1 that triggers the ISR and an LED wired to PC0 that I am trying to toggle by modifying the global volatile x.
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> volatile char x; const uint8_t led_pin = 0; // PORT C const uint8_t btn_pin = 1; // PORT C int main() { // LED setup PORTC.DIR |= (1 << led_pin); // Set LED pin to output // Button setup PORTC.DIR &= ~(1 << btn_pin); // Set button as input PORTC.PIN1CTRL |= (1 << 3); // Enable pull-up resistor // Set interrupt on falling edges PORTC.PIN1CTRL |= (1 << 0); PORTC.PIN1CTRL |= (1 << 1); sei(); // Set global interrupts while(1){ if (x == 1){ PORTC.OUT ^= (1 << led_pin); // toggle led _delay_ms(500); // debounce x = 0; // unset x } } } ISR(PORTC_PORT_vect) { x = 1; // set x PORTC.INTFLAGS |= (1 << 1); // Clear interrupt flag }
For comparison, here's my working code for the ATmega328p that does the same thing:
#include <avr/io.h> // for pin and address functions #include <avr/interrupt.h> // for interrupt related commands #include <util/delay.h> volatile char x; const uint8_t led_pin = PD5; // This is digital pin 5 const uint8_t btn_pin = PD2; // This is the INT0 external interrupt pin int main() { // LED setup DDRD |= (1 << led_pin); // Set LED pin to output // Button setup DDRD &= ~(1 << btn_pin); // Set button as input PORTD |= (1 << btn_pin); // Enable pull-up resistor // Set INT0 interrupt behaviour: Interrupt on falling edges EICRA |= (1 << ISC01); EICRA &= ~(1 << ISC00); sei(); // Set global interrupts EIMSK |= (1 << INT0); // Set INT0 interrupts while(1){ if (x == 1){ PORTD ^= (1 << led_pin); // Set LED pin to high _delay_ms(500); x = 0; } } } ISR(INT0_vect){ x = 1; // set x }
Any ideas guys? I'm using El Tangas' jtag2updi programmer, avr-gcc 8.2.0, and avrdude 6.3. Thanks for taking the time to read this!
Cheers,
S