PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC16F84A - Interrupt neustarten ab main



t0b4d
14.04.2007, 18:04
Hey,

ich bins mal wieder!

Ich möchte das nach einem bestimmten Interrupt der PIC wieder bei Main anfängt!

Jetzt weis ich ja nicht wo der Interrupt aufgetreten ist, weis also auch nicht ob er in einem Unterprogramm war. Deshalb muss ich den Stack löschen und in init_end irgentwie ein GOTO main ermöglichen. Dieses darf aber nur wenn der bestimmte Interrupt ausgelöst wurde.

zB:


int_end
BTFSC int_controller,0
GOTO bestimmter_interrupt;
GOTO init_normal_end

bestimmter_interrupt
;stack und alles andere löschen! aber wie ?!
GOTO main

init_normal_end
SWAPF s_temp,w
MOVWF STATUS
SWAPF w_temp,f
SWAPF w_temp,w


BCF INTCON,RBIF
RETFIE


normaler Interrupt
http://kripserver.net/hbfi05a/clients/interrupt_normal.jpg
Interrupt den ich brauch
http://kripserver.net/hbfi05a/clients/interrupt_i_need.jpg

PICture
14.04.2007, 20:28
Hallo Tob4d!

Ich bin nicht sicher, ob ich dein Problem richtig verstanden habe. Mir ist aber etwas eigefallen, vielleicht hat es Sinn. Die Idee: der bestimmte Interrupt setzt ein Flag und in dem ganzen Programm sind eifache Prüfungen des Flags (btfsc & goto). Wenn irgendwo entdeckt wird, dass das Flag gesetzt ist, wird sofort ins Hauptprogramm gesprungen. Eigentlich sollte es funktionieren.

MfG

t0b4d
14.04.2007, 22:15
hey PICture,

auf dich ist verlass! =)

Wie siehts aber aus wenn er aus einem Unterprogramm (das mit CALL aufgerufen wurde und mit RETURN normalerweise verlassen werden muss) in die Interruptroutine kommt. Ich hab gedacht das dann im Stack etwas gespeichert ist und dann nichtmehr gelöscht wird weil ich das Unterprogramm nicht mit RETURN "schließe". Irgentwann kommt es doch dann zum Überlauf des Stacks?!


Wenn ich hier gerade dumm laber, sry ! ich weiß nichtmal was der Stack überhaupt ist. Wollt nur wissen obs ne Möglichkeit gibt das zu umgehen bzw zu vermeiden.
Das mit dem Flag wär ist gut, aber wie heißt es und vorallem wo springt er dann genau hin? ;)

PICture
14.04.2007, 23:04
Dass habe ich nicht so deteiliert durchgedacht. Ich denke aber jetzt, dass wenn das Flag gesetzt ist müssen alle Unterprogramme zum return springen, dann landet es am Ende immer im Hauptprogramm. Schaut schon besser aus, oder ? :)

Den Flag musst Du selber definieren, wie Du magst, z.B. Fret. Ich habe in jedem Programm immer mindestens ein Register "Flags" wo jeden Bit ein Flag mit #define genannt werden kann. Manchmal habe ich nur 4 Flags, aber opfere gern ein Register dafür. So wie ich sehe, mann müsste in dem in Wiki enstehendem Artikel "PIC Assembler" auch etwas über Flags schreiben.

t0b4d
14.04.2007, 23:24
oha :D selbst definieren, hört sich nach viiiel Arbeit an! Ich schau mal ob ich was dazu finde.

Wie kann ich aber diese Unterprogramme zu einem Return zwingen ? Weil bei dem Interrupt könnt ich ja dann einfach alle Unterprogramme mit dem Befehl zum Return zwingen und dann in main jumpen!

hört sich einfach an :D ist es aber bestimmt nicht ^^

kalledom
15.04.2007, 00:14
Hallo t0b4d,
aus einem Interrupt kannst Du nicht so einfach mit GOTO 'verschwinden', auch nicht mit einem RETURN.
Ein Interrupt muß immer mit RETI (Return from Interrupt) beendet werden, weil mit RETI etwas mehr passiert als mit RETURN.
Bei einem CALL wird die momentane Adresse auf den Stack gelegt und zu dem angegebenen Unterprogramm gesprungen. Jedes Unterprogramm muß mit RETURN abgeschlossen werden, weil damit die Rücksprung-Adresse vom Stack zurück geholt wird und nach der 'CALL-Stelle' weiter gemacht wird.
Bei einem Interrupt geschieht genau das Gleiche; zusätzlich werden weitere Interrupts gesperrt und bei RETI wieder freigegeben.
Wenn Interrupts oder CALLs nicht mit RETI bzw. RETURN abgeschlossen werden, werden immer mehr Rücksprung-Adressen auf dem Stack abgelegt; es kommt zu einem Stack-Überlauf und die Reihenfolge ist durcheinander. Das funktioniert nicht.
Bei einer 'sauberen' Interrupt-Service-Routine brauchst Du Dir überhaupt keine Gedanken über das Hauptprogramm zu machen; der µC macht von alleine an den richtigen Stelle weiter, sofern Du jeden Unterprogramm-Aufruf mit RETURN beendest und es zu keinem Stack-Überlauf kommt.
In der ISR kannst Du an den Interrupt-Flags, die Du teilweise sogar per Programm zurücksetzen mußt, abfragen, wer denn der 'Schuldige' ist und entsprechend verzweigen.
Achtung, die Stack-Tiefe ist auf wenige Rücksprungadressen begrenzt; Du kannst somit nicht 10 CALLs ineinander verschachteln und dann noch Interrupts aktiviert haben.
Informationen aus der ISR kannst Du über FileRegister oder Flags (Bits) an die Hauptrotine übergeben.
Z.B. kannst Du einen neuen Wert in der ISR in einem FileRegister ablegen und ein Flag setzen, daß dem Hauptprogramm mitteilt: es ist ein neuer Wert da. Im Hauptprogramm wird dann der neue Wert ausgelesen und das Flag zurück gesetzt.
Einige Assembler-Beispiele findest Du hier (http://www.domnick-elektronik.de/picasm.htm) und hier (http://www.domnick-elektronik.de/picpwm.htm).

PICture
15.04.2007, 00:27
Wieso viel Arbeit ? Es ist wirklich nichts dabei. Es geht so:

Zuerst Flags (z.B. F0 bis F7) als Bits in einem selber genanntem Register z.B. Flags definieren

#define F0 Flags,0
#define F1 Flags,1
#define F2 Flags,2
#define F3 Flags,3
u.s.w.

Danach den Register Flags definieren

Flags equ 0x37

fertig, das wars. Alles klar?

Eigentlich gibt es zwei Arten von Unterprogrammen:

1. Einfache die bestimmte Befehlsfolge ausführen und zürückspringen. Die muss man nicht zwingen.

2. Endlose Schleifen, die durch was bestimmtes (z.B. ein Tastendruck) unterbrochen werden können und dann kehren sie zurück. Ein Beispiel:

Record .................
Befehlsfolge
.................
btfsc Taste ; wenn Taste gedrückt ist das Bit Taste=0
goto Record
return

Wenn Du jetzt noch in diese Schleife eine Prüfung deines Flags z.B. F2
einfügst,

Record ................
Befehlsfolge
btfsc F2 wenn F2=1 dann Return, sonst zum btfsc Taste
return
btfsc Taste
goto Record
return

dann die eizige Änderung ist, dass die Schleife um 2 Prozessortakten länger ist.

Sag bloss, bitte, nicht, dass es viel Arbeit ist. :)

t0b4d
15.04.2007, 00:27
Schade,

einen befehl um den Stack zu löschen gibts auch nicht?!

Dann funktioniert mein Plan nicht. Muss mir was neues einfallen lassen.

<--- gilt kalledom


Die Schleife die ich nach dem Interrupt umgehen will so zu verändern hab ich mir auch schon überlegt, dachte nur das diese dann durch mein Plan sofort umgehbar wäre. Wollt es halt bissel komplizierter machen das ich vlt. auch noch was lern ;) - hab ich ja jetzt !

Dank(e), euch beiden!

just, t0b4d