Ich habe ein besonderes Problem mit dem Timer auf dem DSPIC33F. Ich muss eine Verzögerungsfunktion erstellen und habe mich entschieden, Timer 2 zu verwenden, um die Anzahl der Befehlszyklen zu zählen. Die Funktion würde den Timer aktivieren und dann in der While-Schleife darauf warten, dass das Interrupt-Flag gesetzt wird. Siehe Code unten:
T2CONbits.TON = 0; // disable Timer 2
IFS0bits.T2IF = 0; // reset Timer 2 interrupt flag
TMR2 = 0; // reset timer accumulator
T2CONbits.TON = 1; // enable Timer 2
while(!IFS0bits.T2IF); // Wait until until the timer 2 timeout
IFS0bits.T2IF = 0; // reset Timer 2 interrupt flag
T2CONbits.TON = 0; // disable Timer 2
Die Funktion funktioniert einwandfrei, wenn die TMR2-Interrupts deaktiviert sind. Wenn jedoch die TMR2-Interrupts aktiviert sind, startet die Firmware neu, wenn das Interrupt-Flag gesetzt ist. Dieser Neustart passiert nur, wenn ich den Code durchlaufe, aber nicht während der schrittweisen Ausführung (ich verwende den ICD3 mit MPLab 8.irgendwas). Ich habe die ISR für TMR2 nicht eingerichtet. Alle anderen Interrupts sind deaktiviert.
Obwohl ich mein Ziel, die Verzögerungsfunktion zu erstellen, erreicht habe, frage ich mich immer noch nach den möglichen Gründen für den Firmware-Neustart. Liegt das daran, dass ich das Interrupt-Flag aus irgendeinem Grund nur innerhalb der ISR ansprechen kann? Oder gibt es andere Gründe?
Seite 2 in der PIC33f-Interrupts-Familienreferenz zeigt, wie der Interrupt-Prozess für den dsPIC33f funktioniert:
http://ww1.microchip.com/downloads/en/DeviceDoc/70300C.pdf
Wenn Sie einen Interrupt (z. B. T2IE) aktivieren und der Interrupt ausgelöst wird, geht er an die Adressstelle, die im peripheren Interrupt-Vektor gefunden wird. Wenn Sie keine gültige Adresse für das Peripheriegerät definiert haben, hat der Peripherie-Interrupt-Vektor eine unbekannte Adresse (vielleicht 0) und wenn der Interrupt ausgelöst wird, geht er an diese Adresse und es können unvorhersehbare Dinge passieren
In Ihrem Fall wird das ALTIVT-Bit (INTCON2<15>) gelöscht, wenn der TMR2-Interrupt ausgelöst wird, wird es an die Adresse gehen, die in 0x000022 gefunden wird.
wenn du schreibst:
void __attribute__((__interrupt__, auto_psv)) _T2Interrupt (void)
{
}
Sie sagen Ihrem Compiler tatsächlich, dass Sie die Adresse des Anfangs dieses Codes an Adresse 0x000022 (TMR2 IVT-Adresse) platzieren möchten.
und wenn du schreibst:
void __attribute__((__interrupt__, auto_psv)) _AltT2Interrupt (void)
{
}
Sie sagen Ihrem Compiler, dass er die Adresse des Anfangs dieses Codes an Adresse 0x000122 (TMR2 AIVT-Adresse) platzieren soll.
Adam Lawrence
udushu
Adam Lawrence