Forum: Mikrocontroller und Digitale Elektronik Assembler Delays - AVR-Tutorial


von Daniel L. (daniellaube)


Lesenswert?

Hallo!

Ich habe eine Frage und verstehe etwas im AVR-Tutorial nicht.
Ich bin im Abschnitt 9.3 und will den Assembler rechnen lassen =)
Es geht um diesen Code:
1
 ; Längere Pause für manche Befehle
2
delay5ms:                               ; 5ms Pause
3
           ldi  temp1, $21
4
WGLOOP0:   ldi  temp2, $C9
5
WGLOOP1:   dec  temp2
6
           brne WGLOOP1
7
           dec  temp1
8
           brne WGLOOP0
9
           ret                          ; wieder zurück

Unten im Erklärtext steht dass in der inneren Schleife, 3 Takte pro 
durchlauf benötigt werden. Diese innere Schleife ist dann noch dieser 
Teil hier oder?:
1
WGLOOP1:   dec  temp2
2
           brne WGLOOP1

Weiter steht, dass in der äußeren Schleife 1 + 603 + 1 + 2 = 607 Takte 
verbraucht werden. Und hier verstehe ich es nichtmehr. Wie kommen 607 
Takte zusammen? Ich verstehe die ganze Architektur auch nicht ganz, sind 
das irgendwie verschachtelte schleifen oder läuft das so ab: temp2 immer 
weiter dekremieren bis er null ist und danach temp1 dekremiert bis er 0 
ist?

Hilfe wäre super =)

Gruß,
Daniel

von Dietrich L. (dietrichl)


Lesenswert?

Daniel Laube schrieb:
> Ich verstehe die ganze Architektur auch nicht ganz, sind
> das irgendwie verschachtelte schleifen oder läuft das so ab: temp2 immer
> weiter dekremieren bis er null ist und danach temp1 dekremiert bis er 0
> ist?

Zeichne Dir zuerst mal ein Flussdiagramm auf, dann sollte der Ablauf 
klar sein (hoffentlich). Dann kannst Du auch die Takte zählen/berechnen.

Gruß Dietrich

von Karl H. (kbuchegg)


Lesenswert?

Daniel Laube schrieb:

> verbraucht werden. Und hier verstehe ich es nichtmehr. Wie kommen 607
> Takte zusammen? Ich verstehe die ganze Architektur auch nicht ganz, sind
> das irgendwie verschachtelte schleifen oder läuft das so ab: temp2 immer
> weiter dekremieren bis er null ist und danach temp1 dekremiert bis er 0
> ist?

Am einfachsten ist es, wenn du im Simulator da einfach mal in 
Einzelschritten durchgehst. Dazu die Konstanten auf kleinere Werte 
runtersetzen, sonst stepst du dir einen Wolf.


Ja, die sind ineinander geschachtelt!

mal etwas mehr Leerraum und ein paar Pfeile reingesetzt


                     ldi  temp1, $21
  +-----> WGLOOP0:   ldi  temp2, $C9
  |
  | +->   WGLOOP1:   dec  temp2
  | +------          brne WGLOOP1
  |
  |                  dec  temp1
  +-------------     brne WGLOOP0

                     ret

temp2 wird also solange runtergezählt, bis es 0 geworden ist. Was 
passiert danach? Danach wird temp1 runtergezählt und wenn es noch nicht 
0 ist, dann gehts zurück an die Stelle, an der temp2 wieder mit $C9 
geladen wird und anschliessend wird temp2 wieder runtergezählt, bis es 0 
geworden ist. Wieder wird temp1 um 1 vermindert und wenn es nicht 0 ist, 
gehts zurück an die Stelle, an der temp2 mit C9 geladen wird und wieder 
wird temp2 solange runtergezählt bis es  0 geworden ist. usw. usw. 
Irgendwann ist dann auch temp1 zu 0 geworden und der Rücksprung 
unterbleibt.

Wie die 603 zustande kommen, sollte für dich allerdings nachvollziehbar 
sein. $C9 ist eine Hexzahl. In Dezimaler Schreibweise wäre das 201. Und 
ein Durchgang durch die temp2-Schleife dauert 3 Takte. Die SChleife wird 
201 mal wiederholt bei 3 Takten, das macht 603 Takte. Der letze 
Durchgang ist ein wenig anders, weil dann der Sprung zu WGLOOP1 nicht 
genommen wird und ehe die Schleiferei losging wurde an temp2 der Wert C9 
zugewiesen, was ja ebenfalls ein paar Takte dauert.

Aus Sicht der temp1 Schleife

           ldi  temp1, $21

WGLOOP0:
           mache irgendwas

           dec  temp1
           brne WGLOOP0


dauert dieses "mache irgendwas" 603 + unterbliebender-Branch + "Lade 
temp2" Takte. Dazu kommen dann noch die Anzahl der Takte um temp1 
runterzuzählen und den Sprung nach WGLOOP0 zu machen.

von Daniel L. (daniellaube)


Lesenswert?

Achso, nun versteche ich auch die folgende umformung, um variabel auf 
verschiedene Taktfrequenzen zu sein!

Vielen Dank!

Daniel

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.