Tutorial Objectives
After completing this AVR microcontroller tutorial readers should be able to:
- Give a definition for the term subroutine.
- Write an assembly subroutine.
- Discuss the usefulness of macros.
AVR Subroutines
What are subroutines?
A subroutine is the assembly equivalent of a function in C. Subroutines are generally use when there are blocks of code that are executed more than once. Subroutines allow for the block of code to be written once then call upon when it is required.
Very Important
There are two very important points you always need to remember when using subroutines:
- When a subroutine is called the microcontroller needs to save the address of the instruction that follows the subroutine call. This is necessary as the microcontroller needs know where to return after the execution of the subroutine. Now the microcontroller internally save this address on the stack. As such the programmer MUST initialize the stack. This is done by storing the starting address of the stack in the stack pointer. The AVR assembly code below shows an example, here the stack pointer of an ATMega8515 AVR microcontroller is being loaded with the last address in SRAM memory. For more information on the AVR stack operation see the AVR Stack & Stack Pointer tutorial.
.include "m8515def.inc"
;Initialize the microcontroller stack pointer
LDI R16, low(RAMEND)
OUT SPL, R16
LDI R16, high(RAMEND)
OUT SPH, R16
- When executing a subroutine the microcontroller needs to know where is the end of the subroutine in other to return to the point in the code where it was before the subroutine was called. The programmer indicate this by putting the RET at the end of the subroutine.
By the way to actually call an AVR subroutine we use either the RCALL or CALL AVR instructions. Note that the RCALL instruction is not available to all the AVR microcontroller so check the datasheet for the microcontroller before using the RCALL instruction.
Writing a Subroutine
The following AVR assembly program toggles the logic value on the pins of portB of an ATMega8515 AVR microcontroller with a delay after each change. Here the delay is provided by the
"Delay" subroutine.
.include "m8515def.inc"
;Initialize the microcontroller stack pointer
LDI R16, low(RAMEND)
OUT SPL, R16
LDI R16, high(RAMEND)
OUT SPH, R16
;Configure portB as an output put
LDI R16, 0xFF
OUT DDRB, R16
;Toggle the pins of portB
LDI R16, 0xFF
OUT PORTB, R16
RCALL Delay
LDI R16, 0x00
OUT PORTB, R16
RCALL Delay
;Delay subroutine
Delay: LDI R17, 0xFF
loop: DEC R17
BRNE loop
RET
AVR Tutorials hopes this AVR assembly tutorial on writting AVR assembly subroutines was beneficial to you and looks forward to your continued visits for all your microcontroller tutorial needs.