Hallo allen,

Is het mogelijk om het RAM geheugen van een AVR (90S8535 in dit geval), direct aan te spreken, zodat je er variabelen in kwijt kunt ? Ik bedoel nu moet je de stack initialiseren (meestal tot het maximum ram geheugen), kun je dit ook bv instellen op 486bytes (i.p.v. 512 = alles), en dan die extra bytes die je over hebt gebruiken om data in weg te schrijven tijdelijk ? Dit omdat ik met een heleboel variabelen zit die niet allemaal in de 32 registers passen. Of is er nog een andere mogelijkheid omdat te doen ? (Ik heb geen plaats voor extern RAM)

Groeten
Antoine

Zeker dezelfde vraag als ik net heb behandelt in het andere topic.

Normaal gebruik je daar niet de stackpointer voor. Die gebruik je alleen bij subroutines en interrupts.


.dseg
program: .byte 1
hey: .byte 1
enz.

Nou je zegt met .dseg dat de komende code te maken heeft met zijn data gebied (dus ram).

Omdat ik niks specificeer verder begint het op de laagste plek van zijn ram. Als ik dan .byte 1 doe dan reserveerd die 1 byte in zijn SRAM geheugen en koppeld het aan een naam, zodat ik in mijn programma kan zeggen

lds r16, teller

indien er bijvoorbeeld stond
teller .byte 1

Dan laad die de waarde van mijn sramplek die teller heet in r16. Die waarde 1 achter byte geeft aan hoeveel byte die plek moet zijn waar de naam aan gekoppeld is.

Met STS kun je iets opslaan van je registers naar een SRAM plek. En met LDS iets ophalen uit een SRAM plek en schrijven naar een register.

[Bericht gewijzigd door Bastiaan op ]

Oeps, had al zo'n vermoeden, mijn fout :(

Ah oke, maar moet je dan ook je stackpointer anders initialiseren ? Ander overloopt dat elkaar toch ? Gezien die beiden in het zelfde ram zitten.

Dus als ik het goed begrijp dan heb jij daar twee namen gekoppeld (program en hey), aan elk een stukje van 1byte in het ram ?

In hoeverre kun je daarmee doorgaan ? De volle 512bytes ?Dat toch niet ?

Groeten
Antoine

Op 2 februari 2003 20:35:18 schreef Antoine:
Oeps, had al zo'n vermoeden, mijn fout :(

Ah oke, maar moet je dan ook je stackpointer anders initialiseren ? Ander overloopt dat elkaar toch ? Gezien die beiden in het zelfde ram zitten.

Je moet even kijken naar mijn asm filetje uit dat andere topic. Daar zie je dat ik de stack op zijn hoogste SRAM gebied zet voordat ze rest van het programma begint.
En ze kunnen elkaar idd overlopen. Er komt dan geen foutmelding of wat dan ook, maar de data komt dan niet meer overeen met wat het word verwacht te zijn. Dus altijd oppassen daarbij. Maar het RAM is best groot dus dat zal niet snel gebeuren.

Dus als ik het goed begrijp dan heb jij daar twee namen gekoppeld (program en hey), aan elk een stukje van 1byte in het ram ?

Klopt, als extra info:
program krijgt SRAM stukje 00 en hey SRAM stukje 01.
Zou je dus doen
LDI r16, 0x40
STS hey, r16
Dan zul je in AVRStudio zien dat die op SRAM plek 01 0x40 neerzet. Probeer maar ;)

In hoeverre kun je daarmee doorgaan ? De volle 512bytes ?Dat toch niet ?

Je SRAM is dacht ik niet de volle 512 byte. Het word gedeelt met je registers (intern, daar merk je niks van). Maar zo groot als je SRAM is kun je gewoon doorgaan.

Ah oke, bedankt !

Nog een vraagje, hoe weet ik dan waar mijn stackpointer zich bevindt ? Zodat er niet onverwacht toch data overschreven wordt ?

Groeten
Antoine

ja kan kiezen waar die komt, meest gebruikt is op het einde van de sram.


.def   temp = R16       ; gewoon een naam aan r16 geven..

ldi    temp, RAMEND	;point stack in RAM-einde
out    SPL, temp	; SPL = StackPointerLow

dit is bij een AT90S2313, bij een Mega8 moet je ook een high byte toewijzen dacht ik.

Op 2 februari 2003 20:58:08 schreef Antoine:
Nog een vraagje, hoe weet ik dan waar mijn stackpointer zich bevindt ? Zodat er niet onverwacht toch data overschreven wordt ?

Dat kan je beantwoorden als je weet wanneer je stack (pointer) verandert. Je stack verandert alleen als jij het via pop, pull aanroept. De stackpointer zelf wijzigt of als je naar een interrupt/subroutine springt.

Zolang jij dus zelf niks verander aan die sp dan zal er niet zo snel wat gebeuren want dat zou je een heleboel subroutines genest moeten hebben wil je in een kritiek gebied komen van jouw eigen SRAM gebiedje.

Bastiaan,

Bedankt, dat is heldere uitleg ! Gezien ik over het algemeen niks doe met pop en pull, is het dus zo dat de stackpointer (die verspringt bij subroutines), helemaal bovenin het ram staat, en ik dus onderaan zit met mijn stukjes toegewezen ram. M.a.w. stel dat ik dus 32 bytes gebruik van het RAM, dan kan ik dus nog 512 - 32 = 480 geneste lussen gebruiken ?

GRoeten
Antoine

Op 3 februari 2003 19:27:53 schreef Antoine:
Bastiaan,

Bedankt, dat is heldere uitleg ! Gezien ik over het algemeen niks doe met pop en pull, is het dus zo dat de stackpointer (die verspringt bij subroutines), helemaal bovenin het ram staat, en ik dus onderaan zit met mijn stukjes toegewezen ram. M.a.w. stel dat ik dus 32 bytes gebruik van het RAM, dan kan ik dus nog 512 - 32 = 480 geneste lussen gebruiken ?

GRoeten
Antoine

Ja, helemaal correct. Je gaat er alleen dan wel vanuit dat je per subroutine 1 byte kwijt bent, en soms is dat niet het geval want dan zijn het er 2 (hoge en lage deel van de program counter), dus dan is het de helft van die 480 maar dat blijven een heleboel 'geneste' routines :D.

ps. Je weet hoe het werkt met de stack als er naar een subroutine word gesprongen? Zoniet dan wil ik je dat nog wel uitleggen.

Heb ook nog een vraagje over het interne SRAM, maar lijkt me wat overdreven er een topic van te maken.

is er nog een kortere manier om een byte aan data in een sram locatie te schrijven dan


ldi r16,0x01h
sts r16,databyte

indien er daarvoor  
databyte: .byte 1 staat

Dus een soort LoaDImmediate functie maar dan niet in het register maar rechtstreeks in het sram.

Heb niet echt iets gevonden in de instructieset, dus ik denk dat dit de enige manier is.

Op 3 februari 2003 23:24:17 schreef Koen Van Vlaenderen:
is er nog een kortere manier om een byte aan data in een sram locatie te schrijven dan


ldi r16,0x01h
sts r16,databyte

indien er daarvoor  
databyte: .byte 1 staat

Dus een soort LoaDImmediate functie maar dan niet in het register maar rechtstreeks in het sram.

Heb niet echt iets gevonden in de instructieset, dus ik denk dat dit de enige manier is.

Dit is de snelste manier. Alles gaat via de registers.

Op 3 februari 2003 21:36:03 schreef Bastiaan:

[...]

Ja, helemaal correct. Je gaat er alleen dan wel vanuit dat je per subroutine 1 byte kwijt bent, en soms is dat niet het geval want dan zijn het er 2 (hoge en lage deel van de program counter), dus dan is het de helft van die 480 maar dat blijven een heleboel 'geneste' routines :D.

ps. Je weet hoe het werkt met de stack als er naar een subroutine word gesprongen? Zoniet dan wil ik je dat nog wel uitleggen.

Nou voorzover ik het weet gebeurd met de stack niet meer dan de programma locatie vanwaar er genest werd (wazige uitleg, ik weet het ;)). Maar voel je vrij om het uit te leggen !

Alvast bedankt
Antoine

Op 4 februari 2003 18:59:37 schreef Antoine:
[...]
Nou voorzover ik het weet gebeurd met de stack niet meer dan de programma locatie vanwaar er genest werd (wazige uitleg, ik weet het ;)). Maar voel je vrij om het uit te leggen !

Aan jouw "wazige uitleg" kan ik zien dat je het al weet, dus uitleg is overbodig :)

Toch nog iets gehad aan m'n MBO :)

.equ SRAM = 0x60

ldi YL, SRAM ;zet Y pointer op 0x60
ld r16, Y ;laad waar Y op staat in r16
adiw YL, 2 ;Y twee adressen omhoog zetten
st Y, r16 ;sla in r16 op waar Y op staat

Je kan ook direct werken, met een zogeheten pointer.
Of indirect:

std Y+23, r16 ;sla data in r16 op in op adres Y+23

Y blijft dan onaangetast, stel Y was 0x60 dan 23 adressen hoger data opslaan in r16. Je kan niet direct van SRAM in SRAM kopieren of schuiven. Dat kan wel zo:

std Y+0, r16
ldd r16, Y+2
std Y+1, r16
ldd r16, Y+3
std Y+2, r16

etc. gebruikmakend van een werkregister. Doorkopieren. Kan ook met een lus en verplaatsen de Y pointer met adiw of sbiw (zie boven), handig bij grote SRAM buffers.

nog een avr-liefhebber blijkbaar... Maar dit topic is 9 maanden oud, daar heeft niemand nog iets aan!