Wegen Delay Funktion _delay_us(double __us)

Gast #482995
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?
Gast #483008
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.
Gast #483033
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...
Gast #483036
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.
Moderator Persönliche Seite #483063
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...
Gast #483372
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.
Moderator Persönliche Seite #483416
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.
Gast #483522
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren