-         

Ergebnis 1 bis 4 von 4

Thema: Frage zu Assembler-Anweisungen

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987

    Frage zu Assembler-Anweisungen

    Anzeige

    Naabend.

    In nem C-Programm verwend ich für kleine Wartezeiten eine Kombination aus Assembler-Befehlen. Diese Anweisung hab ich selbst auch nur per Copy&Paste übernommen. Da ich von Assembler selbst nicht wirklich viel Ahnung hab, wollt ich mal fragen, was genau dort eigentlich gemacht wird.

    Code:
    static inline void _delay4Cycles(ui16_t __count)
    {
      if (__count == 0)
      {
        __asm__ __volatile__("rjmp 1f\n 1:");
      }
      else
      {
        __asm__ __volatile__ (
          "1: sbiw %0,1" "\n\t"
          "brne 1b"
          : "=w" (__count)
          : "0" (__count)
          );
      }
    }
    Der "positive" If-Zweig geht ja noch; einfach nur ein Sprung eine Zeile weiter... Also als Basic-Pendant:
    Code:
    GOTO 1
    1:
    D.h. die Wartezeit wäre hier 1 Cycle.

    Nur der "negative" If-Zweig stellt mich dann vor ein Problem.
    Was macht dort jede Zeile im einzelnen?

    mfG
    #ifndef MfG
    #define MfG

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hi,

    Im "if" Zweig wird getestet, ob "__count==0" und gegebenenfalls auf den nächsten Befehl gesprungen. Dieser Zweig wird übrigens unter der Dezember 2007 Version von WINAVR wegoptimiert (wenn nicht "-O0")!

    Im "else"-Zweig wird von "__count" wird so oft "1" subtrahiert (sbiw="subtract immediate from word"), bis "__count" Null ist (d.h. die "branch not equal" {Sprung rückwärts zum Label "1"} Anweisung wird ausgeführt, wenn das Ergebnis der Subtraktion ungleich Null ist). Ist Null erreicht, geht der Programmzähler einfach auf die nächste Zeile, die dem Inline Code folgt.

    In C (ohne Optimierung, sonst würde diese Zeile wahrscheinlich einfach verschwinden!):
    Code:
    while (--__count);
    Je nach F_CPU und nötiger Wartezeit würde ich Dir eher zu "_delay_us(..)" aus "util/delay.h" raten (in der Klammer sollte ein Konstante stehen und Du musst die Optimierung eingeschaltet haben).

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Thx. Also _delay_ms war mir bekannt; dass es das gleiche mit µs auch noch gibt, nicht. Werds dann demnächst mal überall austauschen.
    #ifndef MfG
    #define MfG

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hier die Dokumentation zu den Funktionen _delay_us(..) und _delay_ms(..): http://www.nongnu.org/avr-libc/user-...il__delay.html
    Only entropy comes easy. - Anton Checkhov

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •