Hallo, ich habe vor, bzw. bin gerade an der Umsetzung des folgenden Projekts: Ich hab ein Board mit nem xMega16D4 auf dem soll folgendes geschehen, nach einem bestimmten Zeitplan sollen Dinge ausgeführt werden. Das folgende (schreib das zur Vereinfachung nur mit LED an/aus) Led1 an 10s warten Led1 aus Led2 an 15s warten Led2 aus Das mit wait zu machen is mal eine ganz schlechte Idee, also Timer. Das hab ich mir so vorgestellt, den Timer so einstellen dass ein Tick alle 10ms stattfindet, dann wird immer eine Variable (ich nenn sie mal A) hochgezählt mit dem Takt. Dann im Programm iwie an der Led1 an z.B. den aktuellen Wert von A merken, den 10s addieren und das in ne Zwischenvariable B speichern, und dann später überprüfen wann A = B ist und dann Led1 aus schalten. Jeder der etwas Ahnung hat wird jetzt wahrscheinlich die Hände überm Kopf zusammen schlagen ... Ich übrigens auch, aber ich komm im Moment grad auf nix besseres (Betriebsblind? ...) Daher die Frage, wie macht man sowas ordentlich? Steh da grad etwas aufm Schlauch. EDIT: ganz vergessen, eigentlich muss man es ja nicht Wissen, geht ja nur ums Prinzip wie man das umsetzt, aber für die dies interessiert, ich arbeit in C. David
:
Bearbeitet durch User
Hi, Das mit der Variable A im Timer ist schon richtig. Die zählst Du hoch. Im Hauptprogramm tust Du nichts anderes als diese Variable auszuwerten. (sinnvollerweise mit einem case Konstrukt) Hier vergleichst Du die Variable mit den gewünschten Zeiten Deiner Ereignisse. In Deinem Fall also: case A A=0: Led1 an # 10s warten A=1000: #10ms x 1000 Led1 aus Led2 an # 15s warten A=2500: #25ms x 1000 (ab A=1000 15s) Led2 aus endcase Und wenn der Zyklus beendet ist, setzt Du A in Deinem Hauptprogramm wieder auf 0. Das ist nichts anderes als eine Statemaschine. Gruß Andreas
:
Bearbeitet durch User
David .. schrieb: > Das hab ich mir so vorgestellt, den Timer so einstellen dass ein Tick > alle 10ms stattfindet, dann wird immer eine Variable (ich nenn sie mal > A) hochgezählt mit dem Takt. > > Dann im Programm iwie an der Led1 an z.B. den aktuellen Wert von A > merken, den 10s addieren und das in ne Zwischenvariable B speichern, und > dann später überprüfen wann A = B ist und dann Led1 aus schalten. Das kann man im Prinzip genau so machen, wie du das vorschlägst. Ich machs ganz gerne anders rum. Ich hab keinen Zähler der hochzäht, sondern pro LED einen Zähler der runterzählt. Quasi ein Countdown für jede LED, wie lange sie noch brennen soll. In der Hauptschleife wird der Countdownzähler auf einen Wert gesetzt, der der gewünschten Zeitdauer der Brenndauer entspricht (unter Berücksichtigung der ISR-Aufrufzeiten) und die LED eingeschaltet. In der ISR wird der Zähler sukzessive wieder runter gezählt und wenn 0 erreicht ist, wird in der ISR die LED abgeschaltet (oder sonst irgendeine Aktion ausgelöst). Variationen davon sind natürlich möglich. Worauf es mir ankommt ist, dass ich das Gefühl habe, dass Countdown-Steuerungen auf dieser Ebene oftmals ein bischen einfacher sind, als eine Uhr die hochzählt.
:
Bearbeitet durch User
Karl Heinz schrieb: > Worauf es mir ankommt ist, > dass ich das Gefühl habe, dass Countdown-Steuerungen auf dieser Ebene > oftmals ein bischen einfacher sind, als eine Uhr die hochzählt. Vor allen Dingen muss man bei Änderungen von Zeiten nur an einer Stelle, nämlich dort wo der Countdown-Wert gesetzt wird, etwas ändern und nicht überall alle Schaltzeitpunkte umrechnen.
Guten Tag, hier gibt es auch noch einen schönen Ansatz solche Zeitsteuerungen zu erschlagen. Beitrag "Wartezeiten effektiv (Scheduler)" Damit sollte sich sowas gut realisieren lassen. Man muss nur im Code die Timerkonfiguration auf ATxmega trimmen... Vielleicht hilft das ja schon mal weiter. Gruß Flo
Wow, vielen Dank für die Antworten, werde ich mir gleich ansehen. Inzwischen hab ich aber auch schon eine Lösung: ISR(RTC_OVF_vect) { timerTime++; } und ein Zeitablauf sieht dann so aus: switch (timerTime) { case 0: //led1 an break; case 200: //led1 aus //led2 an //sound#2 starten break; case 800: //led2 aus //sound stoppen timerTime = 0; break; } Ziemlich simpel und für mich derzeit schonmal ausreichend :)
du musst dabei halt sicherstellen, dass der switch-case oft genug aufgerufen wird, dass du nicht einen Timertick verpasst. Sonst könnte es passieren, dass z.B. timerTime > 800 wird und dann dauert es je nach Datentyp ein bisschen, bis die überläuft und wieder bei 0 anfängt ;)
Sehr guter Punkt. den RTC hab ich so eingestellt das es alle 10ms ein Tick gibt, das dürfte bei 32MHz der CPU wohl locker reichen. Und da ich nichts delays mache sondern nur LEDs, Servos und nen externes Soundmodul (WTV020 von eBay aus China falls jemand sowas zufällig sucht) hab ich da auch kein Problem damit, zumindest derzeit nicht. Hab bisher noch keine Probleme fest gestellt. Ansonsten kann man die XMegas wohl auch noch übertakten :P
David .. schrieb: > Hab bisher noch keine Probleme fest gestellt. > Ansonsten kann man die XMegas wohl auch noch übertakten :P Übertakten brauchst du nicht. Du brauchst nur so programmieren (wenn du mal in die Situation kommst), dass du defensiv arbeitest. Also nicht darauf bestehen, dass eine bestimmte Zahl exakt rauskommen muss, sondern berücksichtigen, dass du eventuell auch mal einen Tick verpassen kannst. Mit den geschilderten Techniken ist das ja auch kein Problem.
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.