Hallo zusammen, Ich hab ein Problem mit meinem Code für einen Atmega48. Und zwar wird durch eine Taste eine Interrupt Routine ausgelöst, die per SPI Daten an ein Funkmodul sendet. Das tut es eigentlich auch wie gewünscht. Komischerweise scheint der Controller nach der Ausführung von EXT_INT1 einen Reset auszulösen. Denn wenn ich die Taste drücke, blinkt die Rote LED die eigentlich nur beim init (also beim Start/RESET) kurz auf, die signalisieren soll das das Funkmodul initialisiert wurde. sbi PORTB,1 rcall rfm_init cbi PORTB,1 Wenn ich die Zeile bei EXT_INT1 entferne: rcall rfm_send Läuft das Programm Normal weiter, ohne das die Rote LED blinkt. Als wird init nicht ausgeführt, was korrekt wäre. Also wäre der Fehler logischerweise in im Block rfm_send. Bis jetzt komme ich aber nicht dahinter, was genau Falsch ist am Code. Also nehme ich an, das ich etwas permanent übersehe. Darum würde ich mich freuen wenn jemand von euch den Code einmal überfliegen könnte, um mir etwas auf die Sprünge zu helfen. Ist übrigens ein Testprogramm für Komponenten auf einer Prototyp PCB. Es ist darum auch Code dabei, die mit der eigentlichen Aufgabe nichts zu tun haben (TWI, OneWire,ect)
Bin gerade am Handy, Sehr wahrscheinlich benutzt deine aufgerufenene Routine delay oder ähnliches und läuft somit in den Wächter. In der ISR ein Flag setzen und in der Main darauf reagieren. ISR: taste=1 Main: taste==1 && rfm_send() MfG
Ich kann in §rfm12_txbyte das Gegenstück zu 'pop lsb' nicht finden.
1 | rfm12_txbyte: |
2 | |
3 | ldi msb,0xB8 |
4 | rcall rfm_trans_ready |
5 | pop lsb |
Wo wird eigentlich 'lsb' (vielleicht auch unter anderem Namen?) auf dem Stack abgelegt? Oooh dazwischengemogelt ;-) sehe gerade: S. Landolt schrieb: > Gegenstück zu 'pop lsb'
:
Bearbeitet durch User
Es war tatsächlich das push lsb das gefehlt hatte! push lsb ldi msb,0xB8 rcall rfm_trans_ready pop lsb So wies aussieht hat das Fehlende push das Statusregister/Register bei pop_stock verändert, einen Fehler generiert, der den Controller in den Reset zwang. Bei der Uart Routine übringens das gleiche problem. Ironischerweise hatte ich das mal genau so mit pop/puhs wie es sein sollte gehabt, und es funktionierte auch ohne Probleme. Durch das ständige abändern des Codes beim Testen, hab ich wohl versehentlich Code gelöscht/nicht kopiert, und beim Kontrollieren übersehen. Ich sollte mehr mit Git arbeiten... Trotz allem Vielen lieben dank an die hilfreichen hinweise! Schöne Festtage!
Und ich sehe gerade, dass es mit dem Aussterben unserer Species trotz aller Unkenrufe doch noch eine Weile dauern wird.
Lukas G. schrieb: > So wies aussieht hat das Fehlende push das Statusregister/Register bei > pop_stock verändert, einen Fehler generiert, der den Controller in den > Reset zwang. So wie es aussieht, hast du den zugrunde leigenden Mechanismus noch nicht richtig durchschaut. Denn wer sollte den Controller auf welche Art "in den Reset gezwungen" haben? > So wies aussieht hat das Fehlende push ... dazu geführt, dass die Rücksprungadresse auf dem Stack falsch interpretiert wurde und beim Rücksprung dann in einen gelöschten Flashbereich mit vielen 0xFF gesprungen ist. Das 0xFF resultiert beim AVR zu einem SBRS, und weil da viele solcher SBRS hintereinander stehen, läuft der Controller munter bis ans "Ende" des Flashs und fängt "vorne" bei 0 wieder an. Und diese 0 ist ja dann auch der Resetvektor.
:
Bearbeitet durch Moderator
Das mit der Rücksprungadresse hab ich mir auch irgendwie gedacht. Im Nachhinein eigentlich Logisch, da die Adresse beim zurückspringen ja auch nicht mehr stimmt, genau wie die anderen Registerwerte die auf dem Stack liegen. Vielen dank für deine Erläuterung!
Wobei noch anzumerken wäre, dass ein Sprung zum Resetvektor nicht einem Reset entspricht - Letzterer setzt zum Beispiel die SFRs auf ihre 'initial values'.
S. Landolt schrieb: >> Das 0xFF resultiert beim AVR zu einem SBRS > ? Ignoriere mal einfach diese 0 im Bit 4, die hat nur der Assembler zu beachten, denn der darf entsprechend der Doku aus dem SBRS R31,7 kein 0xFFFF machen, sondern ein 0xFFF7. Wenn aber im Speicher ein 0XFFFF steht, dann gibt es beim AVR keinen Mechanismus, der einen Interrupt für einen "falschen Opcode" auslöst. Das Bit 4 wird da einfach ignoriert.
Hi Lothar M. schrieb: > So wie es aussieht, hast du den zugrunde leigenden Mechanismus noch > nicht richtig durchschaut. Denn wer sollte den Controller auf welche Art > in den Reset "gezwungen" haben? Nun ja, eine ISR arbeitet ähnlich, wie ein CALL. Da wird die Rücksprungadresse auf den Stack gelegt und beim RETI wieder in den Programmcounter gesschrieben. Auch die Push und Pop Befehle legen Werte auf den Stack und holen diese dort wieder ab. Zur Adressierung dient der Stackpointer, der beim Ablegen von Werten auf den Stack herunterzählt und beim Zurückholen wieder hochzählt. Der Grund für Push und POP, bei einer ISR weiß ja niemand, wann diese aufgerufen wird. So kann ein Ergebnis im Statusregister verloren gehen, wenn es nicht vor dem Ausführen von Befehlen, die das Statusregister verändern, gesichert wird. Und dies geschieht natürlich am Anfang einer ISR mit einem Push-Befehl, der erst einmal wichtige Registerinhalte sichert. Am Ende der ISR holt mal diese Werte mit POP Befehl wieder zurück und kann die ISR mit RETI verlassen. Das funktioniert solange problemlos, wie die Anzahl der POP Befehle auch der Anzahl der Push Befehle entspricht, da der Stackpointer dann auch auf die abgelegte Rücksprungadresse zeigt. Ein POP ohne ein Push holt aber einen teil der Rücksprungadresse und der Stackpointer zeigt dann auf eine Speicherstelle, die alles mögliche beinhaltet, aber nicht die sichere Rücksprungadresse. Daher fängt aller Wahrscheinlichkeit dein Programm wieder bei Null an. Gruß oldmax
Lothar M. schrieb: > Wenn aber im Speicher ein 0XFFFF steht, dann gibt es beim AVR keinen > Mechanismus, der einen Interrupt für einen "falschen Opcode" auslöst. > Das Bit 4 wird da einfach ignoriert. So sieht's aus. Und das gibt's/gab's bei vielen µC/µP, nennt sich typischerweise "undokumentierte Opcodes". Ist hier aber nur die leichte Form davon, nämlich eine simple Doublette. Es gibt halt mehr als einen möglichen Opcode für eine konkrete Operation. Dank der hohen "Dichte" des AVR8-Instructionset gibt es im Vergleich zu anderen µC/µP nur recht wenige dieser "undokumentierten Opcodes" und davon sind wiederum sehr viele einfach nur Doubletten.
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.