Problem mit Schleifengenerator (PIC, ASM)

OP #3487347
Lesenswert?

1
;1998 cycles
2
  movlw  0x8F
3
  movwf  d1
4
  movlw  0x02
5
  movwf  d2
6
Delay_0
7
  decfsz  d1, f
8
  goto  $+2
9
  decfsz  d2, f
10
  goto  Delay_0
11

12
      ;2 cycles
13
  goto  $+1
Ich habe ein Problem mit dem Piclist Schleifengenerator.
Und zwar verstehe ich nicht, wie man aus den zwei Variablen die Cyclen 
errechnet!

Ich dachte, es würde so funktionieren: (4*d1-1)*(4*d2-1)
Aber mit der Formel komme ich auf ungefähr das Doppelte an Cyclen.
Wie muss man die Formel hier für eine verschachtelte Schleife ansetzen?
#3487484
Lesenswert?

So siehst aus:

decfsz  d1, f ist die innere Schleiche
decfsz  d2, f die Äußere.

Ein Durchlauf der Inneren dauert:
  decfsz  d1, f       1 Zyklus +
  goto  $+2           2 Zyklen +
  decfsz  d2, f
  goto  Delay_0       2 Zyklen = 5 Zyklen
Sobald die Innere abgelaufen ist, wird d2 dekrementiert, wenn d2 0 ist, 
ist das delay fertig.
Die innere Schleife wird also zwei Mal ausgeführt und dauert beim ersten 
Mal 143*5 Zyklen, bei 256*5 Zyklen.
Also gesamt:
143*5+255*5
+ 1 Zyklus zusätzlich für den Sprung beim "decfsz d2, f"
+ 2 Zyklen für "goto $+1"
+die 4 Zyklen für das initialisieren von d1, d2
= 1997

Da fehlt mir jetzt ein Taktzyklus. Vllt. habe ich etwas vergessen 
miteinzurechnen.
OP #3487497
Lesenswert?

Max H. schrieb:
>[...] bei 256*5 Zyklen.[...]

Das versteh ich allerdings nicht ganz, wieso 256*5 Zyklen? wir haben 
doch nur ein mal bei d1 143, das dann zwei mal wegen der 2 in d2...
Das Ergebnis stimmt, aber ich verstehe nicht ganz wo die 256*5 Zyklen, 
bzw.
nachher die 255 in der Formel 5*143+5*255 her kommt?

> Da fehlt mir jetzt ein Taktzyklus. Vllt. habe ich etwas vergessen
> miteinzurechnen.

Ich kann mir vorstellen, dass die Wertevergabe irgendwie noch einen 
Zyklus aus macht... Vielleicht lieg ich da aber auch völlig auf dem 
Holzweg!
#3487520
Lesenswert?

Finn Jensen schrieb:
> Das versteh ich allerdings nicht ganz, wieso 256*5 Zyklen? wir haben
> doch nur ein mal bei d1 143, das dann zwei mal wegen der 2 in d2...
> Das Ergebnis stimmt, aber ich verstehe nicht ganz wo die 256*5 Zyklen,
> bzw.
> nachher die 255 in der Formel 5*143+5*255 her kommt?
Ich muss mich entschuldigen, es sind 256. Dann kommen wir auf 
5*143+5*256+4+2=2001 Zyklen. Laut MPLAB SIM sind es 2000 Zyklen. Also 
haben wir jetzt einen Zyklus zu viel berechnet. Der kommt daher, dass 
das ich letzte "goto  Delay_0", das übersprungen wird, mitgerechnet 
habe.

Beim ersten Mal sind es 143 Durchläufe, da du das d0 Register mit 143 
vorlädst, beim zweiten Mal sind es 256 Durchläufe, da das d0 dann mit 
null startet, weil es beim ersten Mal bis null hinuntergezählt wird und 
nicht wieder neu auf 143 gesetzt wird.

Wenn du genau die 1998 Zyklen brauchst musst du das "goto $+1" an Ende 
löschen.

Finn Jensen schrieb:
> Ich kann mir vorstellen, dass die Wertevergabe irgendwie noch einen
> Zyklus aus macht...
Ich nir nicht. movlw und movwf sind einfach Single-Cycle-Befehle.
OP #3488344
Lesenswert?

Jetzt habe ich eine frage zu 2 Fach verschachtelten schleifen, die 
einfach verschachtelten kann ich jetzt ohne Probleme berechnen, aber die 
zweifachen nicht. Meine Überlegung war jetzt diese:

7*3+(7*24)*255+(7*255)*255, womit ich auch auf 498036 komme, aber laut 
piclist kommt man mit dieser schleife auf 499994. Knapp 1000 Zyklen 
mehr!
Wie genau muss ich rechnen?
1
  movlw  0x03
2
  movwf  d1
3
  movlw  0x18
4
  movwf  d2
5
  movlw  0x02
6
  movwf  d3
7
Delay_0
8
  decfsz  d1, f
9
  goto  $+2
10
  decfsz  d2, f
11
  goto  $+2
12
  decfsz  d3, f
13
  goto  Delay_0
14

15
      ;6 cycles
16
  goto  $+1
17
  goto  $+1
18
  goto  $+1
Und bei dieser Schleife, die eigentlich 999997 Zyklen haben soll, komme 
ich mit meiner Formel auf gerade ein mal 539126.
Die wäre hier dann 7*8+(7*47)*255+(7*255)*255
OP #3488351
Lesenswert?

Finn Jensen schrieb:
> Jetzt habe ich eine frage zu 2 Fach verschachtelten schleifen, die
> einfach verschachtelten kann ich jetzt ohne Probleme berechnen, aber die
> zweifachen nicht. Meine Überlegung war jetzt diese:
>
> 7*3+(7*24)*255+(7*255)*255, womit ich auch auf 498036 komme, aber laut
> piclist kommt man mit dieser schleife auf 499994. Knapp 1000 Zyklen
> mehr!
> Wie genau muss ich rechnen?
>
>   movlw  0x03
>   movwf  d1
>   movlw  0x18
>   movwf  d2
>   movlw  0x02
>   movwf  d3
> Delay_0
>   decfsz  d1, f
>   goto  $+2
>   decfsz  d2, f
>   goto  $+2
>   decfsz  d3, f
>   goto  Delay_0
>
>       ;6 cycles
>   goto  $+1
>   goto  $+1
>   goto  $+1
>
> Und bei dieser Schleife, die eigentlich 999997 Zyklen haben soll, komme
> ich mit meiner Formel auf gerade ein mal 539126.
> Die wäre hier dann 7*8+(7*47)*255+(7*255)*255

leider darf ich meine Posts nicht bearbeiten...
Bei dieser schleife:
1
movlw  0x08
2
  movwf  d1
3
  movlw  0x2F
4
  movwf  d2
5
  movlw  0x03
6
  movwf  d3
7
Delay_0
8
  decfsz  d1, f
9
  goto  $+2
10
  decfsz  d2, f
11
  goto  $+2
12
  decfsz  d3, f
13
  goto  Delay_0
OP #3488510
Lesenswert?

Stampede schrieb:
> Hi,
>
> meine PIC Assembler Tage sind etwas her, aber muss es nicht
>
>
1
> Delay_0
2
>   decfsz  d1, f
3
>   goto  $-2   <----- MINUS ?
4
>
> heißen? Der Controller soll ja wieder zum decfsz zurückspringen und
> nicht vorwärts...

Man kann auch $+2, damit springt er dann 2 Zeilen weiter auf das nächste 
goto $+2, damit springt er dann 2 Zeilen weiter auf goto Delay_0 und 
fängt dann von vorne an.
OP #3488822
Lesenswert?

Max H. schrieb:
> Hast du schon versucht so eine Schleife komplett selbst zu schreiben?
> Dann wirst du auch verstehen wie du sie richtig berechnest.

Hm, also wenn ich ehrlich bin, ich würde die Schleife auch so schreiben
oder vielleicht einfach immer nach jedem decrement Befehl wieder den 
Sprungbefehl an den Anfang. Letztendlich würde ich aber noch immer nicht 
wissen, wie ich mit 3 decrement Befehlen rechnen muss...

Also statt dem Aufbau
1
movlw  0x08
2
  movwf  d1
3
  movlw  0x2F
4
  movwf  d2
5
  movlw  0x03
6
  movwf  d3
7
Delay_0
8
  decfsz  d1, f
9
  goto  $+2
10
  decfsz  d2, f
11
  goto  $+2
12
  decfsz  d3, f
13
  goto  Delay_0
So:
1
movlw  0x08
2
  movwf  d1
3
  movlw  0x2F
4
  movwf  d2
5
  movlw  0x03
6
  movwf  d3
7
Delay_0
8
  decfsz  d1, f
9
  goto  Delay_0
10
  decfsz  d2, f
11
  goto  Delay_0
12
  decfsz  d3, f
13
  goto  Delay_0
#3488845
Lesenswert?

Finn Jensen schrieb:

> Hm, also wenn ich ehrlich bin, ich würde die Schleife auch so schreiben
> oder vielleicht einfach immer nach jedem decrement Befehl wieder den
> Sprungbefehl an den Anfang. Letztendlich würde ich aber noch immer nicht
> wissen, wie ich mit 3 decrement Befehlen rechnen muss...

Was auch oft hilft.
Sich dumm stellen, selber µc spielen und (mit kleinen Zahlen!) einfach 
selber den Code durchsimulieren, wobei man ganz einfach die Takte 
zusammenzählt, die man gerade simuliert.

Aus der Beobachtung dessen, welche Befehle in welcher Reihenfolge 
abgearbeitet werden, ergibt sich 'die Formel' recht zwangsläufig, wenn 
man sich nach erfolgter Simulation zurücklehnt und sich überlegt, wie 
die Dinge da jetzt gelaufen sind.


Zum Thema kleine Zahlen:
Damit man sich nicht dumm und dusselig simuliert, kann man ja mal 
annehmen, dass man es mit einem 3 Bit Rechner zu tun hat. D.h. der kann 
nicht von 0 bis 255 in einem Byte operieren, sondern nur von 0 bis 7 
(bzw. umgekehrt, wenn ein decrement auf 0 angewendet wird, dann ist der 
nächst kleinere Wert dann eben nicht 255 sondern 7). Letzten Endes ist 
die Bitbreite ja nur ein Zahlenwert in der Formel, ändert aber an der 
Struktur der Formel nichts.
#3488855
Lesenswert?

> wie ich mit 3 decrement Befehlen rechnen muss...

Im Prinzip nach

Die Herstellung einer Flasche Bier dauert 10 Sekunden.
Die Flaschen für eine Kiste Bier herzustellen dauert daher wie lange?
Wenn auf einer Palette 12 Kisten Bier gestapelt werden, wie lange dauert 
dann die Herstellung der Flaschen für eine Palette?
Auf einen LKW können 48 Paletten mit Bierkisten geladen werden. Wie 
lange dauert es, die dafür notwendigen Flaschen herzustellen?
Auf dem Autozug durchs Inntal, von Kufstein auf den Brenner, passen 132 
LKW mit Paletten voller Bierkisten. Wie lange dauert es, die dabei 
beförderten Flaschen herzustellen?


Aber letzten Endes hängt es davon ab, wie genau die einzelnen Schleifen 
ineinander geschachtelt werden. Wenn man das im Code nicht sieht, dann 
muss man das eben durch simulieren rauskriegen.
OP #3490195
Lesenswert?

Leider komme ich immer noch nicht weiter...
Ich frage mich selbst schon wieso.
Gerechnet habe ich so:
d1 = 8, d2 = 47, d3 = 3
Wenn d1 das erste mal durchläuft, haben wir 7*8 = 56.
Beim zweiten mal ist d1 = 255
und wird mit 7*d2*d1 berechnet, das sind dann 83895.
Beim dritten mal (da liegt jetzt mein Problem!) müsste d1 = 255, d2 = 
255 und d3 = 3 sein.
Und dieses mal müsste man 7*d2*d1*d3 sein, dann kommt man aber schon auf 
1365525. Und dann muss man die ja auch noch addieren, womit man auf 
1449476.

Aber das macht ja keinen Sinn. Laut Piclist kommt man mit den Variablen 
auf ~1000000
#3490276
Lesenswert?

Finn Jensen schrieb:

> Wenn d1 das erste mal durchläuft, haben wir 7*8 = 56.
> Beim zweiten mal ist d1 = 255
> und wird mit 7*d2*d1 berechnet, das sind dann 83895.

wieso 7?
Wieso d2?

Du hast das vorgegebene d2 ja aufgeteilt. In den ersten Durchlauf und in 
die restlichen Durchläufe. D.h. die Anzahl der restlichen Durchläufe ist 
ja d2-1, weil ja der erste Durchlauf anders zu bewerten ist.


Simulier es dir mit kleinen Zahlen durch! Dir ist scheinbar noch nicht 
wirklich klar, wie da die Abläufe sind.
OP #3490419
Lesenswert?

Karl Heinz schrieb:
> Finn Jensen schrieb:
>
>> Wenn d1 das erste mal durchläuft, haben wir 7*8 = 56.
>> Beim zweiten mal ist d1 = 255
>> und wird mit 7*d2*d1 berechnet, das sind dann 83895.
>
> wieso 7?
> Wieso d2?
>
> Du hast das vorgegebene d2 ja aufgeteilt. In den ersten Durchlauf und in
> die restlichen Durchläufe. D.h. die Anzahl der restlichen Durchläufe ist
> ja d2-1, weil ja der erste Durchlauf anders zu bewerten ist.
>
>
> Simulier es dir mit kleinen Zahlen durch! Dir ist scheinbar noch nicht
> wirklich klar, wie da die Abläufe sind.

Ich habe das ganze so verstanden:

  movlw  0x08
  movwf  d1
  movlw  0x2F
  movwf  d2
  movlw  0x03
  movwf  d3
Delay_0
  decfsz  d1, f ;Erster Durchlauf: 7 * 8(d1)
  goto  $+2     ;(7 wegen 1x decfsz, dann 3x goto = 7
  decfsz  d2, f ;Zweiter Durchlauf: 7 * 255(d1) * 2F(d2)
  goto  $+2     ;(7 wegen 1x decfsz, dann 3x goto = 7
  decfsz  d3, f ;Dritter Durchlauf: 7 * 255(d1) * 255(d2) * 3(d3)
  goto  Delay_0

Also, ja, mir sind die Abläufe noch nicht ganz klar, ich weiß nicht, wie 
oft decfsz für d1 und für d2 durchgeführt wird. d3 wird ja genau 3 mal 
durchgeführt.
#3490454
Lesenswert?

Jetzt eine einfacher zu verstehende Art von Schleife. Du musst doch 
nicht genau diese verwenden?

Ich hache meine Schleifen immer so:
1
Delay:
2
movlw 0x09         ;
3
movwf d3           ;
4
del_2:          ;
5
movlw 0x08      ;
6
movwf d2        ;
7
del_1:       ; Innerste Schleife
8
movlw 0x07   ; Dauert immer 2+3*0x07 Zyklen
9
movwf d1     ;
10
decfsz d1,f  ;
11
goto $-1     ;
12
decfsz d2,f     ; 2. Innerste Schleife.
13
goto del_1      ; Dauert immer 2+0x08*(3+Innerste)
14
decfsz d3,f        ; Außere Schleife
15
goto del_2         ; Dauert immer 2+0x09*(3+2.Innerste)
Abgesehen von 2 Labels mehr ist der Code gleich lang.

Welchen PIC verwendest du?
Bei PIC18 muss man bedenken, dass das Überspringen eines GOTOs 3 Zyklen 
dauert.

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