-
        

Ergebnis 1 bis 8 von 8

Thema: PIC16F84A - Interrupt neustarten ab main

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    07.01.2007
    Beiträge
    27

    PIC16F84A - Interrupt neustarten ab main

    Anzeige

    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:
    Code:
    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

    Interrupt den ich brauch

  2. #2
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.969
    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

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    07.01.2007
    Beiträge
    27
    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?

  4. #4
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.969
    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.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    07.01.2007
    Beiträge
    27
    oha 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 ist es aber bestimmt nicht ^^

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    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 und hier.
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

  7. #7
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.969
    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.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    07.01.2007
    Beiträge
    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

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •