Hallo Leute, ich soll auf der Platine(8051) ein Ampelsystem simulieren, habe aber Probleme, da ich neu in dem Gebiet bin. Ich benutze den Timer 0 und eine Tabelle um die Phasen der Ampel darzustellen. Der Port P2 sieht so aus: rot, gelb, grün, 0, 0, 0, rot, grün Hier ist mein Programm. Ich wäre sehr dankbar wenn jemand mal einen Blick draufwerfen könnte! Und ich entschuldige mich für meine Unkenntnis. ljmp hauptprogramm org 000bh; LJMP isr_t0; hauptprogramm: mov r0, #0 ;tabellephasen mov r1, #80 ;wartezeit mov r2, #100 ;wartezeit mov tl0, #6 mov th0, #6 mov tmod, #00000010b mov tcon, #00010000b setb ea setb tr0 setb et0 endlos: ljmp endlos isr_t0: mov a, r0 mov dptr, #tabelle movc a, @a+dptr mov p2, a anl a, #00001010 ;maskierung, erspart die abfrage bei r0 lcall label3 inc r0 reti label3: djnz r1, label3 djnz r2,label3 mov r1, #80 mov r2,#100 ret tabelle: DB 00100010b, 01000010b, 10000010b, 10000001b,10000001b,10000001b,10000001b, 10000010b, 01000010b, 00100010b end
Wie die Spam-Erkennung, die einen nichts Posten lässt, das z.B. das Wort cas ino (natürlich ohne Leerzeichen...) enthält, könnte man eine Sperre einbauen, die zumindest ein einziges Fragezeichen in einem Ausgangspost erzwingt.
Also das Programm läuft nicht wie ich es will. Wenn ich das in Keil uVision4 Simuliere, dann blinkt der Port P2 gelegentlich, aber die Leds sollen ja konstant an sein, wenn sie gesetzt sind. und außerdem stimmt es von der Zeit her auch nicht. Die Wartezeit zwischen jeden Wechseln beträgt ja 2 Sekunden, aber bei der Simulation schaltet es nicht nach 2 Sek.
Ich hab mich durch Dein Assembler nicht durchgearbeitet, da ich selbst nur C programmiere. Für Dich scheint mir der wichtigste Schritt: ein Stift, ein Blatt Papier und darauf ein Zustandsdiagramm mit allen Übergängen zu sein. (In der Realisierung ist das dann nur noch ein Zähler der brav hochzählt, nach Zählerstand die Lampen schaltet und fertig.) Wenn Du auf das Zustandsdiagramm verzichtest fängst Du jedes mal neu an. Mit Zustandsdiagramm ist es relativ einfach das z.B. auf Ampel mit Sensorschleife und Anforderungstaster umzustricken. viel Erfolg Hauspapa
Kai Blah schrieb: > anl a, #00001010 ;maskierung, erspart die abfrage bei r0 Da fehlt wohl ein "b" bei der Konstante, damit der Compiler auch weiss, dass das eine Binärkonstante sein soll.
ja habe es jetzt auch bemerkt, aber die Leds werden immer noch nicht richtig angezeigt
Kai Blah schrieb: > label3: > djnz r1, label3 > djnz r2,label3 > mov r1, #80 > mov r2,#100 > ret Wofür brauchst du diese Verzögerungsschleife, wenn doch der Aufruf durch den Timer erfolgt? Wenn der Timer zu schnell triggert, sollte das vom Konzept her anders gelöst werden, zB die Timer-Interrupts zählen.
Früher hat man bei jeder Assembler-Zeile wenigstens einen Kommentar hinten drangefügt. Das gibt es heute auch schon nicht mehr. Früher war eben alles besser. Ist der Teil bei Label3 eine Warteschleife? Ist ja sehr komisch programmiert. Was passiert, wenn der innere Zähler bei 0 ist? Wird der gar nicht mehr neu gesetzt? Naja, würde ja normalerweise im Kommentar stehen.
das label3 ist eine warteschleife, da ich einen 8 bit autoreload timer benutze. die wartezeit soll 2 sek. sein und nur mit den reloadwert des timers komme ich nicht auf 2 sekunden. Deswegen habe ich r1 und r2 als hilfsregister benutzt, um auf sek wartezeit zu kommen.
wenn ich mich nicht irre, dann zählt jedes mal wenn der timer überläuft r0 ein mal hoch => inc r0
PittyJ schrieb: > Was passiert, wenn der innere Zähler bei 0 ist? > Wird der gar nicht mehr neu gesetzt? Er zählt konsequenterweise mit 255 weiter. Dann ist die Verzögerung halt 2,5 mal länger als gedacht... Kai Blah schrieb: > ja habe es jetzt auch bemerkt, aber die Leds werden immer noch nicht > richtig angezeigt Und WAS wird angezeigt?
Die Warteschleife ist schon seltsam programmiert- der innere Zähler ändert seinen Wert mit dem nächsten djnz-Befehl von 0x00 auf 0xFF, was vemutlich nicht so gewollt ist, vermute ich zumindest.
Also, mehrere prinzipielle Probleme: * der Bereich von R0 wird nirgendwo überprüft --> "komische" Anzeige * Warteschleife im Timerinterrupt zeigt, dass Sinn und Zweck von Timern und Interrupts nicht klar sind ToDo: * Im Unterrichtsmaterial nachlesen, wofür man Timer nimmt und warum Warteschleifen in Interrupts böse sind * Warteschleife entfernen * R0 Bereichsüberprüfung hinzufügen
Maik Fox schrieb: > Kai Blah schrieb: >> anl a, #00001010 ;maskierung, erspart die abfrage bei r0 > > Da fehlt wohl ein "b" bei der Konstante, damit der Compiler auch weiss, > dass das eine Binärkonstante sein soll. Und diese ganze Zeile hat im Kontext des Programm sowieso keinerlei Funktion, daher war der Fehler recht egal.
ich habe die warteschleife ein bisschen verändert, es wird ja 80*100 gezählt und zum schluss wird r1 wieder auf 80 und r2 auf 100 gesetzt da ja nach jedem überlauf die schleife wieder 80*100 gezählt wird label3: mov r1, #80 label2: djnz r1,label2 djnz r2,label3 MOV R2,#100 mov r1, #80 ret Ich bedanke mich hier für die unterstützung und entschuldige mich für meine ungenügende Kenntnis
Kai Blah schrieb: > ich habe die warteschleife ein bisschen verändert, Sinnvoller wäre folgendes: In der ISR wird gezählt, wie oft sie aufgerufen wurde. Erst nach n-mal Aufruf wird das Teil "Ampelsteuerung" ausgeführt. In der jetzigen Lösung ist die ISR und der Timer gerade für die Katze: wenn Du in der ISR 2 Sekunden wartest, ist der Timer sowieso abgelaufen und ein neuer Interrupt steht bei Verlassen der ISR bereits an. D.h.: Du kannst das ganze gleich in der "endlos:"-Schleife machen und Dir den Timer sparen. Gruß Dietrich
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.