Forum: Mikrocontroller und Digitale Elektronik Taktanzahl einer for-Schleife


von Frank O. (Gast)


Lesenswert?

Guten Morgen,

ich habe folgenden Code:

while ((PIN_SHT & (1<<PIN_DATA)) && (i < 320000))
    i++;

  if (i >= 320000)
    *error_code = 3;

mit 2Mhz; 320000 = 320ms

So die while schleife kontrolliert, ob der Pin_data high wird oder die 
Zählvariable 320000 erreicht hat und bricht dann die Schleife ab.

jetzt zu meiner frage bei 2MHz habe ich eine Periodendauer von 500ns.

Ich bin ich davon ausgegangen, dass die Prüfung der Bedingung einen Takt 
benötigt und die Inkrementierung einen weiteren Takt. Wodurch ich 2 
Takte habe oder 1µs.

Stimmt das oder brauch die Schleife zur Prüfung der Bedingung mehr als 1 
Takt?

Vielen Dank für eure Hilfe!

von Peter II (Gast)


Lesenswert?

Frank O. schrieb:
> Ich bin ich davon ausgegangen, dass die Prüfung der Bedingung einen Takt
> benötigt

nie. Es sind schon mal 2 Bedingungen die geprüft werden müssen

PIN_SHT & (1<<PIN_DATA)

und

i < 320000

also wenn überhaupt schon mal 2 Takte. Da wir nicht wissen ob um welche 
CPU es sich handelt gehe ich einfach mal von einer 8bit CPU aus. Damit 
braucht man hier schon mal wieder 2 Takte weil das ganze mindestens 
16bit ist.

Aber sinnvoller ist es einfach mal in das erzeugte assembler file zu 
schauen und selber zu rechnen.

von spess53 (Gast)


Lesenswert?

Hi

>Stimmt das oder brauch die Schleife zur Prüfung der Bedingung mehr als 1
>Takt?

Sieh dir einfach den erzeugten Assemblercode an. Aber es sind auf jeden 
Fall einige Takte mehr als 1.

MfG Spess

von Alexander F. (alexf91)


Lesenswert?

Ich gehe mal von einem 8 Bit Prozessor aus:
1 Takt für die Überprüfung der Schleifenbedingung ist kaum realistisch, 
da ja 2 voneinander unabhängige Bedingungen geprüft werden. Zusätzlich 
führst du mit i<320000 einen vergleich mit einer 32-bit Variable durch.
i++ inkrementiert eine 32-bit Variable, also geht das auch nicht in 
einem Takt.

von nobi (Gast)


Lesenswert?

Hallo,

Die Pruefung brauhct natürlich mehr als einen Takt, Du hast ja auch 2 
bedingungen verknüpft Pin einlesen, bit schiften, verunden, zählvariable 
prüfen... und damm noch ein und verknüpfung der beiden Ergebnisse

am besten du schasut Dir mal den Assembler Code an, den der Compiler 
daraus macht.

Die anzahl der Takte sind vermutlich auch noch von der Eingestellten 
Optimierungsstufe den Compilers (-O0 oder -O2) abhängig.

ps. Die schleife bricht ab, wenn der Pin_data low wird

von Peter (Gast)


Lesenswert?

Und dann gibt es noch uCs die schon 4..16 Takte für die Ausführung einer 
einzelnen ASM-Instruktion benötigen...

von Frank O. (Gast)


Lesenswert?

nobi schrieb:
> ps. Die schleife bricht ab, wenn der Pin_data low wird

Jop mein Fehler in der Erklärung

Es handelt sich um einen ATmega32 ich gucke mir mal den assemblercode an 
und poste ihn später mal

Vielen Dank schonmal

von Frank O. (Gast)


Lesenswert?

Kann mir einer helfen herauszufinden, wieviele Takte das sind ich kenn 
mich mit assembler absolut nicht aus!

  while ((PIN_SHT & (1<<PIN_DATA)) && (i < 320000))
     bfa:  86 9b         sbis  0x10, 6  ; 16
     bfc:  09 c0         rjmp  .+18       ; 0xc10 
<SHT75Temperature+0x50>
     bfe:  80 30         cpi  r24, 0x00  ; 0
     c00:  22 ee         ldi  r18, 0xE2  ; 226
     c02:  92 07         cpc  r25, r18
     c04:  24 e0         ldi  r18, 0x04  ; 4
     c06:  a2 07         cpc  r26, r18
     c08:  20 e0         ldi  r18, 0x00  ; 0
     c0a:  b2 07         cpc  r27, r18
     c0c:  99 f7         brne  .-26       ; 0xbf4 
<SHT75Temperature+0x34>
     c0e:  08 c0         rjmp  .+16       ; 0xc20 
<SHT75Temperature+0x60>
    i++;

Was wird denn jetzt alles gezählt?

Vielen Dank

von (prx) A. K. (prx)


Lesenswert?

Da fehlt was: Der Sprung zurück geht nach 0xbf4, dein Auszug fängt aber 
erst bei 0xbfa an.

von Axel S. (a-za-z0-9)


Lesenswert?

Frank O. schrieb:

> mit 2Mhz; 320000 = 320ms
> So die while schleife kontrolliert, ob der Pin_data high wird oder die
> Zählvariable 320000 erreicht hat und bricht dann die Schleife ab.

Mal ganz abgesehen von deiner Milchmädchenrechnung mit den Taktzyklen in 
der Schleife ist das ein ganz schlechtes Design, weil es nicht 
portabel ist. Schon eine simple Änderung der Compilerflags (z.B. 
Debug-Build vs. Release) wird voraussichtlich die Wartezeit verändern. 
Dito eine Änderung der Taktfrequenz.

Wenn du überhaupt busy-waiting verwenden willst, dann geh wenigstens 
über   _delay_us() aus <util/delay.h>. Angesichts der mit 320ms eher 
langen Wartezeit würde ich aber eher einen Timer empfehlen.


XL

von Frank O. (Gast)


Angehängte Dateien:

Lesenswert?

Axel Schwenke schrieb:
> Wenn du überhaupt busy-waiting verwenden willst, dann geh wenigstens
>
> über   _delay_us() aus <util/delay.h>. Angesichts der mit 320ms eher
>
> langen Wartezeit würde ich aber eher einen Timer empfehlen.

Ja vielen Dank!

Ich hätte auch noch einen Timer frei nur das müsste ich wieder über 
Interrupts laufen lassen und ich hab da schon einige verwendet und 
wollte nicht noch weitere verwenden, wodurch sich die chance, dass sich 
2 überschneiden und dadurch versetzt ausgeführt werden erhöht!

Aber ich hab es mal im hinterkopf und werde es einfach mal später 
ausprobieren.

Im Anhang habe ich mal die komplette Funktion hochgeladen!
Ich glaube muss mich mal was mit assembler beschäftigen, dass ist alles 
nicht verstänlich für mich!

von Karl H. (kbuchegg)


Lesenswert?

Dann machs wenigstens so
1
  i = 0;
2
  while ((PIN_SHT & (1<<PIN_DATA)) && (i++ < 320))
3
    _delay_ms( 1 );
4
5
  if (i >= 320)
6
    *error_code = 3;

dann stimmt die Zeit wenigstens so einigermassen, weil der Rest der 
SChleife im Vergleich zum _delay_ms unter "ferner liefen" fungiert.

von Frank O. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dann machs wenigstens so
>
>   i = 0;
>
>   while ((PIN_SHT & (1<<PIN_DATA)) && (i++ < 320))
>
>     _delay_ms( 1 );
>
>
>
>   if (i >= 320)
>
>     *error_code = 3;
>
> dann stimmt die Zeit wenigstens so einigermassen.

Ja habe ich mir auch überlegt genau muss es ja eh nicht sein! ob jetzt 
310 oder 330ms spiel keine Rolle

von Hannes L. (hannes)


Lesenswert?

Frank O. schrieb:
> Was wird denn jetzt alles gezählt?

Im Datenblatt Deines AVRs gibt es eine Tabelle "Instruction Set 
Summary", in der ist zu jedem ASM-Befehl unter anderem auch die 
Abarbeitungszeit (in Taktzyklen) aufgelistet.

Falls damit immernoch Unklarheiten bestehen, hilft die Hilfe des 
AVR-Studios (Cursor auf ASM-Befehl stellen und F1-Taste drücken) oder 
das PDF mit der ausführlichen Beschreibung des Instruction-Set.

Der Rest ist dann einfaches Addieren...

...

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.