Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F877A (timer1) accurate timing question

Status
Not open for further replies.

micro571

New Member
I've got the timer1 interrupt working. It's a 16 bit timer. I'm using a 20MHz oscillator.

I'd like to have a variable micros that keeps track of how long the program has been running. I'd like 10uS resolution.

Using this calculator: **broken link removed**
I found that I can get a 10uS timer period by setting the pre-scalar to 1:1 and timer offset to 0xffcd.

Code:
unsigned long micros = 0;

void interrupt isr(void){
	if((TMR1IE)&&(TMR1IF)){
		TMR1H = 0xff;  //TIMER OFFSET FOR 10uS Period
		TMR1L = 0xcd; //TIMER OFFSET FOR 10uS Period
		micros+=10;
		TMR1IF=0;	// clear event flag
	}
}

Questions:
- Am I doing this correctly, by setting the TMR1H and TMR1L values in the ISR or there a better way to do this?
- Do I need to account for the (time) length of the ISR to get an accurate count for my micros variable? If so, what should I set my timer period to (ie, 9.8uS or something)?
 
You can get much greater accuracy by using the PWM module in Special Event Trigger mode. In this mode CCPR1H/L act as an interval timer for timer1 and so you get a resolution of 200nS without having to update any registers. I have example code somewhere if it helps.

Edit, just noticed you stated 10uS - not 10mS as I thought. This is tricky as 10uS is only 50 instructions and so any interrupt will tie up most of the processors time.

Mike.
 
Last edited:
If you want to get an accurate period with TIMER1, you can subtract a constant (instead of just reloading) from the TMR1 count - this takes into account varying interrupt latencies.

Better still, you can use TIMER2 which allows you to set the period once and you're guaranteed accurate time (so long as the ISR triggers properly). The ISR is simplified. Also, you don't need to check TMR2IE if it's always going to be enabled.
Code:
void interrupt(){
   if(TMR2IF){
      micros+=10;
      TMR2IF = 0;
      }
   }
 
Dougy,

Did you know you can also set the period for timer1 with full 16 bit accuracy? If you want an interrupt every 47371 cycles then timer1 can do it - completely automatically. Check out the Special Event Trigger of the CCP module.

Mike.
 
To get the performance I need, I might have to use a delay in a loop then.

Is there a way for me to see how long a certain code segment takes to run?

I could toggle a pin, run then code, and toggle the pin again and look at the response on an oscilloscope, but is there an easier way?

Edit: Fixed typo.
 
Last edited:
Did you know you can also set the period for timer1 with full 16 bit accuracy? If you want an interrupt every 47371 cycles then timer1 can do it - completely automatically. Check out the Special Event Trigger of the CCP module.

No, I was completely ignorant; never used CCP (or read about it). Looks very handy.
 
Dougy,

Did you know you can also set the period for timer1 with full 16 bit accuracy? If you want an interrupt every 47371 cycles then timer1 can do it - completely automatically. Check out the Special Event Trigger of the CCP module.

Mike.

You know I'd never noticed that feature, learn something new every day.

Better still, it's just what I need for something I'm working on at the moment that uses the ADC :)
 
Geko,

On some chips the Special Events Trigger can also start the ADC for you when the period times out. On the 16 series it is only available on CCP2.

Mike.
 
Handy? Just bloody handy? It's bloody fantastic.

Said in best Monty Python voice.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top