PIC Multiple Timer Interrupt Problem

Discussion in 'Embedded Systems and Microcontrollers' started by saneeshforu, Feb 22, 2014.

  1. saneeshforu

    Thread Starter New Member

    Feb 22, 2014
    6
    0
    Haii all I have a problem related with Microc PIC IDE (v8.2)
    I have 2 timer interrupts(tmr2,tmr1) in my program..like this..
    Code ( (Unknown Language)):
    1.  
    2. void interrupt(){
    3.    if (PIR1.TMR1IF) {
    4.  PIR1.TMR1IF=0;
    5.   cnt++ ;
    6.   TMR1H = 0x80;
    7.   TMR1L = 0x00;
    8.    }
    9. else if(PIR1.TMR2IF)
    10.   {
    11.    PIR1.TMR2IF=0;
    12.    cnt2++ ;
    13.    TMR2  =   0;
    14.     }     }
    15.  
    But when Timer 2 Enables (PIE1.TMR2IE = 1) ,both of two interrupts(cnt and cnt2) get incremented ...why ?/

    MY WHOLE PROGRAM IS THE BELOW ONE

    Code ( (Unknown Language)):
    1.  
    2. unsigned short cnt;
    3. unsigned short cnt2;
    4.  
    5.  
    6.  void interrupt(){
    7.  
    8.    if (PIR1.TMR1IF) {
    9.  
    10.  PIR1.TMR1IF=0;
    11.   cnt++ ;
    12.   TMR1H = 0x80;
    13.   TMR1L = 0x00;
    14.  
    15.    }
    16.  
    17. else if(PIR1.TMR2IF)
    18.  
    19.   {
    20.    PIR1.TMR2IF=0;
    21.    cnt2++ ;
    22.    TMR2  =   0;
    23.  
    24.    }
    25.  
    26.      }
    27.  
    28.   void main()
    29. {
    30.   ANSEL  = 0;            // Configure AN pins as digital I/O
    31.   ANSELH = 0;
    32.   TRISB = 0xFF;          // set PORTB to be input
    33.    TRISE = 0;
    34.   TRISD = 0;             // set PORTD to be output
    35.   PORTD = 0x00;
    36.   PORTE=0X00;          // initialize PORTD
    37.            
    38.  
    39.   T1CON = 1;
    40.   T2CON = 0xFF;               // Timer2 settings
    41.   TMR2  =   0;                // Initialize Timer2 register
    42.    TMR1H = 0x80;               // Initialize Timer1 register
    43.    TMR1L = 0x00;
    44.   INTCON = 0xC0;
    45.   PIE1.TMR2IE = 1;
    46.   PIE1.TMR1IE  = 0;
    47.    PIR1.TMR1IF=0;
    48.   cnt=0;
    49.   cnt2 = 0;
    50.    PIR1.TMR2IF=0;
    51.  
    52.  for(;;)
    53.  {
    54.  
    55.  if(cnt==61)
    56.  
    57.    {
    58.      PORTE=~PORTE;
    59.      cnt=0;
    60.      }
    61.      
    62.    else  if (cnt2==160)
    63.    {
    64.       PIE1.TMR2IE = 0;
    65.       PIE1.TMR1IE  = 1;
    66.       cnt2=0;
    67.       cnt=0;
    68.  
    69.       PORTD=~PORTD;
    70.     }
    71.      
    72.  }
    73. }
    74.  
     
    Last edited by a moderator: Feb 23, 2014
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    988
    Please use code tags when posting code:

    Code ( (Unknown Language)):
    1.  
    2. void interrupt(){
    3.      if (PIR1.TMR1IF) {
    4.         PIR1.TMR1IF=0;
    5.         cnt++ ;
    6.        TMR1H = 0x80;
    7.        TMR1L = 0x00;
    8.     }
    9.   else if(PIR1.TMR2IF)
    10.   {
    11.       PIR1.TMR2IF=0;
    12.       cnt2++ ;
    13.       TMR2 = 0;
    14.   }
    15. }
    16.  
    Set a breakpoint inside your if (PIR1.TMR1IF) block to be certain that code is being reached.


    Also try initializing PIR1.TMR1IF to 0 at the start of your code in main() PIR1.TMR1IF=0;
     
    saneeshforu likes this.
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Hit the HELP button on your compiler and find the section for "Using MPLAB® Simulator"

    Follow the directions there so you can watch while the computer traces thru your code.

    Additionally, I doubt the "else if" in your interrupt is correct. It should be a straight "if" statement.
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,339
    1,021
    In the interrupt routine, don't use if-else, the interrupts are not related and need to be processed as individual events, not one excluding the other. EDIT: As ErnieM said, too.

    Since interrupts get disabled/enabled in the code, you have to test the interrupt enable, TMRxIE, as well as the TMRxIF in the service routine. The timers continue to run, setting IF even though the interrupt is disabled. Once in the interrupt routine (from the other timer) that stray IF flag will be processed.

    Try something like this:
    Code ( (Unknown Language)):
    1. void interrupt(){
    2.  
    3.     if (PIR1.TMR1IE)        // process TMR1 interrupt when IE && IF
    4.         if (PIR1.TMR1IF) {
    5.             PIR1.TMR1IF=0;
    6.             cnt++ ;
    7.             TMR1H = 0x80;
    8.             TMR1L = 0x00;
    9.         }
    10.  
    11.      if(PIR1.TMR2IE)
    12.         if(PIR1.TMR2IF){    // process TMR2 interrupt when IE && IF
    13.             PIR1.TMR2IF=0;
    14.             cnt2++ ;
    15.       //      TMR2  =   0;  unnecessary. TMR2 resets to 00h when it equals PR2
    16.         }
    17.  
    18.  }//interrupt
    Finally, you need to set PR2 in init since TMR2IF is generated on a match of TMR2 and PR2, scaled by the postscaler. Its a good idea even if you expect to use the default reset value. I had to look it up myself.
     
    Last edited: Feb 23, 2014
    saneeshforu likes this.
  5. saneeshforu

    Thread Starter New Member

    Feb 22, 2014
    6
    0
Loading...