Forum: Compiler & IDEs Delay im us-Bereich


von Daniel SchulzeHagen (Gast)


Lesenswert?

Hallo!
Ich brauch in meinem Programm eine Verzögerungsfunktion (Delay), der man 
die Anzahl der us (10^-6 Sekunden) übergeben kann. Da ich einen 
AT90S4433 mit einem 4.096MHz Quarz benutze, ist halt auch schon die 
Zeit, die der Controller für den Funktionsaufruf und die Zuweisungen 
benötigt entscheidend.
Da ich kein Assembler kann und meine bisherigen Versuche gerade mal von 
der Größenordnung gepaßt haben, würde ich mich über Eure Hilfe sehr 
freuen!

Daniel

von Joerg Wunsch (Gast)


Lesenswert?


von Daniel SchulzeHagen (Gast)


Lesenswert?

Vielen Dank!

von Christoph (Gast)


Lesenswert?

Sorry das ich auch hier einen so alten Thread noch einmal nach oben
hole, aber es erscheint mir sinnvoll :)

Hat jemand mit den Funktionen aus dem obigen Link schon gearbeitet? Ich
habe nämlich so meine kleinen Probleme damit.

Die ms_spin() Funktion funktioniert erstmal einwandfrei, dass ist die
gute Nachricht ;). Die us_spin Funktion, die ja eigentlich im us
Bereich arbeiten soll verhält sich allerdinga genauso wie die ms_spin
Funktion. Ist ansich auch nicht verwunderlich, wenn ich mich nämlich
nicht komplett verlesen habe sind die beiden Funktionen ein und
dieselbe...

Da ich im moment versuche, etwas mit einem IR-Empfänger zusammen zu
basteln, wäre ein Timer im us Bereich natürlich sehr nützlich. Wäre
toll wenn jemand einen Tip für mich hätte :)

Gruss Christoph

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Ich würde in us_spin() LOOPS_PER_MS durch LOOPS_PER_US ersetzen, damit
sollte es funktionieren.

von Christoph (Gast)


Lesenswert?

Habe ich eben ausprobiert:

GCC liefert mit folgendes beim compilieren:

ccemaaaa.s: Assembler messages:
ccemaaaa.s:73: Warning: constant out of 8-bit range: 3906

ich vermute mal, dass es mit diesen Zeilen zusammenhängt:

#define AVR_CLK (4000000)
#define LOOPS_PER_US (AVR_CLK/4)
#define LOOPS_PER_MS (AVR_CLK/1000/4)

was man dagegen machen kann weiss ich allerdings nicht, so gut kenne
ich mit dem gcc/avr leider noch nicht aus.

Der Code wird zwar trotzdem noch compiliert, arbeitet aber nicht
korrekt, die Pause die ein delay von eigentlich 1000 us sein sollte ist
mehrere sekunden lang...leider hab ich mich mit dem debuggen/simulieren
auch noch nicht wirklich beschäftigt, im moment probier ich das meiste
direkt auf dem avr aus.

von Christoph (Gast)


Lesenswert?

Ok, dann nur noch eine kurze Überlegung zu den Routinen in delay.h:

die _delay_loop_2() braucht laut Beschreibung 4 Takte für einen Umlauf.
D.h. bei 4Mhz sind das (1/4000000) * 4 = 1us pro Umlauf. Wenn das so
stimmt, könnte ich doch in meinem Fall mit dem Aufruf
_delay_loop_2(1500) z.b. einen 1500us = 1.5ms langen delay erzeugen,
oder hab ich irgendwas vergessen?

von Joerg Wunsch (Gast)


Lesenswert?

Eine kurze VMLAB-Simulation bestätigt das, ja.

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Delay-Loops dienen ausschließlich dazu, irgendwelche Minimalzeiten
einzuhalten. Also z.B. für die Busy-Zeiten bei LCDs oder die Timings
beim I2C-Bus.

Eine Genauigkeit ist dabei nicht im entferntesten zu erreichen und erst
recht nicht bei kleinen Delays. Da zählt ja auch jede andere
Instruktion vor und nach dem Aufruf mit und natürlich sämtliche
Interrupts.

Einen IR-Empfänger kannst Du damit voll vergessen.
Da hilft nur ein Timerinterrupt oder Polling eines freilaufenden
Timers.

Anbei ein Beispiel für das Polling bei einem 2. UART Sender in
Software.


Peter

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Und hier noch der IR-Empfänger mit Timerinterrupt.

Da es C-Programme sind, sollte man sie leicht vom 8051 auf den AVR
anpassen können (Timerzugriff, Portpinzugriff, Quarztakt).


Peter

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.