Forum: Mikrocontroller und Digitale Elektronik Speicherstelle im SRAM direkt decrementieren Attiny13


von norad (Gast)


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

von spess53 (Gast)


Lesenswert?

Hi

Warum benutzt du nicht die Register im Bereich r0..r15. 'DEC' 
funktioniert auch mit diesen Registern.

MfG Spess

von Falk B. (falk)


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

von norad (Gast)


Lesenswert?

@spess53

werd ich gleich mal auspropieren.

@Falk

Deinen Beitrag habe ich nicht verstanden. Ich habe selbstverständlich 
das Tutorial gelesen aber hilft mir in dem Fall nicht weiter.


Gruß

norad

von norad (Gast)


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.

von Falk B. (falk)


Lesenswert?

@ norad (Gast)

>Fazit: R0-R15 können nicht so einfach benutzt werden.

Irrtum. Einfach ein ldi r16,123 gefolgt von einem mov r0,r16. Schwups 
kannst du deine r0..r15 laden. ADD/SUB/DEC etc. laufen mit allen 
Registern.

MFG
Falk

von norad (Gast)


Lesenswert?

@Falk

Danke für deinen Tipp!

MFG

norad

von Philipp B. (philipp_burch)


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 ;)

von Falk B. (falk)


Lesenswert?

@ Philipp Burch (philipp_burch)

>Das ist schlecht. Das ist Code, der von einem schlecht optimierenden
>Compiler produziert wird.

Nöö, von einem Programmieranfänger ;-)

MFG
Falk

von Rolf Magnus (Gast)


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.

von Philipp B. (philipp_burch)


Lesenswert?

Falk Brunner wrote:
> @ Philipp Burch (philipp_burch)
>
>>Das ist schlecht. Das ist Code, der von einem schlecht optimierenden
>>Compiler produziert wird.
>
> Nöö, von einem Programmieranfänger ;-)

Anscheinend auch, ja ;)

von norad (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.