Forum: Compiler & IDEs Verständnisproblem delay.h !!HILFE!!


von Asterix-007 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Männers,

ich brauche mal eure Hilfe, bevor ich hier noch eine Koffeinvergiftung
und/oder graue Haare bekomme.
Zum Problem: Ich will mit der oben geposteten delay.h eine Verzögerung
von ca 200 bis 600 µs bewerkstelligen.
Als Hardware benutze ich einen ATmega 128 mit 16 MHz Taktfrequenz.

Die Funktion " _delay_us(double __us)" ist klar, hier wird der
übergebene Wert auf die Funktion " _delay_loop_1" angepaßt.
Laut Aussage des Kommentars kann ich mit _delay_us eine max Verzögerung
von 768µs / 16MHz = 48 µs erreichen.

Ergo, muß ich in der Funktion "_delay_loop_1" etwas "drehen".
Und damit sind wir bei meinem Problem:

static _inline_ void
_delay_loop_1(uint8_t __count)
{
  _asm_ volatile (
    "1: dec %0" "\n\t"
    "brne 1b"
    : "=r" (__count)
    : "0" (__count)
  );
}

Es wäre schön, wenn mir jemand von Euch diese 6 Zeilen mal erklären
könnte, und vielleicht auch die andere Funktion (_delay_loop_2).
Ich weiß, das hier mit dem 8Bit-Counter bzw. 16Bit-Counter etwas
decrementiert wird, kann das aber beim besten Willen nicht
nachvollziehen!! C ist das scheinbar nicht und Assembler auch nicht,
oder nur zum Teil.... Vielleicht ist das so was wie ne Makro-Anweisung
oder ähnlich, naja ich hoffe auf Euch!!!
Wenn ich das kapiert habe, kann ich mich entscheiden, ob ich mir was
neues einfallen lasse, oder hier weiter Zeit investiere.

Übrigens, die Datei "delay.h" stammt aus dem letzten WinAVR und
sollte bei jedem, der diesen nutzt mit dabei sein.

vielen Dank für Eure Mühe!

mfg

Asterix-007

von Irgwer (Gast)


Lesenswert?

Hallo Asterix,

warum nicht einfach:

_delay_ms(0.2) bzw. _delay_ms(0.6)

mfg Irgwer

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> C ist das scheinbar nicht und Assembler auch nicht, oder nur zum
> Teil.... Vielleicht ist das so was wie ne Makro-Anweisung oder
> ähnlich, naja ich hoffe auf Euch!

Es ist der sogenannte inline-Assembler.  Doku findest du in der
avr-libc-Doku.

Kurz:

Das Register __count wird decrementiert, bis es 0 ist.  Über die
sogenannte constraint "r" wird der Compiler angewiesen, für __count
auch tatsächlich ein Register bereitzustellen (und nicht etwa eine
Speicherzelle im RAM).  Das ist notwendig, weil nur damit die
DEC-Anweisung funktioniert.

Da die DEC-Anweisung einen Taktzyklus braucht und der anschließende
Rücksprung BRNE zwei Zyklen (solange er springt), hat man drei
Taktzyklen pro __count-Wert.

Ansonsten: volle Zustimmung, benutze _delay_ms(0.2).  Bitte schalte
die Optimierung ein, damit die Gleitkomma-Rechnerei vom Compiler
erledigt wird.  Falls du Probleme hast, bei mehr als einem Aufruf von
_delay_ms() doch noch Gleitkommarechnungen mit reingezogen zu
bekommen, aktualisiere bitte deine Bibliothek auf avr-libc-1.2.6.

von Asterix-007 (Gast)


Lesenswert?

@ Jörg:

Danke für die Hilfe! Das Prinzip hatte ich mir schon so gedacht, aber
ich konnte den Quellcode nicht zuordnen bzw. deuten!

Die neue Lib habe ich mir schon geladen, und die Hilfe habe ich auch
schon aktiviert! Aaaaber, wie bekomme ich die Library
"eingebastelt"????
Ich habe schon versucht sie irgendwo einzufügen, aber dat war wohl
nix...;-))

Gibst du mir noch einen Tip??

Danke!

Asterix-007

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.