Hallo, ich programmiere gerade einen Lasertagger (Lasertag). Ich programmiere in Assembler. Ich möchte, dass man bei einem "HIT" nicht mehr weiter schießen kann und stattdessen ein Ton ertönt. Das läuft bei mir zur Zeit über einen Interrupt. Jetzt stehe ich vor zwei Problemen: 1. Im Falle eines "HIT" soll man lediglich 5 Sekunden warten müssen und dann weiterspielen können. Das heißt ich benötige währen des Interrupts, der den "HIT" Zustand auslöst, einen Timer, der die Zeit zählt. Zur Zeit überbrücke ich die Wartezeit durch Schleifen mit "NOP" und sitze so einfach die Wartezeit ab. Das ist mir aber zu ungenau. Kann ich irgendwie den Timer weiterlaufen lassen und den Interrupt dadurch nach 5 Sekunden beenden lassen? Das Problem vor dem ich stehe ist, dass während eines Interrupts, alle anderen Interrupts deaktiviert sind (somit auch der Timer und dessen Overflow). Hat Jemand eine Idee wie ich das lösen könnte? 2. Ich möchte, dass nach dem "HIT" das Programm nicht an die Stelle an der es vor dem Interrupt war zurückspringt, sondern dass es wieder an den Anfang des Programms springt. Ich kenne bis jetzt nur den Befehl "RETI", mit dem ich lediglich an die Ursprungsadresse springen kann. Wie könnte ich das lösen? Liebe Grüße, René
@ René W. (mikrokibo) >Ich möchte, dass man bei einem "HIT" nicht mehr weiter schießen kann und >stattdessen ein Ton ertönt. Das läuft bei mir zur Zeit über einen >Interrupt. Und damit vermutlich nicht so gut. >1. Im Falle eines "HIT" soll man lediglich 5 Sekunden warten müssen und >dann weiterspielen können. Das heißt ich benötige währen des Interrupts, >der den "HIT" Zustand auslöst, einen Timer, der die Zeit zählt. Dein Interrupt aktiviert nur ein Flag, welches von einer Statemachine in der Hauptschleife verarbeitet wird. Siehe Interrupt. > Zur Zeit >überbrücke ich die Wartezeit durch Schleifen mit "NOP" und sitze so >einfach die Wartezeit ab. Das ist mir aber zu ungenau. Und blockiert deine CPU zu 100%. >2. Ich möchte, dass nach dem "HIT" das Programm nicht an die Stelle an >der es vor dem Interrupt war zurückspringt, sondern dass es wieder an >den Anfang des Programms springt. Auch das kann und sollte man ganz einfach und sauber in der Statemachine lösen. Geht auch problemlos in ASM.
>sauber in der Statemachine lösen
Genau. Und da diese wahrscheinlich schnell genug ist, könnte man sich
den INT für das HIT-Event evtrl. auch sparen und direkt in der
StateMaschine im Zustand "Warten auf HIT" als Transition nutzen.
Man könnte es auch so formulieren. Wann immer man in einem µC-Programm so programmiert > Zur Zeit überbrücke ich die Wartezeit durch Schleifen mit "NOP" > und sitze so einfach die Wartezeit ab. dann sind Probleme unausweichlich und man hat sehr wahrscheinlich ganz einfach einen völlig verkorksten Ansatz für das Programm gewählt. Aktive Warteschleifen sind in der µC-Programmierung die Mutter allen Übels. Sie sind in den seltensten Fällen die Lösung aber sehr oft das Problem. Da reissen einen dann auch Interrupts nicht mehr raus. Die drücken einen dann nur noch tiefer in den Sumpf rein und verlagern das Programm von 'verkorkst' zu 'völlig verkorkste von-hinten-durch-die-Brust-ins-Auge Lösungs Idee'. Da hilft nur noch ein massives Redesign mit einem vernünftigen Ansatz, wie zb der schon erwähnten State-machine. und mit 'massives Redesign' meine ich: wegwerfen und mit einem ordentlichen Ansatz nochmal neu anfangen. Retten lässt sich da meistens sowieso nichts mehr. Im Falle einer Statemachein beginnt man dabei mit Papier und Bleistift und einem aufmalen der Zustände (der States) der Maschine und identifizierung der Zuastandsübergänge. Statemachine
Karl Heinz schrieb: > Retten lässt sich da meistens > sowieso nichts mehr. Na vielleicht könnte man den alten Teil zum Initialisieren der Ports noch verwenden vor der Hauptschleife der SM. :)
Ich danke euch für eure Tipps. Bin noch ziemlich neu hier und das ist das erste Programm, das ich programmiere. Habe auch mit Programmieren noch nicht so viel gemacht, aber ich lerne gerne dazu. Der Tipp mit der State Machine und den Rest wegwerfen hört sich doch ganz vernünftig an... Ich fange gleich mal an zu lesen..
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.