why unintialized stack errors?
2007-01-02 by Thomas Keller
As far as I can see, I am initializing the stack point to RAMEND, but
when i simulate this code, i am getting an uninitialized stack error
when the rcall instrcution is hit. Why for?
.include "tn25def.inc"
; Define here the variables
;
.def temp =r16
; Define here Reset and interrupt vectors, if any
;
RESET:
rjmp START
reti ; Addr $01
reti ; Addr $02
reti ; Addr $03
reti ; Addr $04
reti ; Addr $05
reti ; Addr $06 Use 'rjmp myVector'
reti ; Addr $07 to define a interrupt vector
reti ; Addr $08
reti ; Addr $09
reti ; Addr $0A
reti ; Addr $0B This is just an example
reti ; Addr $0C Not all MCUs have the same
reti ; Addr $0D number of interrupt vectors
reti ; Addr $0E
reti ; Addr $0F
reti ; Addr $10
; Program starts here after Reset
;
START:
; this table povides the data for the intensity curve needed for
; xxxxxxxxxxxxxxx. the data represent the value sin^3 * 255 for
; each angle from 0 through 90 at .9 degree increments
.eseg
TABLE:
.db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 5, 6, 6
.db 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 36
.db 39, 44, 48, 52, 55, 59, 62, 66, 70, 74, 78, 82, 86, 90, 94, 99
.db 103, 108, 112, 117, 121, 126, 130, 135, 140, 144, 149, 153
.db 158, 163, 167, 172, 176, 180, 185, 189, 193, 197, 201, 205
.db 209, 212, 216, 219, 223, 226, 229, 232, 234, 237, 239, 242
.db 344, 346, 247, 249, 250, 252, 253, 254, 255, 255, 255
;
.cseg
BEGIN:
ldi r30, RAMEND ; initialize stack pointer
out SPL, r30
ldi r31, 0x00 ; set up EEPROM high byte address
out EEARH, r31 ; store in register
ldi r31, 0x00 ; set up upper WGM bytes
out WGM01, r31 ; and once again
ldi r31, 0x03 ; set upo to set waveform
configuration
out WGM00, r31 ; output to appropriate
control register
;
; set up timer delay for ~~.01 second
;
; counter clock will be prescaled by 1024 to make the .01 second
count easier
;
ldi r31, 0x38 ; load low byte of delay count
out TCNT0, r31 ; output to counter/timer 0-
ldi r31, 0xe5 ; load the control value for
TCCR1
; CTC1 set, PWMa set, COM1A set to
; toggle on match, timer clock set
; for system clock divided by 256
out TCCR1, r31 ` ; store in register
ldi r31, 0x01 ; load value for TCCR01A
out TCCR0A, r31 ; and strope to TCCR01A
ldi r31, 0x04 ; load value for TTCCR01B
out TCCR0B, r31 ; output to TCCR01B
ldi r31, 0x00 ; load compre output macthj value
out OCR0A, r31 ; stroe in output
compare register 0A
;
; this code sets the default initial table adress at -1. It will
automatically
; increment on the first access, to 0
;
ldi r16, 0xff ; first addresss - 1 in
EEPROM table data
ldi r17, 0x00 ; direction control byte, 0 = up
rcall TABLEDATA
rjmp DONE ; all done, leave
;
; this subroutine counts up and down through the data table in the EEPROM
; data, reading all 100 data values, from bottom to top, then top to
bottom
; one at a time
;
NEXT:
ldi r30, 0x00 ; compare value
cp r17, r30 ; check direction bit for value
brne UP ; it's set for an up count
ldi r30, 0x00 ; compare value
dec r16 ; count the table pointer
down one
cp r16, r30 ; at the bottom yet?
ldi r17, 0xff ; set direction flag to count up
RJMP QUIT0 ; all done, depart
UP:
ldi r30, 0x63 ; compare value
inc r16 ; increment table pointer
cp r16, r30 ; 99 decimal, end of table
breq FIXIT0 ; deal with table overflow
rjmp QUIT0 ; all done, depart
FIXIT0:
ldi r17, 0x00 ; reset direction flag for
down count
QUIT0:
ret ; return from subrouttine
call
;
; read a value from the EEPROM table
;
TABLEDATA:
rcall NEXT ; go grab next tabel address
out EEARL, r16 ; move table value address
to EEPROM
; address register low byte
in r0, EEDR ; read data from EEPROM
data register
ret ; all done, go home
DONE:
rjmp DONE
.exit