Hallo ihr klugen C++Köpfe! Kurz und knapp: Das auskommentiere Codebeispiel im Anhang soll einen ATmega8 eine LED im Sekundentakt aufblinken lassen. Nebenbei läuft der Timer2 im Clear to Compare Mode, in dessen Interrupt-Funktion im Code jedoch nichts steht, da das Problem auch ohne abzuarbeitende Befehle im interrupt besteht. das Problem: Wenn die globalen Interrupts aus sind oder man den Timer-Overflow-Interrupt ausstelt mit dem Register "TIMSK", dann stimmen die Sekundentakte, die "delay" erzeugt. Lässt man Timer und Interrupts wie im Codebeispiel eingeschaltet, so stimmen die Sekundentakte nicht mehr. Woran liegt diese scheinbare Abhängigkeit von Timerinterrupt und delay??? Wie behebe dies? - Freqenz ist passend im makefile hinterlegt - Optimierungsgrad des Compilers = s (Optimization for size) Hintergrund: Bin 19 Jahre alt und von Visual C++ Beginner zum Mikrocontroller Beginner konvertiert und habe bisher nur ein Servo Rampen fahren lassen und LEDs zum Blinken gebracht. Da ich aber mit einem uC zwei servos und über ein Schieberegister ein LCD betreiben will, müssen die delay-Zeiten ja stimmen.
Leider scheibst du nicht wie ungenau es ist. Aber das delay warten nicht wirklich die Zeit im ms ab, sondert verbaucht einfach x-ms Rechenzeit. Wenn innerhalb dieser ein ein Interupt eintritt, der auch rechenzeit braucht, dann weiss die delay funktion nichts davon. Es addieren sich also die zeiten. man kann also nur sagen das Delay mindestens x-ms warten. Wenn man es genauer will muss man mit Timern arbeiten.
Hallo, wenn der Timerinterrupt freigegeben ist, wird auch die Interruptroutine aufgerufen. Selbst wenn die nur aufgerufen und beendet wird, kostet das ca. 10 Takte. Wenn GCC noch Register rettet und zurückschreibt, entsprechend mehr. Um die verlängert sich die Delay-Zeit natürlich. Delay ist keine Routine für eine Uhr, es ist ein Hilfsmittel, um kurze Wartezeiten zu erreichen. Für Sachen gibt es ja die Timer. Gruß aus Berlin Michael
Warteschleifen sind meist die schlechteste Lösung. Mit Timern geht das besser. Konkrete Hilfe kann ich Dir nicht geben, da ich AVRs in ASM programmiere. ...
Na das ging ja super schnell, ich staune wie viel hier los ist und wie toll einem hier geholfen wird, ich hab mir tagelang den Kopf zerbrochen. Habe wohl das grundsätzliche Schema der delays übersehen, ich dachte, der uC würde die delays mit der Zeit aus den Interrupts verrechnen und hätte nur ein Problem wenn das delay kürzer als der interrupt ist. Fazit: Absolut alles was exakt getimed sein muss, wird mit timern gemacht. Mit delays kann man nur Zeit draufrechnen. Vielen Dank! blöder Denkfehler^^
genau delays sind nur für kleine pausen wo es absolut unkritisch ist ob das nun mal 5ms oder7ms sind ist dann egal bei genauen timings immer einen timer verwenden
> ...kleine pausen... > ...5ms oder7ms... Das ist ein Widerspruch. Kleine Pausen sind im Mikrosekundenbereich, 5 bis 7 Millisekunden sind bereits große Pausen. Warteschleifen sind dann berechtigt, wenn die Zeiten so kurz sind, dass bei Verwendung eines Timers der Interrupt-Overhead stören würde. Im Millisekundenbereich ist der Timer die bessere Wahl. ...
Hallo, oooch... ich mache auch manchmal 30ms Pause per BusyLoop, wenn der AVR definitv in der Zeit nichts sinnvolles machen kann. ;-) Beispiel? Wenn ich auf den Luftdrucksensor warten muß, weil ich anschließend die Daten senden will, mache ich das einfach. Will damit nur sagen: es kommt gerade bei einem µC immer auf das Umfeld an. Man kann sich da ja immer sicher sein, daß nur geanu das läuft, was man programmiert hat (sollte es zumindest ;)). Wenn natürlich irgendwann mal der AVR in solchen Pausen Updates von atmel.com holen will............ Gruß aus Berlin Michael
> Beispiel? Wenn ich auf den Luftdrucksensor warten muß, weil ich > anschließend die Daten senden will, mache ich das einfach. Bei der LCD-Init mach' ich das auch, da liegt eh noch nix Anderes an. > Will damit nur sagen: es kommt gerade bei einem µC immer auf das Umfeld > an. Genau. > Man kann sich da ja immer sicher sein, daß nur geanu das läuft, was man > programmiert hat (sollte es zumindest ;)). So sollte es sein, sofern man nicht unverstandene Fundstücke zusammenkopiert hat. Meine Programme haben meist aber etwas mehr zu tun, da versuche ich, ISRs und Mainloop-Jobs möglichst kurz (schnell) zu halten. Was nützt es mir, wenn die ISR einen Merker setzt, die Mainloop diesen (bzw. den daran hängenden Job) aber nicht zeitnah abarbeiten kann, weil ein anderer Job im Busywait hängt oder (als Timer) Takte zählt, während ein (mitgekaufter) Timer arbeitslos ist. Und nein, es ist kein Dogma, hat sich aber schon oft als nützlich erwiesen. Gruß aus der Elbaue ...
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.