SparkFun Forums 

Where electronics enthusiasts find answers.

General project discussion / help
Did you make a robotic coffee pot which implements HTCPCP and decafs unauthorized users? Show it off here!
By emalper
#194628
Hi guys how can i calculate the timer overflow for timer1 on pic16f877a in my code?
Code: Select all
sbit LED at RB0_bit;
void interrupt() {
  time++ ;
  if (time == 100) {          // if time is 76
      LED  = ~LED;        // then toggle led and
      time = 0;                // reset time
      }
  PIR1.TMR1IF = 0;            // clear TMR1IF
  TMR1H = 128;
  TMR1L = 0;
}
void main() {
  PORTB = 0x00;               // Initialize PORTB
  TRISB = 0;                  // PORTB is output
  T1CON = 1;                  // Timer1 settings
  PIR1.TMR1IF = 0;            // clear TMR1IF
  TMR1H = 0x80;               // Initialize Timer1 register
  TMR1L = 0x00;
  PIE1.TMR1IE  = 1;           // enable Timer1 interrupt
  time =   0;                  // initialize cnt
  INTCON = 0xC0;              // Set GIE, PEIE
  do {

    } while (1);
}
User avatar
By phalanx
#194659
Your basic formula to calculate an overflow is: Count / ((Fosc/4)/Prescaler). Keep in mind that since the interrupt is triggered when 0xFFFF rolls to 0x0000, you need to add 1 to the difference of 0xFFFF and your value loaded into the timer register. In your case Count = (0xFFFF - 0x8000)+0x1 = 0x8000 or 32768 in decimal.

Your overflow time will be relative to the clock frequency of your PIC. Assuming you have a 4Mhz clock, your timer will overflow in: 32,768/((4,000,000/4)/1) = 32,768/1,000,000 = 0.032768 seconds or about 30.5Hz.

Your actual interval will be slightly longer since you have overhead in your ISR prior to clearing TMR1L back to zero. Immediately upon entering your ISR, you can set TMR1H to 0x80 before TMR1L has a chance to overflow so you end up with exactly the same periodic rate since no counts are lost by resetting it to zero. After doing that, then you can run your IF routine. Ideally you would have your ISR set a flag bit in a variable and immediately exit to indicate to your main() loop that processing related to your LED counter is necessary. That way as your program gets more complex, you can have lots of interrupts occurring with a reduced risk of latency.

As a final note, you need to clean up how you initialize your timers. It's good practice to clear your timer control register in one instruction, configure it in another, and turn it on with a third.

-Bill