Forum: Mikrocontroller und Digitale Elektronik Microprojekt


von Kai B. (blah)


Lesenswert?

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

von Nachfrager (Gast)


Lesenswert?

Kai Blah schrieb:
> habe aber Probleme

Welche?

von Achim M. (minifloat)


Lesenswert?

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.

von Kai B. (blah)


Lesenswert?

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.

von Hauspapa (Gast)


Lesenswert?

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

von Nachfrager (Gast)


Lesenswert?

Kai Blah schrieb:
> ich soll auf der Platine(8051)

Welche?

von Kai B. (blah)


Lesenswert?

AT89C51RC2

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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.

von Kai B. (blah)


Lesenswert?

ja habe es jetzt auch bemerkt, aber die Leds werden immer noch nicht 
richtig angezeigt

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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.

von PittyJ (Gast)


Lesenswert?

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.

von Kai B. (blah)


Lesenswert?

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.

von Kai B. (blah)


Lesenswert?

wenn ich mich nicht irre, dann zählt jedes mal wenn der timer überläuft 
r0 ein mal hoch => inc r0

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?

von Toni (Gast)


Lesenswert?

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.

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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

von Maik F. (sabuty) Benutzerseite


Lesenswert?

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.

von Kai B. (blah)


Lesenswert?

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

von Dietrich L. (dietrichl)


Lesenswert?

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
Noch kein Account? Hier anmelden.