Abstract
The attachInterrupt() sets a function to be called when an external interrupt occurs.
The external interrupt is triggered by one of INT0, INT1, and PCINT0 to PCINT23. On the Arduino Uno, INT0(pin 2) and INT1(pin 3) can be used.
Controling interrupt
The registers EICRA and EIMSK controls the external interrupt.
EICRA
EICRA contrls how the interrupt is detected.
EICRA | ||||||||
---|---|---|---|---|---|---|---|---|
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Name | - | - | - | - | ISC11 | ISC10 | ISC01 | ISC00 |
The combination of ISC11 and ISC10 controls the condition of INT1(pin 3), and ISC01 and ISC00 controls that of INT0(pin2).
ISC11/ISC01 | ISC10/ISC00 | Condition |
---|---|---|
0 | 0 | Low level |
0 | 1 | Any bitwise change |
1 | 0 | The falling edge |
1 | 1 | The rising edge |
EIMSK
The EIMSK(External Interrupt Mask Register) enables and disables external interrupt.
EIMSK | ||||||||
---|---|---|---|---|---|---|---|---|
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Name | - | - | - | - | - | - | INT1 | INT0 |
When the bit is 1, it enables interrupt. Also I bit of the status register need to be 1.
Source Code
The attachInterrupt() is defined in hardware/arduino/avr/cores/arduino/WInterrupts.c as below. Only the souce code for Arduino UNO is quoted. The original source code supports many tips using #if’s.
|
|
|
|
The voidFuncPtr is a pointer to function which has no argument and returns void. As EXTERNAL_NUM_INTERRUPTS is defined as 2, the array can hold 2 functions. Initial value is noghint() which dose nothing.
The input is interruptNum, userFunc and mode. The types are uint8_t, void(*)(void) and int. It has no output.
|
|
When the interrupt is less than EXTERNAL_NUM_INTERRUPTS, rest of the code is executed.
The function specified by an argument is stored to intFunc[].
|
|
Sets the registers related to interrupt number.
|
|
The operation is a little bit difficult( to me), I will dissect them.
|
|
ISC00 and ISC01 are 0 and 1 respectively. 1 « ISC00 is 1(0b00000001) and 1«ISC01 is 2(0b00000010).
Bitwise OR of them is 0b00000011(=3).
|
|
Next calculate the bitwise AND of EICRA and ~((1 « ISC00) | (1 « ISC01))).
As ((1 « ISC00) | (1 « ISC01))) is 0b00000011, the bitwise NOT is 0b11111100.
Then calculating bitwise AND of EICRA and 0b11111100 would clear lower 2 bits of EICRA.
Next calculate bitwise OR of mode « ISC00. As ISC00 is 0, it is same as calculate bitwise OR with mode.
|
|
The mode is one of the LOW, CHANGE, RISING and FALLING and they are 0, 1, 2, 3 respectively.
The value of mode is not checked, if we specify invalid value, it may do something bad.
INT0_vect and INT1_vect are Interrupt handllers.
|
|
ISR() is a macro to define interrupt handllers.
Version
Arduino AVR Boards 1.8.6
Last Update
March 21, 2023