www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RS232


Autor: Zsolt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: Macc (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Zsolt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist wenn man aber keine Scope hat? Habe leider zu Hause keines!!

MfG Zsolt

Autor: Andreas K. (oldcoolman)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann auch einen Debugger verwenden.

Autor: Andreas K. (oldcoolman)
Datum:

Bewertung
0 lesenswert
nicht 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


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas K. (oldcoolman)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.