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
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
Ich würde in us_spin() LOOPS_PER_MS durch LOOPS_PER_US ersetzen, damit sollte es funktionieren.
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.
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?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.