Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC 16F877A Timer 0 interrupt service routine

Status
Not open for further replies.

vinctal

Newbie level 4
Joined
Oct 13, 2016
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
76
Hi, I am new in Microcontroller programming. I wish to investigate the duration taken to execute Timer 0 Interrupt.


Port RB1 is set to high upon entering interrupt service routine and Port RB0 is being toggled every time when Timer 0 Interrupt occurs. So RB0 output is being monitored to check the interval between Timer 0 Interrupt occurs whilst RB1 is being monitored to check the duration taken to execute the interrupt service routine.

The Interrupt Time is set to 55.6 us. However the simulation results in proteus show that the Interrupt time (RB0) is about 60 us...
Can anyone help to explain ?


Thanks



timer0.pngTimer0_1.png

//--------------------------------------------------------------------------------------------------------------------------------------------------


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <htc.h>
__CONFIG (FOSC_HS & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF);
#define _XTAL_FREQ 20000000
 
void interrupt ISR( )
{
     RB0 = !RB0;
     RB1 = 1;
  
        if (TMR0IF) //Timer 0 interrupt, occurs when 'Timer 0 counter' = TMR0
        
         {
            TMR0IF = 0; //Clear interrupt flag bit
            TMR0=117; 
         }
     RB1 = 0;         
    
 
}
 
 
void main(void)
{
TRISA=0b00000000;
PORTA=0b00000000;
TRISB=0b00000000;
PORTB=0b00000000;
TRISC=0b00000000;
PORTC=0b00000000;
TRISD=0b00000000;
PORTD=0b00000000;
 
//TIMER 0 INTIALIIZE
//Prescaler 1:2; TMR0 Preload = 117; Actual Interrupt Time : 55.6 us
  OPTION_REG = 0x80;
  TMR0       = 117;
  INTCON     = 0xA0;
 
while(1)
{
               
}
 
}



//--------------------------------------------------------------------------------------------------------------------------------------------------
 
Last edited by a moderator:

the compiler has some instruction to do between firing interrupt and beginning of isr
you have some instructions between toggling RB0 and resetting the timer to TMR0=117;
55.6us is the time period between TMR0=117; and firing the interrupt
if you want precise simulation use MPLAB debugger stopwatch to monitor exactly what happens
 

Hi,

I'm not familiar with PICs.

If you need precise 55.6us then you have to setup the timer in a different way.
In a way that the timer hardware automatically starts with "117" and you don't have to set it every time within the ISR.

The effect is, that the execution of the ISR is delayed a short time, but the next ISR is also delayed and therefore you see exact (averaged) 55.6us. Jitter in the range of some instruction times may occur.

Klaus
 

The traditional way of getting exact timing from this type of timer (i.e. one that does not reset itself when it overflows) is to remember that the counter will still 'tick' after the overflow.
As mentioned above, the processor will take a bit of time to respond to the interrupt and also there is pre-amble code that you may not see in the ISR that must also be taken into account.
Therefore, what you do is to use the calculated value (117 in your case) and "add" the count that is actually in the TMR0 register before putting the result back into TMR0. (You 'add' because the counter counts up and overflows when it reaches 0xff. If the TMR0 register has a value of (say) 5 when you want to reset it, then the value it needs for an accurate time interval is 117 + 5 or 122.)
An alternative is to use Timer 2 on that device as it has a PRx register and the timer will automatically reset it self correctly without any need for the type of calculation you need for Timer 0 and Timer 1 (on that device).
Susan
 

Hi,

Even better - because it adds no errors - is to simply allways add 117 to the compare register.

117, 234, 351, 468, 585 ....

Klaus
 

Klaus - the problem is that on that particular device, Timer 0 (and Timer 1 which is a 16-bit timer) both have the timer count register only - there is no comparison register. (In the data sheet see Figure 5-1 for Timer 0 and Figure 6-2 for Timer 1.) Therefore the technique that I first described is the 'standard' way to get these timers to provide the required regular interrupt period.
However Timer 2 DOES have the comparison register (PR2) which lets you set that to a single value and the timer will interrupt (and reset back to zero) when the comparator detects a match (between TMR2 and PR2). (See Figure 7-1 in the data sheet for Timer 2.) Also having the comparison register means that you don't have to change it unless you want a new interval.
Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top