mikrocontroller.net

Forum: Compiler & IDEs Wegen Delay Funktion _delay_us(double __us)


Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich hab eine Frage zur o.g. Funktion von der delay.h:

Es heißt: "The maximal possible delay is 768 µs / F_CPU in MHz."

Bei mir @16Mhz kann ich also max. 48µs Delay machen.

Anwendungsspezifisch will ich aber auf bis ca. 20000µs also 20ms delay 
machen können und das mit der Genauigkeit von +/- ein paar µs.

Jetzt woll ich mich umhöreh ob es eine bessere Funktion gibt, weil die 
Funktion in der delay.h kann ich nicht erweitern.

Also höchstens die Funktion x mal dann für z.b. 4800µs dann 100x 
aufrufeun?

Geht das nicht irgendwie einfacher?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jetzt woll ich mich umhöreh ob es eine bessere Funktion gibt,...
Ja, nen Timer. Mit delay-Funktionen arbeitet man eigentlich 
grundsätzlich nur dann, wenn man kurze Verzögerungszeiten benötigt, für 
die es sich nicht lohnt, einen Timer anzuwerfen (vorausgesetzt, Du hast 
einen Timer für diese Aufgabe frei). Und wenns bei dem gewünschten 
Bereich auf einige µs genau sein soll, wirst Du um einen Timer eh nicht 
rumkommen, außer Du programmierst Dir in Assembler selber eine Routine, 
die in der Lage ist, die gewünschte Funktion zu erfüllen (CPU-Takte 
zählen). Bei Mehrfachaufrufen der delay-Funktionen müsstest Du genau 
kontrollieren, was der Compiler aus der Schleife, in der Du die Aufrufe 
machst, macht. Das führt sonst zu weiteren Ungenauigkeiten.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beachte auch, dass diese _delay_XX-Funktionen ausschließlich mit
zur Compilezeit bekannten festen Werten benutzt werden dürfen.
Alles andere verursacht mehr Laufzeit-Overhead, als du dir mit deinen
+/- paar Mikrosekunden aufhalsen möchtest.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan hat natürlich recht. _delay_ms bekommt ja einen double übergeben 
(oh, wie konnte ich das vergessen... wird Zeit, Feierabend zu machen). 
Da kannste natürlich z.B. mit _delay_ms(10.001) eine sehr gute 
Genauigkeit erreichen. Allerdings geht _delay_ms bei 16 MHz auch nur bis 
ungefähr 16 ms...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Upps zu schnell abgeschickt... Das was Jörg sagt, ist natürlich auch 
zu beachten. Wenn Deine Werte erst zur Laufzeit des Controller-Programms 
bekannt sind, wirst Du um einen Timer wohl tatsächlich nicht rumkommen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alternative, falls Timer aus irgendwelchen Gründen nicht geht, aber
nur ein paar feste Werte gebraucht werden: die Zyklenzähler in einer
lookup table vorberechnen und dann _delay_loop_2 und ggf. danach
noch _delay_loop_1 damit aufrufen.

Manchmal wäre es natürlich hülfreich, wenn die Leute ihr eigentliches
Problem posten würden...

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Leute! Eure Hilfe ist super!

Das mit dem double Übergabe in der _delay_ms... habe ich schlichtweg 
übersehen, damit sollte es dann eigentlich funktionieren. Sonst muss ich 
mal die Timer neu programmieren.

Die Ursache meines Problems kommt daher, dass ich mit Ultraschall 
experimentiere und zu genau definierten Zeiten ein Schallimpuls 
rausschicken will. Um dabei auf eine Genauigkeit von 1mm Auflösung im 
Messbereich zu kommen brauch ich schon eine Genauigkeit im µs-Bereich 
(Schalllaufzeit 1mm ca. 3µs).

D.h. so wie ich das sehe und meinem Compiler alle Parameter bekannt 
sind, sollte es dann keine Probleme mit der Genauigkeit geben!?

Ich werd das jetzt mal ausprobieren mit der ms-Funktion.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, wenn alles zur Compile-Zeit bekannt ist, sollte es kein Problem
sein.

Ich würde den Timer jedoch für die sinnvollere Wahl halten.  Wie
generierst du den Ultraschall selbst, mit dem AVR oder mit einer
externen Schaltung?  Wenn es ein externer Generator ist, kannst du
denn ja mittels des OCx-Ausgangs automatisch vom Timer aktivieren
lassen, also keinerlei Software-Latenz.

Autor: Mister mit Kanister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Jörg,

der Schall wird extern generiert. Lediglich mit dem µC gebe ich ein 
Enable/Disable Signal an die Sende-/Empfangsstufe. Die Sendestufe 
besteht aus einem NE555 Oszillator, der auf die Resonanz des 
Piezoschwingers abgestimmt ist. Nachfolgend kommt dann eine 
Trafoschaltung, die mir die 5V TTL Wechselspannung auf ca. 300V 
hochtransformiert.

Das Enable Signal hab ich bisher noch am normalen Port hängen, aber Dein 
beschriebener OCx-Ausgang wär dann mit Verwendung eines Timers die 1. 
Wahl.

Theoretisch könnte ich mit dem OCx eine Wechselspannung erzeugen und 
dann direkt auf die Sendestufe gehen, dann könnte ich mir den 555 
sparen.

Ich hab mal ein Test gemacht. Funktioniert gut bis zum Delay von 16ms, 
mehr packt er halt nicht. Fürs erste reicht das mal, für längere 
Pausenzeiten mach ich das dann mit nem Timer.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.