// * blinking LED program *
#include <avr/io.h>
; either expected by linker, equivalent to the "old style" .ORG 0
; or alternatively generated by the C/C++ compiler on its own accord
.TEXT
_start:
jmp start
; interrupt table would follow *** here *** if there are any interrupt services
; 32bits per entry, up to 34 entries
; this is the part of the loader program that initializes the stack etc.
.TEXT
start:
ldi R16, 0xFF & (RAMEND>>8)
out _SFR_IO_ADDR(SPH), R16
ldi R16, 0xFF & RAMEND
out _SFR_IO_ADDR(SPL), R16
; main program function starts here
.GLOBAL main
main:
main_initialize:
cbi _SFR_IO_ADDR(PORTB), 3
; Using PORTB, Pin3 as output
; other pins kept as inputs as they were originally
sbi _SFR_IO_ADDR(DDRB), 3
main_superloop:
; LED on
sbi _SFR_IO_ADDR(PORTB), 3
; and wait
ldi R21, 0
ldi R20, 100
rcall delay_in_ms
; LED off
cbi _SFR_IO_ADDR(PORTB), 3
; and wait
ldi r21, 0
ldi r20, 100
rcall delay_in_ms
; and do ti forever
rjmp main_superloop
; this function
; - T.B.A. receives a short int variable in registers [r21,r20]
; - causes time delay of that many milliseconds by wasting time and energy
;
delay_in_ms:
push R16
in R16, _SFR_IO_ADDR(SREG)
push R16
.equ OneMS, 16000000 / 5 / 1000 ; 16000 for quartz FRQ, /1000 for 1 ms, /5 for the duration of the loop
push R17
push R18
push R19
; TO DO: add the loop to run the delay [r21,r20] times
ms_counter_loop:
ldi R19, 0xFF & ( OneMS >> 16 )
; note -- we only need two registers but that would speed up the loop and mabye we would have to go back to three registers to keep the count
ldi R18, hi8 (OneMS) ; or 0xFF & ( OneMS >> 8 )
ldi R17, lo8 (OneMS) ; or 0xFF & OneMS
delay_loop:
subi R17, 1
sbci R18, 0
sbci R19, 0
brcc delay_loop
subi R20, 1
sbci R21, 0
brcc ms_counter_loop
pop R19
pop R18
pop R17
pop R16
out _SFR_IO_ADDR(SREG), R16
pop R16
ret