-
1Defining ISRs (Interrupt Service Routines) in AVR Assembly
If you want to use interrupts in your Assembly code, you need to define the interrupt vectors in your code. Luckily, this is done by the linker for you. All you need to do is to give your ISR a specific name, by defining a global label.
For instance, the following code defines the handle for external interrupt 0 (INT0), that can be triggered by pin 2 of Arduino (PD2):
.global INT0_vect INT0_vect: ; your code here reti
You can find the complete list of interrupt handler names in the avr-libc manual, under the section named "Choosing the vector: Interrupt vector names". Not all the vectors are applicable for Arduino Uno: look for "ATmega328P" in "Applicable for device" column to know which vectors are relevant (you can also consult the datasheet).
-
2How to write your ISRs:
1. Your ISR must preserve the values of any registers it uses. Otherwise, it may affect the program coding in unexpected ways. Usually, you'd
push
all the registers that you use at the beginning, andpop
them before returning.2. The ISR should also preserve the value of
SREG
, where the flags are. This is done by copying it to a general purpose register (whose value was already saved to stack), then pushing it into the stack, e.g.:in r0, SREG push r0
and then restore it before:
pop r0 out SREG, r0
This can be omitted if you don't use any instructions that modify the flags. For instance, if you use the ISR to just toggle a GPIO pin and nothing more. I'd still recommend to include this, just in case someone adds some instructions that modify the flags in the future.
3. Using
reti
instead ofret
. That's the same as ret, but it also re-enables interrupts. otherwise, you'd return to the program with interrupts disabled.Note: I recommend to take a look at the assembly code generated by the compiler for ISRs that you create in C. You can open the INT0 Example project and look at the generated assembly code by pressing "F1" in the editor and selecting "View Compiled Assembly Code Listing", go to the "sketch.lst" tab and search for "INT0_vect".
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.