Hallo, ich bin der Anfanger in Thema PIC-Programmierung. Ich habe eine Interrupt-Prozedur erzeugt, die 2 Typen der Interrupts bedienen muss, und zwar Interrupt von Timer0 und von Timer1. Problem ist dass ich unterscheiden kann nicht, welches Interrupt augetretten ist, weil beide Flags TMR0IF und TMR1IF immer zu 1 eingesetzt sind. Ich dachte dass entweder TMR0IF oder TMR1IF eingesetzt ist. Wahrscheinlich verstehe ich etwas nicht und mache die Sachen nicht korrekt. Bitte um Hilfe! Danke, Jack. Hier mein Source-Code: void interrupt isr(void) { if (TMR0IF) // interrupt from Timer0 { // do something... TMR0IF = 0; // finally clear interrupt flags -> ready for next interrupt } if (TMR1IF) // interrupt from Timer1 { // ERROR: this handler is also called because TMR1IF is always 1, too! TMR1IF = 0; } }
hallo arbeitest du mit winavr? wenn ja, geht der aufruf eines interrupts bei mir so: interrupt (xxxx) oder signal (xxxx) aber ich arbeite mit avr´s, da weis ich nicht obs anders ist mit pic´s
AVR's kenne ich gar nicht :( Seit 2 Wochen lerne ich PIC und hier habe ich dieses Problem mit Interrupts...
Deine ISR ist so weit OK. Wenn beide Interruptflags gesetzt sind, sind höchstwahrscheinlich auch beide Timer übergelaufen.
Hallo, du mußt bei einem Interrupt die einzelnen Bit´s abfragen, ob sie gesetzt sind um dann zu verzweigen. Wenn du mit deiner Routine fertig bist, sind die entsprechenden Interruptbit´s (TMR0IF, TMR1IF) zu löschen. Das muss man Softwaretechnisch machen. Gruß Erhard
@Erhard na, exakt das macht er doch: if (TMR0IF) <---- Abfrage { TMR0IF = 0; <---- Flag löschen } if (TMR1IF) <---- Abfrage { TMR1IF = 0; <---- Flag löschen }
> Und wie sind die Timer konfiguriert?
Also, Timer0 hat die Periode ganz ändere als Timer1 und es sollte nicht
sein, dass beide Timers immer übergelaufen sind. Die Timers
konfiguriere ich in ISR weil ich damit 2 PWMs emuliere.
if (TMR0IF) // interrupt from Timer0 - switch from low to high (start
new period and duty cycle)
{
// first emulated PWM
if (bDuty0)
{
RB0 = 0; // signal low on output
TMR0 = 256 - (unsigned int)(0.00095000 * XTAL) / (unsigned
int)(TIM0_PRESCALER * 4);
}
else
{
RB0 = 1; // high
TMR0 = 256 - (unsigned int)(0.00005000 * XTAL) / (unsigned
int)(TIM0_PRESCALER * 4);
}
bDuty0 = !bDuty0;
TMR0IF = 0; // finally clear interrupt flags -> ready for next
interrupt
}
// TMR1_value = 65536 - period * clock / (prescaler * 4)
if (TMR1IF)
{
// second emulated PWM
if (bDuty1)
{
RB1 = 0; // low on output
uiDelay = 65536 - (unsigned int)(0.00099000 * XTAL) /
(unsigned int)(TIM1_PRESCALER * 4);
}
else
{
RB1 = 1; // high
uiDelay = 65536 - (unsigned int)(0.00001000 * XTAL) /
(unsigned int)(TIM1_PRESCALER * 4);
}
TMR1L = uiDelay & 0xFF;
TMR1H = uiDelay >> 8;
bDuty1 = !bDuty1;
TMR1IF = 0;
}
Überprüfe das Ganze doch mal im Simulator. Vor allem ob die Flags richtig zurückgesetzt werden.
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.