MIC 15 - Arduino Assembly
MIC 15 - Arduino Assembly
Lesson 16
2
Arduino Assembly
1.#include<stdio.h>
2.int count = 0;
You can write a code using 3.void main()
only C like the hello world 4.{
code beside: 5.for( i = 0; i<100; i++)
6. {
7. printf("hello world %d", i);
8. }
9.}
You can also mix C and assembly using the "asm" pseudo-function. By using
the "naked" attribute for functions, you can write your entire program in
assembly code, but from within a C file so that the compiler takes care of all
the labels, section directives, etc. For example:
void somefunction(void) __attribute__((naked))
{
asm volatile ("
; your assembly code here
");
}
3
Blink LED on PB5(Arduino Uno pin 13)
4
Example Analysis:
; Blink LED on PB5(Arduino Uno pin 13)
; http://forum.arduino.cc/index.php?topic=159572#msg1194604
#define __SFR_OFFSET 0
#include "avr/io.h"
.global main
main:
sbi DDRB, 5 ; Set PB5 as output (Set bit in I/O register ) P[b] ←1
blink:
sbi PINB, 5 ; Toggle PINB P[b] ←1
5
6
ldi r25, hi8(1000) ;Load constant
ldi r24, lo8(1000) ;Load constant
call delay_ms
jmp blink
Assuming that our Arduino AVR is running at 16 MHz (16 Million clock
cycles per second), how long does all this take?
T = 1/ F then T = 1 / 16E6
T = 0,0000000625 seconds, not precisely 0,06 us
The human eye can’t make out a difference in the picture frame
if it appears for less than 16ms to 13ms (0,016-0,013s).
7
Hence purely based on this we can say sampling frequency is
60Hz to 80Hz (about 0,06 & 0,08 MHz).
So we will need to know how many times we will loop to in
terms of a cycle of say half a second (0.5sec) off and half a
second (0.5sec) on so that the LED flashes every half a
second at a frequency of 16 MHz we need x cycles. Here’s
how:
8
How to achieve all these cycles if I can count only up to 255
(remember, we have an 8-bit chip)?
For this, we will have to implement two loops: inner
and outloop. See how:
9
delay_ms:
;Delay about (r25:r24)*ms. Clobbers r30, and r31.
; One millisecond is about 16000 cycles at 16MHz.
; The inner loop takes 4 cycles, so we repeat it 3000 times
ldi r31, hi8(4000) ;Load constant
ldi r30, lo8(4000) ;Load constant
1:
sbiw r30, 1 ;Set bit in I/O register
brne 1b ; Branch if not equal
sbiw r24, 1 ;Set bit in I/O register
brne delay_ms ; Branch if not equal
ret
Every time the registers don’t overflow the loop takes adiw(2) +
brne(2) = 4 cycles.
This is done 0xFFFF (65 535) times before the overflow occurs.
The next time the loop only needs 3 cycles, because no branch
is done.
This adds up to 4 * 65 535(looping) + 3(overflow) + 2(clr) = 262
145 cycles. This is still not enough: 8 000 000/262 145 ~ 30.51. 10
Instruction : Cycle : Descriptions
ldi : 1 : Load Immediate Into ; Loads an 8-bit constant directly to regs.16 to 31.
cbi : 1 : Clear Bit In I/O Register — Clears a specified bit in an I/O register.
sbi : 1 : Set Bit in I/O Register — Sets a specified bit in an I/O Register.
out : 1 : Store Register to I/O Location — Stores data from register Rr in the
Register File to I/O Space (Ports, Timers, Configuration Registers, etc.).
dec : 1 : Decrement — Subtracts one from the contents of register Rd and
places the result in the destination register Rd.
adiw : 2 : Add Immediate to Word — Adds an immediate value (0–63) to a
register pair and places the result in the register pair.
brne : 2 : Branch if Not Equal — Conditional relative branch. Tests the Zero Flag
(Z) and branches relatively to PC if Z is cleared.
rcall : 1 : Relative Call to Subroutine — Relative call to an address within PC
ret : 1 : Return from Subroutine — Returns from the subroutine.
rjmp : 1 : Relative Jump — Relative jump to an address.
11