Go Down

Topic: Attachinterrupt question (Read 465 times) previous topic - next topic

jerseyguy1996

Reading the documentation in the library reference it seems that this is allowed:

Code: [Select]
attachInterrupt(0, myISR, LOW);

//do something here


detachInterrupt(0);
attachInterrupt(0, myOtherISR, LOW);

//do other stuff


How does this work exactly?  My understanding of interrupts on the Atmega is that the interrupt jumps to the corresponding interrupt vector which has the instruction to jump to the ISR.  I wasn't aware that the ISR specified at the interrupt vector could be changed during the running of the program.
Arduino Uno;
Mega328

tmd3

The jmp instruction at the interrupt vector doesn't change.  The program keeps track, in SRAM, of which program is associated with the interrupt.  When the interrupt fires, the program fetches that data, and decides which code to execute.  I can't tell for certain exactly how it works, but it looks to me like the ISR fetches a pointer to the function that was last named in attachInterrupt().  Maybe someone more erudite than I will chime in and clarify it.

You could do something similar, without resorting to attachInterrupt() and detachInterrupt(), with something like this - pseudocode, with break statements omitted:
Code: [Select]
ISR(INT0_vect) {
  switch(actionCode) {
  case 1: do something;
  case 2: do something else;
  case 3: do yet a another thing;
  }
}

Nick Gammon

The attachInterrupt call stores your function in a small table (indexed by the interrupt number).

When an interrupt fires it checks if that is not NULL,  and if so jumps to that function.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

johnwasser

It's Open Source so you can always study the implementation.  Here it is with the code to enable and disable the specific interrupt removed:
Code: [Select]

static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
    intFunc[interruptNum] = userFunc;
  }
}

void detachInterrupt(uint8_t interruptNum) {
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
    intFunc[interruptNum] = 0;
  }
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

jerseyguy1996

Great explanations guys!  Thanks!  I wanted to use the timer interrupts on the Atmega but there may be 2 or 3 functions that could run on one timer interrupt, based on the current state of the machine.
Arduino Uno;
Mega328

PaulS

Quote
I wanted to use the timer interrupts on the Atmega but there may be 2 or 3 functions that could run on one timer interrupt, based on the current state of the machine.

I suspect, then, that LOW is not the correct trigger for the interrupt handler. FALLING, maybe.

UKHeliBob

Quote
I wanted to use the timer interrupts on the Atmega

attachInterrupt() and detachInterrupt() are not used with timer interrupts though.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Nick Gammon

http://www.gammon.com.au/forum/?id=11504
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

jerseyguy1996

Great link!  That helps a lot!
Arduino Uno;
Mega328

Go Up