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!
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.
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
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
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.
> 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...
...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.
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
@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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.