Forum: Compiler & IDEs Delay: Verständnissproblem


von jochen (Gast)


Lesenswert?

Hallo Zusammen,

mein mega8 läuft mit einem 4MHz Quarz. Nach einigen Vorüberlegungen
müsste folgender Code ein Delay von 15ms erzeugen
     for(i=0; i<=12000; i++) {};
genaugenommen sind es 15000,5 us

Mein Compiler generiert mir nun jedoch folgenden ASM Code

  74:  8f ed         ldi  r24, 0xDF  ; 223
  76:  9e e2         ldi  r25, 0x2E  ; 46
  78:  04 97         sbiw  r24, 0x04  ; 4
                                        ^-- WARUM ?
  7a:  97 ff         sbrs  r25, 7
  7c:  fd cf         rjmp  .-6        ; 0x78
  7e:  08 95         ret

Was ich nun nicht verstehe ist warum an der markierten Stelle eine 4
und keine 1 steht. (BTW. füge ich noch ein NOP im C-Code ein wird der
Wert mit 1 richtig generiert)
Was mache ich bzw. der compiler hier falsch?

Danke schon mal, der Jochen

von Alex (Gast)


Lesenswert?

kannst du etwas mehr vom c-code posten?

von Alex (Gast)


Lesenswert?

static void delay(uint16_t us)
{        /*Verzögerung in Microsekunden*/
    while ( us ) us--;
}

main(){
...
while(15000)}       /*bin mir nicht sicher ob es 14999 sein müssen*/


du brauchst dann noch
#include <inttypes.h>

#include <avr/inttypes.h> funktioniert bei mir nicht, hat dafür jemand
ne erklärung?

von jochen (Gast)


Lesenswert?

Hallo Alex,

die Funktion kenne ich. Das Problem ist aber immer noch was der
C-Compiler daraus macht. Siehe hierzu folgendes:

void delay(void)
{        /*Verzögerung in Microsekunden*/
    int us;
    us = 800;
  80:  80 e2         ldi  r24, 0x20  ; 32
  82:  93 e0         ldi  r25, 0x03  ; 3
    while ( us ) us--;
  84:  49 97         sbiw  r24, 0x19  ; 25
--> Hier kommt der Teil den ich nicht verstehe !!!!!
  86:  f1 f7         brne  .-4        ; 0x84
}
  88:  08 95         ret

sbiw ist laut Datenblat: Subtract imidiate from word. So wie ich das
sehe wird hier pro Schleifendurchlauf 19h also 25d abgezogen. D.h. die
Schleife dauert nur 1/25 der Zeit die ich eigentlich erwarte.

Nun ist die Frage warum ist das so bzw. wo ist mein
Verständnissproblem.

Der Jochen

von Alex (Gast)


Lesenswert?

Mit compiler kenne ich mich nicht aus, ich versuche daher alles in c zu
programmieren.

Wie übersetzt du den C-Code in Assembler??? Würde mich interessieren.

Habe deine Frage falsch verstanden, ich dachte dein Prog macht nicht
was du willst.

von jochen (Gast)


Lesenswert?

Hallo Alex,

wenn Du den C-Code mit gcc übersetzt gibt es unter anderem ein .lst
File. In diesem File kannst Du den ASM-Code den der C-Compiler erzeugt
sehen.
Ich will halt einfach sicher gehen das die delays die ich programmiere
auch eingehalten werden. Deshalb hab ich mir den ASM Code mal
angesehen.

Der Jochen

von Peter D. (peda)


Lesenswert?

Solche extrem langen Delays von 15ms würde ich immer mit einem Timer
machen, entweder mit einem Interrupt oder Polling.

Das ist genauer und vor allem vom Compiler unabhängig.


Peter

von Berndt Brandes (Gast)


Lesenswert?

Der Compiler darf mit leeren Schleifen machen, was er will (komplett
wegnehmen, verändern, ...). Es Ändert sich ja nix (OK, die Laufzeit,
aber das ist dem Compiler Wurscht). Hängt man ein NOP rein, ist alles
OK.

/Berndt

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.