Speicherstelle im SRAM direkt decrementieren Attiny13

Gast #729312
Lesenswert?

Hallo!

Ich beschäftige mich gerade mit dem Ram Speicher.

Da mir die Register von 16 - 25 zu wenig sind habe ich mir gedacht 
nimmste
den Ram.

Nun! Da gab es gleich ein Problem. Denn Ich wollte bestimmte 
Ramspeicherzellen direkt benutzen. Geht auch aber bissel umständlich.

Bsp1.  Diese Routine benutzt die Register R17-R19

wait1:
     ldi z1,5
w1:
     ldi z2,100
w2:
     ldi z3,255
w3:
     dec z3
     brne w3
     dec z2
     brne w2
     dec z1
     brne w1
     ret

Bsp2. Diese Reoutine benutzt nun das Ram ab 0x60- 0x62
wait1:

     ldi    A,5           ;Startwerte ins Ram Schreiben
     sts    z1,A
w1:
     ldi    A,100
     sts    z2,A
w2:
     ldi    A,255
     sts    z3,A
w3:
      lds   A,z3          ;Schleifenzähler laden
      dec   A             ;Dekrementieren
      sts   z3,A          ;Wieder sichern
      brne  W3            ;Schleife verlassen wenn 0
      lds   A,z2
      dec   A
      sts   z2,A
      brne  w2
      lds   A,z1
      dec   A
      sts   z1,A
      brne  w1

     ret

Wie könte man diese Routine mit RAM benutzung kürzer schreiben.


Gruß
norad
#729326
Lesenswert?

@  norad (Gast)

>Ich beschäftige mich gerade mit dem Ram Speicher.

Wie schön.

>Da mir die Register von 16 - 25 zu wenig sind habe ich mir gedacht
>nimmste den Ram.

Sehr clever.

>Nun! Da gab es gleich ein Problem. Denn Ich wollte bestimmte
>Ramspeicherzellen direkt benutzen. Geht auch aber bissel umständlich.

Das macht man nicht. Der Assembler kann das besser verwalten.

AVR-Tutorial: SRAM

MfG
Falk
Gast #729358
Lesenswert?

@spess53

Leider funktioniert es mit deinem Vorschlag nicht.

Wenn ich es so vereinbare
.def   z1       = R0
.def   z2       = R1
.def   z3       = R2

Und so die Startwerte setze
ldi z1,5
ldi z2,100
ldi z3,100


kommt beim Compilieren diese Fehlermeldungen:

C:\Users\Klaus\Documents\Clean_Sensor\Funktionen.inc(30): error: Invalid 
register


Fazit: R0-R15 können nicht so einfach benutzt werden.
#729378
Lesenswert?

norad wrote:
> Bsp2. Diese Reoutine benutzt nun das Ram ab 0x60- 0x62
1
wait1:
2

3
     ldi    A,5           ;Startwerte ins Ram Schreiben
4
     sts    z1,A
5
w1:
6
     ldi    A,100
7
     sts    z2,A
8
w2:
9
     ldi    A,255
10
     sts    z3,A
11
w3:
12
      lds   A,z3          ;Schleifenzähler laden
13
      dec   A             ;Dekrementieren
14
      sts   z3,A          ;Wieder sichern
15
      brne  W3            ;Schleife verlassen wenn 0
16
      lds   A,z2
17
      dec   A
18
      sts   z2,A
19
      brne  w2
20
      lds   A,z1
21
      dec   A
22
      sts   z1,A
23
      brne  w1
24

25
     ret
Das ist schlecht. Das ist Code, der von einem schlecht optimierenden 
Compiler produziert wird. Eine Warteschleife ist eine denkbar schlechte 
Demonstration zur Verwendung des SRAMs, denn genau da brauchst du ganz 
bestimmt nicht "viel" Speicher. Wenn du die Wartezeit unbedingt per SRAM 
übergeben willst, dann lädst du die drei Register am Anfang der Funktion 
mit diesen Werten (lds), hockst die Wartezeit ab und beschreibst die 
Speicherzellen am Ende mit 0 (Was sich sinnvollerweise ohnehin immer in 
einem Register befindet).

Btw: Warten solltest du mit Timern, nicht mit Schleifen ;)
Gast #729442
Lesenswert?

> Da mir die Register von 16 - 25 zu wenig sind habe ich mir gedacht
> nimmste den Ram.

Die Register fangen bei 0 an und gehen bis 31.

>      lds   A,z3          ;Schleifenzähler laden
>      dec   A             ;Dekrementieren
>      sts   z3,A          ;Wieder sichern

Ich finde es ziemlich umständlich, den Schleifenzähler ständig im RAM zu 
halten. Der AVR hat so viele Register. Da sollte man sich nicht auf die 
Benutzung eines einzelnen beschränken und damit den Code unnötig durch 
überflüssige Lade- und Speicherinstruktioen aufbähen, zumal der Tiny13 
nur 1k Flash hat.

> Wie könte man diese Routine mit RAM benutzung kürzer schreiben.

Man könnte sie ohne RAM-Benutzung deutchlich kürzer schreiben.
Gast #729488
Lesenswert?

Hallo!

Vielen Dank für eure Tipps und vorschläge!

Ich habe es jetzt so gemacht wie es Falk vorgeschlagen hatte, benutzte 
die Register 0 - 3.

wait1:
     ldi A,5
     mov z1,A
w1:
     ldi A,100
     mov z2,A
w2:
     ldi A,255
     mov z3,A
w3:
     dec z3
     brne w3
     dec z2
     brne w2
     dec z1
     brne w1
     ret

@Philipp Burch

>Warten solltest du mit Timern, nicht mit Schleifen ;)

In diesem Fall ist Warten mit Schleife nicht Zeitkritisch, sonst benutze 
ich selbstverständlich Timer.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren