FAQ:Interrupts
From GNU 68HC11/HC12
This FAQ section gives some tips about interrupts on 68HC11 and 68HC12.
How can I define an ISR function (Interrupt Service Routine)?
Many embedded compilers use keywords or #pragma, but GCC finds consistency by using function attributes. Here is an example to flag the function "GotKeypress" as an ISR. Note that it is usually practical to also define it as a 'near' function, to avoid using a trampoline if using a banked memory model:
void attribute((interrupt,near)) GotKeypress (void) { [...] }
See 5.25 Declaring Attributes of Functions
How can I setup an interrupt table for a ROM?
A special section exists for the definition of the interrupt vector table of the 68HC11 or 68HC12. The vectors must be in a section named .vectors.
In assembly, use:
.sect .vectors
With gcc, use:
__attribute__ ((section (".vectors")))
How can I define an interrupt table?
This seems to work for me (borrowed from other users)
void __attribute__((interrupt)) sci_int(void){ char inchar; inchar = SC0SR1; //needed to clear RDRF flag inchar = SC0DRL; //read incoming character sci_putch(inchar); }
void __attribute__((interrupt)) isr_empty(void){/* do nothing */}
extern void _start(void);/* entry point in crt0.s */
void __attribute__ (( section (".vectors") )) (* const interrupt_vectors[])(void) = { isr_empty, /* $ffc0: reserved */ isr_empty, /* $ffc2: reserved */ isr_empty, /* $ffc4: reserved */ isr_empty, /* $ffc6: reserved */ isr_empty, /* $ffc8: reserved */ isr_empty, /* $ffca: reserved */ isr_empty, /* $ffcc: reserved */ isr_empty, /* $ffce: reserved */ isr_empty, /* $ffd0: reserved */ isr_empty, /* $ffd2: reserved */ isr_empty, /* $ffd4: reserved */ sci_int, /* $ffd6: SCI serial system */ isr_empty, /* $ffd8: SPI serial transfer complete (SPIE) */ isr_empty, /* $ffda: Pulse accumulator input edge (PAII) */ isr_empty, /* $ffdc: Pulse accumulator overflow (PAOVI) */ isr_empty, /* $ffde: Timer overflow (TOI) */ isr_empty, /* $ffe0: Timer channel 7 */ isr_empty, /* $ffe2: Timer channel 6 */ isr_empty, /* $ffe4: Timer channel 5 */ isr_empty, /* $ffe6: Timer channel 4 */ isr_empty, /* $ffe8: Timer channel 3 */ isr_empty, /* $ffea: Timer channel 2 */ isr_empty, /* $ffec: Timer channel 1 */ isr_empty, /* $ffee: Timer channel 0 */ isr_empty, /* $fff0: Real-time interrupt (RTII) */ isr_empty, /* $fff2: -IRQ (external pin) */ isr_empty, /* $fff4: -XIRQ pin */ isr_empty, /* $fff6: Software interrupt */ _start, /* $fff8: Illegal opcode trap */ _start, /* $fffa: COP failure (NOCOP) */ _start, /* $fffc: Clock monitor fail (CME) */ _start /* $fffe: -RESET (hardware reset) */ };