Searching \ for '[PIC] timer0 interrupt accuracy problem' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'timer0 interrupt accuracy problem'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] timer0 interrupt accuracy problem'
2006\02\26@041452 by Gökhan SEVER

picon face
I'm trying to grasp the functionality of tmr0 interrupt.

I have written a basic tmr0 interrupt based c code. (I used hi-tech picc
compiler in my testings)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <htc.h>

__CONFIG(XT & WDTDIS);

void interrupt tmr0_isr (void) {
   RB0 ^= 1;
   T0IF = 0;
   TMR0 = 255;
}

void main (void) {

   PSA = 1;            // prescalar assigned to the WDT
   T0CS = 0;            // select internal clock
   T0IE = 1;            // enable timer interrupt
   GIE = 1;            // enable global interrupts

   TRISB0 = 0;
   RB0 = 0;

   TMR0 = 255;       // Load the tmr0 for the minimum interrupt rate

   while(1);

}

// All the calculations are based on 4 MHZ XT.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Above i would expecting the toggle rate of RB0 is about 1 us  + 2us (synch
cycles) + a few more for interrupt latency which is totally about 5 us. But
when i tested the rate with MPLAB stopwatch i get an interrupt at each 18us.
So the tmr0_init_value = 256 - (delay_time * clock_freq/4) dont work with my
tmr0 calculations. (assumed no prescaler).

So where am i misunderstanding, is this the problem of c compiler or me?

2006\02\26@103019 by Tech

flavicon
face
{Quote hidden}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////
>
> Above i would expecting the toggle rate of RB0 is about 1 us  + 2us (synch
> cycles) + a few more for interrupt latency which is totally about 5 us. But
> when i tested the rate with MPLAB stopwatch i get an interrupt at each 18us.
> So the tmr0_init_value = 256 - (delay_time * clock_freq/4) dont work with my
> tmr0 calculations. (assumed no prescaler).
>
> So where am i misunderstanding, is this the problem of c compiler or me?

There's over-head for bank switching, moving things around, and GIE will
not be re-enabled until exit from your interrupt on RETFIE.

In MPLAB click View, Program Memory to see the assembler generated
by your C compiler.

 0000              CLRF STATUS
 0001              MOVLW 0
 0002              MOVWF PCLATH
 0003              GOTO 0x14

 0004              MOVWF 0x70               ;<-- int vector
 0005              MOVF STATUS, W
 0006              CLRF STATUS
 0007              MOVWF 0x20
 0008  tmr0_isr    BCF STATUS, 0x5
 0009              MOVLW 0x1
 000A              XORWF PORTB, F
 000B              BCF INTCON, 0x2
 000C              MOVLW 0xff
 000D              MOVWF TMR0
 000E              BCF STATUS, 0x5
 000F              MOVF 0x20, W
 0010              MOVWF STATUS
 0011              SWAPF 0x70, F
 0012              SWAPF 0x70, W
 0013              RETFIE  '<-- interrupts disabled until here

 0014              CLRF STATUS
 0015              GOTO main

 03F5  main    BSF STATUS, 0x5
 03F6              BSF TMR0, 0x3
 03F7              BCF TMR0, 0x5
 03F8              BSF INTCON, 0x5
 03F9              BSF INTCON, 0x7
 03FA              BCF PORTB, 0
 03FB              BCF STATUS, 0x5
 03FC              BCF PORTB, 0
 03FD              MOVLW 0xfe
 03FE              MOVWF TMR0
 03FF              GOTO 0x3ff

Regards,

Bruce

2006\02\27@025020 by Michael Rigby-Jones

picon face


{Quote hidden}

You are missing the overhead of the context save which is invisible from the source code.  The compiler has to put in code to save the W and status registers (at a minimum).

Why are you trying to get such high frequency interrupts anyway? This will be tying up pretty much 100% CPU time, so anything in your main loop is not going to get run, or best case it will get run very slowly.  There's probably a better way of doing things if you describe the overall problem you are trying to solve.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2006\02\27@040402 by Gökhan SEVER

picon face
What i trying to achieve is produce 3 software pwm's. At last i've grasped
that my first method sucks nearly all the cpu time. Now i've changed it to
classic loop method.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
for(;;) {

   /* if PWM counter rolled over then set all outputs high */
   if( ++pwm_counter == 0 ) {
     PORTB |= 0x07;
   }

   /* compare counter against duty cycle variables */
   if (pwm_counter == pwm_duty_cycle0) {
     RB0 = 0;
   }
   if (pwm_counter == pwm_duty_cycle1) {
     RB1 = 0;
   }
   if (pwm_counter == pwm_duty_cycle2) {
     RB2 = 0;
   }

   }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

In this configuration i can produce minimum 4ms pwm period with 8-bit
resolution.  Is there any fancy way to achieve higher resulation and lower
pwm periods with 4 Mhz XT?

2006\02\27@081319 by Dave Tweed

face
flavicon
face
<gstr2005spamKILLspamgmail.com> wrote:
> What i trying to achieve is produce 3 software pwm's. At last i've grasped
> that my first method sucks nearly all the cpu time. Now i've changed it to
> classic loop method.
>
> In this configuration i can produce minimum 4ms pwm period with 8-bit
> resolution. Is there any fancy way to achieve higher resulation and lower
> pwm periods with 4 Mhz XT?

On a PIC18F, you can get the loop down to 8 instructions and 9 cycles, for
a PWM period of 1e-6*9*256 = 2.3 ms:

loop:
       cpfsgt  pwm_duty_cycle0         ; 1
       bcf     latb, 0                 ; 1
       cpfsgt  pwm_duty_cycle1         ; 1
       bcf     latb, 1                 ; 1
       cpfsgt  pwm_duty_cycle2         ; 1
       bcf     latb, 2                 ; 1
loop_1:
       incf    wreg, w                 ; 1 1
       bnz     loop                    ; 2 1

       bsf     latb, 0                 ;   1
       nop                             ;   1
       bsf     latb, 1                 ;   1
       nop                             ;   1
       bsf     latb, 2                 ;   1
       bra     loop_1                  ;   2

Note that the NOPs balance the execution time regardless of which way the
bnz goes, and also eliminate the small timing skew among the three output
channels.

Going to more than 8 bits of resolution on an 8-bit processor is going to
cost you a lot in terms of PWM period.

-- Dave Tweed

2006\02\27@083331 by Gerhard Fiedler

picon face
Gökhan SEVER wrote:

> What i trying to achieve is produce 3 software pwm's.

> In this configuration i can produce minimum 4ms pwm period with 8-bit
> resolution.  

With your method, the PWM period depends on the loop instructions, and on
the conditional paths in the loop. May or may not matter. You also may not
have interrupts enabled, as they would screw this up completely. And you
can't do anything else (or you need to make sure that the outputs are in a
state where you can tolerate the PWM generation being "on hold", so to
speak, while you're doing something else.

Some of these problems you can avoid by placing the code in a timer
interrupt.

> Is there any fancy way to achieve higher resulation and lower pwm periods
> with 4 Mhz XT?

Since what you did in your loop is about the minimum that has to be done
for PWM (the three ifs possibly could be optimized somewhat, possibly also
the generated assembly), it can't be much faster. Is there anything that
ties you to 4 MHz?

Gerhard

2006\02\27@084116 by Michael Rigby-Jones

picon face


{Quote hidden}

Arrgh, don't go there.  The OP originaly had his PWM code in a timer interrupt, but actually ran through all 256 PWM counts each time the interrupt fired so the PIC spent all it's time in the ISR.

The basic problem is that the PIC isn't really fast enough to get the desired PWM period and resolution when using C.  This is a job for assembler IMO, especialy as the OP wants to integrate a soft-UART into the project.  More details on the HiTech forums!

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2006\02\27@125309 by Gerhard Fiedler

picon face
Michael Rigby-Jones wrote:

> Arrgh, don't go there.  The OP originaly had his PWM code in a timer
> interrupt, but actually ran through all 256 PWM counts each time the
> interrupt fired so the PIC spent all it's time in the ISR.

You don't have to do that... with three outputs, only 4 interrupts max per
period are necessary. Which way to go depends a lot on the rest of the
requirements (which are not mentioned).

Gerhard

More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...