Hallo, ich arbeite mich gerade wieder in PIC Programmierung ein und versuche verschiedene kleine Testprogramme zu programmieren um die Chips und C richtig zu verstehen. Nun habe ich ein Frage zur "best practice". ;) Ich habe das Vellemann Testboard und habe mit das Beispielprogramm dazu angesehen (ASM) welches einfach beim drücken von Tasten verschiedene Muster auf den LEDs erzeugt. In der notwenigen Delay Routine, damit man die LEDs leuchten sieht, wird immer wieder der Tastenzustand abgefragt und bei gedrückter Taste die Delay Schleife verlassen und in einem Menue Teil die richtige Routine neu aufgerufen. Soweit so gut, das versteh ich auch soweit alles. Nun bin ich am zeifeln wie man das in C am besten löst. Habe bisher mit Standard delay(ms) Funktionen gearbeitet. Die laufen also stur bis zum Emde durch und eine Reaktion auf eine neu gedrückte Taste kann erst dann wieder erfolgen. Ich könnte ja auch eine "spezielle" delay() Routine schreiben die beim auftreten einer gedrückten Taste mit break; abgebrochen wird. Also ähnlich dem Assembler Code. Ist das der richtige Ansatz? Oder gibts da mit C eine elegantere Methode? Danke und viele Grüße Andreas
Langes Delay auf wiederholte kurze Delays runterbrechen und zwischendurch mal nach der Taste suchen.
Andreas Krüger schrieb: > Hallo, > ich arbeite mich gerade wieder in PIC Programmierung ein und versuche > verschiedene kleine Testprogramme zu programmieren um die Chips und C > richtig zu verstehen. Nun habe ich ein Frage zur "best practice". ;) > Ich habe das Vellemann Testboard und habe mit das Beispielprogramm dazu > angesehen (ASM) welches einfach beim drücken von Tasten verschiedene > Muster auf den LEDs erzeugt. In der notwenigen Delay Routine, damit man > die LEDs leuchten sieht, wird immer wieder der Tastenzustand abgefragt > und bei gedrückter Taste die Delay Schleife verlassen und in einem Menue > Teil die richtige Routine neu aufgerufen. Soweit so gut, das versteh ich > auch soweit alles. Dann hast du auch schon verstanden, dass der ganze Delay-Ansatz eine Sackgasse ist. > abgebrochen wird. Also ähnlich dem Assembler Code. Ist das der richtige > Ansatz? Oder gibts da mit C eine elegantere Methode? Da gehst weniger um C und/oder Assembler sondern um das ganze Prozedere. Ein Delay, also eine Warteschleife ist grundsätzlich zwar einfach, aber der falsche Ansatz für komplexere Programme. Für solche Dinge hat man Timer. Zeitsteuerungen laufen in 'richtigen' Programmen praktisch immer über einen Timer.
Andreas Krüger schrieb: > Nun habe ich ein Frage zur "best practice". ;) Man verwendet delay_ms() überhaupt nicht (höchstens in der Initialsierung oder delay_ns() für sehr kurze Delays). Für alles andere gibt es Timer.
"Best practice" wäre wohl: kein delay verwenden. Timer stellt zeitbasis zur Verfügung, "delay" als zählen von xxx Timer-Ticks implementieren, z.b. innerhalb der State-Machine in der Main-Loop. Wenn nichts zu tun ist, kann die Main-Loop in den sleep/idle/power-save modus.
Vom Prinzip her:
1 | for(;;){ |
2 | if( timer_abgelaufen() ) |
3 | naechstes_muster_anzeigen(); |
4 | if( tastendruck() ) |
5 | tastendruck_behandeln(); |
6 | }
|
Nach genau diesem Prinzip arbeitet dieses Beispiel: Beitrag "Re: AVR Sleep Mode / Knight Rider" Peter
Andreas Krüger schrieb: > Oder gibts da mit C eine elegantere Methode? Ja. Man wartet gar nicht, sondern arbeitet statdessen was anderes. Und sieht in einer Schleife (die legendäre Hauptschleife) zwischendurch mal nach, ob die Zeit schon vorbei ist. Wenn die Zeit dann um ist, dann wird die gewünschte Aktion ausgeführt: http://www.lothar-miller.de/s9y/categories/22-Zeiten
Danke für die vielen schnellen Antworten! Ihr seid wirklich klasse!! Ich denke das schubst mich schon in die richtige Richtung. Wenn man den uC zwischendurch in den sleep schicken will etwa so: durchlaufender Timer mit Interrupt Timer Interrupt auslösen. (aufwachen) Timertick Variable inkrementieren. Tastenstatus abfragen (mit Entprellung) Interrupt Routine beenden Die Mainschleife läuft durch das aufwachen auch weiter. Hier dann prüfen ob Zeit für Musterwechsel abgelaufen oder andere Taste gedrückt. Enstprechende Programmteile aufrufen. Wieder schlafen legen. Liege ich da richtig? Viele Grüße Andreas
Die Tasterentprellung kann man auch nach dem Aufwachen in der Hauptschleife machen, die ist ja nicht zeitkritisch. ISRs immer so kurz wie möglich halten, es könnte ja schließlich noch andere, wirklich zeitkritische Interrupts geben. Ansonsten ja, das ist übliche Vorgehensweise.
Sleep sollte man nur da verwenden, wo es auch auf die Stromaufnahme ankommt. Und auch erst ganz zum Schluß implementieren. 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.