Forum: Mikrocontroller und Digitale Elektronik PIC-Interrupt für Timer0 und Timer1


von Jack (Gast)


Lesenswert?

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;

   }


}

von Michael (Gast)


Lesenswert?

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

von Jack (Gast)


Lesenswert?

AVR's kenne ich gar nicht :( Seit 2 Wochen lerne ich PIC und hier habe
ich dieses Problem mit Interrupts...

von ElMachel (Gast)


Lesenswert?

hallo

welchen Compiler und welchen PIC benutzt du?

von Jack (Gast)


Lesenswert?

Compiler ist Hi-Tech C Compiler (aufgerufen von MPLAB IDE 7.10) und PIC
ist 16F873A

von Chief Brady (Gast)


Lesenswert?

Und wie sind die Timer konfiguriert?

von Steffen (Gast)


Lesenswert?

Deine ISR ist so weit OK. Wenn beide Interruptflags gesetzt sind, sind
höchstwahrscheinlich auch beide Timer übergelaufen.

von Erhard (Gast)


Lesenswert?

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

von Chief Brady (Gast)


Lesenswert?

@Erhard

na, exakt das macht er doch:

  if (TMR0IF)       <---- Abfrage
   {
      TMR0IF = 0;   <---- Flag löschen
   }

   if (TMR1IF)      <---- Abfrage
   {
      TMR1IF = 0;   <---- Flag löschen
   }

von Jack (Gast)


Lesenswert?

> 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;


   }

von Steffen (Gast)


Lesenswert?

Ü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
Noch kein Account? Hier anmelden.