On this page the basics of the interrupt system on an AVR 328P (Arduino UNO) is given as an example on interrupt systems.
It only deals with the basic functionallity.
More modern CPU architetures may have more complicated ISR systems so take this as a teaser.
Interrupts
An interrupt (caused by external activation on digital pin or internal affairs) is the ablility to stop execution of main code
and jump to code associated with the interrupt and after execution continue the main code.
Its a wellknown feature and is used everywhere.
In many system a couting timer is issuing interrupts with fixed intervals. The interrupt service routine (IRS) is then maintaining a clock - like in the primitive example below.
volatile unsigned long sysTime;
ISR(TIMER_ISR)
{
sysTime++;
}
The standard Arduino way is explained here.
You are not directly installing your function as an interrupt service routine (ISR). Instead an Arduino ISR is installed on and your code is called from this one.
This in someway to ensure or prevent you dont to do anything that may harm the system - like misconfigure the ISR system.
Interrupts can on AVR can be configured to react one
LOW - continous interrupt triggered
RISING - level change low to high
FALLING - level change high to low
CHANGE - level change either ways
Example below is from this Arduino page
(click for code)
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
Interrupts directly on the HW
A 328P has two direct external interrupts
INT0 - port PD2 - D2 pin
INT1 - port PD3 - D3 pin
(click for image)
Interrupt vector table
Interrupt handling is vectorized/table controlled.
When an interrupt takes place a jump address is in vectorized in a table in RAM:
(click for table)
We do have some help to get our ISR called from the ISR vectortable. The macro ISR and the predefined address references INT0 and INT1 get reference to the ISR code to written in the vector table.
In addition the ISR does also take care of preserving state of the interrupted program by pushing CPU registers on the stack somethe ISR can 1) use themm 2) reestablish them when interrupt is finish.
(click for code)
// your code
ISR(INT0_vect) {
//here goes your ISR code
}
and the code disassembled: (avr-objdump -S -D <>.elf
ISR(INT0_vect) {
652: 1f 92 push r1
654: 0f 92 push r0
656: 0f b6 in r0, 0x3f ; 63
658: 0f 92 push r0
65a: 11 24 eor r1, r1
}
65c: 0f 90 pop r0
65e: 0f be out 0x3f, r0 ; 63
660: 0f 90 pop r0
662: 1f 90 pop r1
664: 18 95 reti
void setup() {
etc
and the ISR vector table
00000000 <__vectors>:
0: 0c 94 5d 00 jmp 0xba ; 0xba <__ctors_end>
4: 0c 94 29 03 jmp 0x652 ; 0x652 <__vector_1> --- INT0 see above INTO is on addr 0x652
8: 0c 94 33 03 jmp 0x666 ; 0x666 <__vector_2> --- INT1
c: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
10: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
14: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
18: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
1c: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
20: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
24: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
28: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
2c: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
30: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
34: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
38: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
3c: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
40: 0c 94 df 02 jmp 0x5be ; 0x5be <__vector_16>
44: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
48: 0c 94 ad 02 jmp 0x55a ; 0x55a <__vector_18>
4c: 0c 94 87 02 jmp 0x50e ; 0x50e <__vector_19>
50: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
54: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
58: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
5c: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
60: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
64: 0c 94 85 00 jmp 0x10a ; 0x10a <__bad_interrupt>
Links
(click for code)
|