2016-07-08 19 views
0

Ich verwende Interrupt-On-Change auf RC7 von PIC16LF1618. Hier ist die Initialisierung Bit, das ich für I-O-C:Interrupt-On-Change während der Laufzeit

void I_O_C_Initialize (void) { 
    INTCONbits.IOCIF = 0; 
    IOCCFbits.IOCCF7 = 0; 
    INTCONbits.IOCIE = 1; 
    IOCCP = 0x80; 
} 

Ich kann den PIC von einem Power-Down-Modus (SLEEP) mit einem positiven Trigger auf RC7 wecken. Allerdings möchte ich diesen Trigger auch während der Ausführungszeit verfügbar haben, so als ob irgendein positiver Trigger auf RC7 den PIC zurücksetzen und in die erste Zeile der main() -Funktion gehen sollte.

Könnten Sie mir bitte Bescheid geben, wie Sie dies erreichen?

P.S: Da das Zurücksetzen so schnell wie möglich erfolgen muss und für die Ausführungszeit entscheidend ist, kann ich nicht mehrere if-Anweisungen innerhalb der Hauptfunktion hinzufügen, um nach dem positiven Trigger auf RC7 zu suchen. Daher suche ich nach einer Interrupt-Option zum Zurücksetzen des PIC, auch wenn es eine Verzögerung oder Funktionsschleifen ausführt.

Dank

Antwort

0

Das Problem wurde jetzt behoben. Nach dem Aktivieren des GIE-Bits, wann immer ich den Interrupt On Change (IOC) während der Laufzeit benötigte und die unten stehende Funktion verwendete, arbeitete der IOC während der Laufzeit sowie im Power-Down-Modus (SLEEP).

void interrupt ISR (void); 

void interrupt ISR (void) { 
    if (RC7==1) { 
     asm("pagesel foobar"); 
     asm("goto foobar"); 
    } 
    else 
     return; 
} 


asm("foobar:"); 
while (1) { 
    IOCCFbits.IOCCF7 = 0; 
    INTCONbits.GIE = 1; 

    . //Do the calculations here 
    . //Here if any Interrupt On Change happens for RC7, 
    . //the ISR routine would stop all calculations and 
    . //would return to the start of the loop without 
    . //resetting any of the registers. 

    INTCONbits.GIE = 0; 
    IOCCFbits.IOCCF7 = 0; 
    SLEEP(); 
} 
0

In den meisten 8-Bit-PIC-Geräte, und vorausgesetzt, Sie XC8 verwenden, gibt es eine Definition ist, dass die erforderliche Montage Befehl ruft:

#define RESET() asm("reset") 

Also, in Ihrem Interrupt-Handler, Fügen Sie einfach diese Codezeile ein:

RESET(); 
+0

Ja, ich benutze XC8. Würde so etwas helfen? #define RESET() asm ("reset") Innerhalb der Hauptschleife: \t // Da ich die SLEEP-Funktion anrufe, sollten die GIE- und PEIE-Bits normalerweise deaktiviert sein. \t INTCONbits.GIE = ​​1; \t INTCONbits.PEIE = 1; Vor SLEEP-Funktion: \t // Deaktivieren der GIE- und PEIE-Bits, um vom SLEEP-Modus aufzuwachen \t INTCONbits.GIE = ​​0; \t INTCONbits.PEIE = 0; void interrupt ISR (void) { if (RC7 == 1) { \t INTCONbits.GIE = ​​0; \t INTCONbits.PEIE = 0; \t IOCCF = ((IOCCF^0xFF) & IOCCF); \t RESET(); } } –

+0

@ArunKumar Es sollte bereits definiert sein, also benutze 'RESET();' wo immer du in deiner Logik bist - diese Logik ist deine Wahl, ich lasse dich wissen, wie man einen Hardware-Reset des PIC erzwingt aus dem Code. In Ihrem Interrupt können Sie das entsprechende Register überprüfen, um festzustellen, ob Sie gerade aus dem Schlaf aufgewacht sind oder nicht. –

+0

Das RESET() funktioniert gut. Es macht jedoch einen kompletten sanften Neustart und ich möchte das vermeiden. Gibt es eine Möglichkeit, zu einem Label innerhalb des main() vom ISR-Interrupt zu springen? –