Forum: Mikrocontroller und Digitale Elektronik RS232


von Zsolt (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Habe da ein kleines Problem:
Im Anhang befindet sich ein Programm das wen es z.B.: "H11" über Rs232 
erhält das Led am PORTB,1 einschalten sollte. Nun aber, habe ich den 
Mega angeschlossen und ihm H11 übertragen, er hat auch das LED 
eingeschalen aber wenn ich danach z.B. das zweite Led am Portb, 2 
einschalten oder das erste led auschalten möchte macht er nichts mehr. 
Erst wenn ich ihn resete dann kann ich das LED wieder einschalten. Ein 
weiteres Problem ich kann auch nach einem Reset das zweite led nicht 
ansteuern! Kann mir bitte jemand helfen, wäre sehr dankbar!

Danke, mfG Zsolt

Ach ja, ich habe auch versucht am schluss jeder funktion wo jetzt "reti" 
steht  "ret" oder "rjmp Main" hinzuschreiben hat aber leider auch nichts 
gebracht!

von Macc (Gast)


Lesenswert?

Wie findet man Fehler in irgendwelchem Code ?
Einen freien Pin als Ausgang definieren und auf den Pin einen Puls 
ausgeben. Dadurch kann man mit dem Scope mitverfolgen welche Code 
ausgefuehrt wurde und welcher nicht.

von Zsolt (Gast)


Lesenswert?

Was ist wenn man aber keine Scope hat? Habe leider zu Hause keines!!

MfG Zsolt

von Andreas K. (oldcoolman)


Lesenswert?

Dann löscht du einen Pin und
fügst gleich danach eine endlosschleife ein.
nach der endlos setzt du ihn wieder.

Jetzt hängt das programm an der stelle und gibt dir per
signal 0 an daß es hier angekommen ist

alles klaro?

Gruß
Andi

von Obelix (Gast)


Lesenswert?

Man kann auch einen Debugger verwenden.

von Andreas K. (oldcoolman)


Lesenswert?

wenn man hat.

also ich kenn den controller net,aber wenn man aus einer
Interruptroutine(int_rxc) heraus zu einer anderen springt (kein call),
dann MUSS diese angesprungene mit reti beendet werden !!
(es sei denn man springt wieder zuück in die int_rxc,aber sowas ist echt
Murx!!)

reti ist wie ein call nur für Interrupts.
Das heißt es wird eine Adresse auf dem Stack gespeichert,die
bei reti wieder zurückgeholt wird. Nur so kann das Programm
da weitermachen wo es unterbrochen wurde.

Hier sind einige male ret und reti verwechselt.
Dies produziert Stackfehler,da nützt auch kein scope!

gute Nacht

Gruß
ANdreas


von Karl H. (kbuchegg)


Lesenswert?

Wobei man auch sagen muss, dass der ganze Programmaufbau, so
wie er jetzt ist, ziemlicher Murx ist.

Da wird hemmunglos in der Interrupt Routine eine Warteschleife
eingefügt, wenn nicht das richtige Zeichen daherkommt.
Da wird in der Interrupt Routine enie unnötige Auswertung gefahren,
die auch noch darin mündet, dass zeichen zurückgeschickt werden,
was wiederrum zu Wartezeiten im Interrupt führt etc.


Interrupt Funktionen sollen kurz sein!


Ein Aufbau der sich gut bewährt, ist zb Folgender:
Die Interrupt Funktion, die je automatisch nach dem Empfang
eines Zeichens aufgerufen wird, hat nur eine Aufgabe:
Sie nimmt das Zeichen entgegen, entscheidet ob durch dieses
Zeichen eine komplette Befehlssequenz empfangen wurde.
* Ist dieses Zeichen die Endekennung für die Sequenz, dann
  setzt sie eine Flagge
* Ist dieses Zeichen nicht die Endekennung, dann speichert sie
  das Zeichen im SRAM.

Die eigentliche Auswertung erfolgt dann im Hauptprogramm in
einer Schleife. In der Schleife wird ständig die Flagge
kontrolliert. Ist diese gesetzt, dann bedeutet dies, dass
im SRAM eine komplette Kommandosequenz vorliegt und in der
Hauptschleife wird diese dann ausgewertet.

Die Aufgabe der Interrupt Funktion ist es also, aus dem
empfangenen Zeichenstrom einzelne komplette Kommandosequenzrn
herauszufischen und im SRAM zu speichern.
Die Aufgabe der Hauptschliefe ist es eine komplette Kommandosequenz
zu bearbeiten.

von johnny.m (Gast)


Lesenswert?

> Dies produziert Stackfehler,da nützt auch kein scope!
Das stimmt nicht. Der einzige Unterschied zwischen ret und reti ist, 
dass bei einem reti das I-Bit im Statusregister gesetzt wird, um die 
Interrupts wieder freizugeben. Dem Stack ist das egal, welcher 
Return-Befehl die abgelegte Rücksprungadresse wieder "abholt". Nur 
werden nach der Beendigung eines Interrupt-Handlers mit ret anstatt mit 
reti die Interrupts nicht wieder freigegeben und demzufolge ist der 
erste Interrupt auch gleichzeitig der letzte...

von johnny.m (Gast)


Lesenswert?

...Ergänzung: Stackprobleme kriegt der OP allerdings trotzdem, da im 
Code Sprung- und Verzweigungsbefehle (z.B. breq) mit einem ret 
abgeschlossen werden. Da weder Sprung- noch Verzweigungsbefehle eine 
Rücksprungadresse auf dem Stack ablegen, knallt es beim ret, wenn eine 
Adresse vom Stack geholt wird, die dort gar nicht abgelegt wurde (bzw. 
die von jemand anderem dort abgelegt wurde...). Ein Unterprogramm wird 
mit (r)call aufgerufen, und NUR bei (r)call darf ein ret verwendet 
werden, um an die aufrufende Stelle zurückzukehren! Bei (r)jmp und 
br<xy> hat ein ret nichts verloren.

von Andreas K. (oldcoolman)


Lesenswert?

jonny,
das mit dem ret und reti stimmt natürlich!!

nur sollte man per hand des I-Flag rücksetzen und dann per ret 
verlassen,
wo es doch reti gibt?

sorry,ich kenne nur 8051
wußte nicht was breq macht.

zur Ergänzung:

ISR:
...
...
...
bedingter sprung in eine außerhalb liegende routine
...
...
...
reti

außerhalb liegende routine
..
...
...
...
RETI   (!!!)


ist genauso ok. beidesmal wird die ursprunsadresse zurückgeholt!
da ein sprung keine adressenspeichert.

Gruß
Andi

von johnny.m (Gast)


Lesenswert?

@Andreas:
Ist ein bisschen schwer nachvollziehbar, was der OP sich genau dabei 
gedacht hat. Ich war davon ausgegangen, dass er mit dem ret wieder 
zurück an die Stelle hinter dem breq springen wollte. Wenn das nicht der 
Fall ist, dann trifft Dein Vorschlag zu, indem er einfach das ret durch 
ein reti ersetzt.

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.