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?
> 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.
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.
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...
...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.
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...
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.