Tutorial Objectives
After completing this AVR microcontroller tutorial readers should be able to:
- Give a simple definition for assembly language.
- Write simple assembly programs.
- Demonstrate good programming practice in writing assembly programs.
Introduction to AVR Assembly Language
What is assembly language?
Assembly language is an alphanumeric representation of machine code. Below is an example of a AVR assembly code written in assembly language. Each line of the code is an instruction telling the microcontroller to carry out a task.
ADD R16, R17 ; Add value in R16 to value in R17
DEC R17 ; Minus 1 from the value contained in R17
MOV R18, R16 ; Copy the value in R16 to R18
END: JMP END ; Jump to the label END
The instructions used in writing programs in assembly language are not general but specific to the microcontroller. Each company provides a set of instructions for there microcontrollers. AVR 8-bits microcontrollers have a commoninstruction set .
Please note that not all instructions are available to all microcontrollers. The set available to each AVR microcontroller is given in its datasheet.
Good Assembly Programming Practice
When writing your AVR assembly programs it is a good practice to organize your code in four columns as shown in the code below. This has the benefit of your program being easier to read/debug by you and others.
;Col_1 Col_2 Col_3 Col_4
ADD R16, R17 ; Add value in R16 to value in R17
DEC R17 ; Minus 1 from the value contained in R17
MOV R18, R16 ; Copy the value in R16 to R18
END: JMP END ; Jump to the label END
Column 1 (Col_1) is used for labels. Labels are basically markers use by the programmer when indicating to the microcontroller to jump to a specific location in the code.
Column 2 (Col_2) is used for the microcontroller instructions.
Column 3 (Col_3) is used for arguments operated on by the instruction in column 2.
Column 4 (Col_4) is used for comments. Note here that a semi-colon ";" is put in front of each comments. That is the semi-colon indicate that the statement that follows it in the same line is a comment.
Writing Macros for the AVR Assembler
Tutorial Objectives
After completing this AVR microcontroller tutorial readers should be able to:
- Give a definition for the term macro.
- Write an assembly macro.
- Discuss the usefulness of macros.
Assembly Macros
What is a Macros?
In assembly programming a macro is basically a set of instruction represented by a single statement. A macro can be seen as a new instruction created by the programmer for the microcontroller.
Note however that this new instruction (the macro) is created by using the existing instructions that are provided with the AVR microcontroller.
Use of an Assembly Macros
Lets say you wanted to initialize the AVR stack pointer. It would take four (4) instructions to accomplish this task as shown in the AVR assembly code below. Here we are loading the last address of SRAM in the AVR microcontroller stack pointer.
;Initialize the AVR microcontroller stack pointer
LDI R16, low(RAMEND)
OUT SPL, R16
LDI R16, high(RAMEND)
OUT SPH, R16
Now instead of writing the four (4) instruction to initialize the AVR stack pointer you can define a macro, say LSP, with these instructions and use this macro to replace the set of instruction as shown in the AVR assembly code below.
;Initialize the stack
LSP R16, RAMEND
Steps in written AVR assembly macros
Macros are simple to code, as show in the code sample below, just follow the simple steps given here:
- All macros definitions starts with the MACRO assembler directive followed by the name of the macro in the same line. Here the name of our macro is LSP.
- Notice in macro definition below the @0 and @1 symbols. These are place holders for arguments that will be passed to the macro, @0 and @1 will be replaced by the first and second arguments respectively. Note you could also have @2, @3 and so on.
- Use the ENDMACRO AVR assembler directive to end the definition of your macro.
.MACRO LSP
LDI @0, low(@1)
OUT SPL, @0
LDI @0, high(@1)
OUT SPH, @0
.ENDMACRO
Once you have defined your macro it can be used just like any other of the AVR microcontroller instructions. Below shows how you would use the macro just define above. Note here that @0 and @1 will be replaced by R16 andRAMEND respectively in the macro definition.
LSP R16, RAMEND
Writing Subroutines for the AVR Microcontroller
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 MUSTinitialize 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
No comments:
Post a Comment