32 bit Interrupt timer on PT0, 9s12dg128

Started by blewis999 March 24, 2006
I have a working 16 bit timer but now find that at low freq's we are 
getting overflow so I need to go to a 32 bit timer interrupt driven. 
Of course the ECT is 16 bit, so is this as simple as implementing an 
interrupt on the timer overflow and  adding 10000 to a time count each 
time and then finally adding the capture timer to the 32 bit count on 
the final edge?

I have to also drive a pin with the same freq captured and I am not 
sure of the sync issues. How do you use the input timer over flow 
interrupt while, driving the output and also needing the overflow flag 
to track a similiar 32 bit number. The overflow flag has to be cleared 
  so wouldn't that mess up the other timer?

Or is there a better way to do this?

Thanks in advance for the suggestions.

Bob Lewis
	
>I have a working 16 bit timer but now find that at low freq's we are
> getting overflow so I need to go to a 32 bit timer
interrupt driven.
> Of course the ECT is 16 bit, so is this as simple as implementing an
> interrupt on the timer overflow and  adding 10000 to a time count each
> time and then finally adding the capture timer to the 32 bit count on
> the final edge?

IMO it doesn't make sense to use TOV interrupt to generate long pulses or 
periods. It's way easier to count 16bit overflows in TCx interrupts.
	setup_for_long_delay()
{
   TCx= t0 + loword(ticks);
   if(hiword(ticks) ==0) {TCTL=} // in case ticks < 2^16 next OC event is
                                                    // the target event
   clearTCxflag();
}

TCxISR()
{
    // don't update TCx, just clear flag, and interrupt will fire every 
0x10000 ticks

   if(hiword(ticks)) hiword(ticks) = hiword(ticks) - 1; // overflows counter
   if(hiword(ticks) ==0) {TCTL=}    // after overflows counter reached 0 - 
next OC
                                                        // event will be the 
target event
    clearTCxflag();
}
	Above pseudocode is oversimplified. loword(ticks) close to 0 are 
troublesome. Interrupts latency or code execution time may make your 
flagclear() too late. In case ticks&0xffff is very small I do divide 
overflow period (2^16) into two halves and generate first interrupt at 
t0+(0x8000+loword(ticks)), second interrupt at TCx+0x8000, further 
interrupts (if any) every TCx+0x10000.

char overhead;
#define minOCxperiod nnn

setup_for_long_delay()
{
   if(loword(ticks)<minOCperiod)
  {
      overhead=1;
      TCx = t0 + (0x8000 + loword(ticks));
   }
   else
   {
       overhead=0;
      TCx= t0 + loword(ticks);
   }
   if(hiword(ticks) ==0  && !overhead) {TCTL=}
                                         // in case ticks < 2^16 next OC 
event is
                                         // the target event
   clearTCxflag();
}

TCxISR()
{
   if(overhead) TCx +=0x8000;

   if(hiword(ticks)) hiword(ticks) = hiword(ticks) - 1; // overflows counter
   if(hiword(ticks) ==0) {TCTL=}    // after overflows counter reached 0 - 
next OC
                                                        // event will be the 
target event
    clearTCxflag();
}
	>
> I have to also drive a pin with the same freq
captured and I am not
> sure of the sync issues. How do you use the input timer over flow
> interrupt while, driving the output and also needing the overflow flag
> to track a similiar 32 bit number. The overflow flag has to be cleared
>  so wouldn't that mess up the other timer?
	HC11 pink book has good example how to measure long periods.
(http://www.freescale.com/files/microcontrollers/doc/ref_manual/M68HC11RM.pdf)

IMO that's the only application for TOV interrupt ( to count >16bit ticks 
from one IC event to another IC event).
	>
> Or is there a better way to do this?
>
> Thanks in advance for the suggestions.
>
> Bob Lewis
	Regards,
Edward
	
blewis999 wrote: > I have a working 16 bit timer but now find that at low freq's we are > getting overflow so I need to go to a 32 bit timer interrupt driven. > Of course the ECT is 16 bit, so is this as simple as implementing an > interrupt on the timer overflow and adding 10000 to a time count each > time and then finally adding the capture timer to the 32 bit count on > the final edge? Yes, you could do it that way but 32 bit ops are a bit expensive on 9s12 (cycles-wise). Can you adjust your prescale to keep in the 16bit range? In one case where I couldn't change the prescale due to the requirements of a different timer (they share the same time base per ECT), I right shifted my capture times by 4 and added to overflows left shifted by 12 (my max period was such that I couldn't overflow 16 bits with this scheme). The loss of accuracy may not be acceptable for your app. > > I have to also drive a pin with the same freq captured and I am not > sure of the sync issues. How do you use the input timer over flow > interrupt while, driving the output and also needing the overflow flag > to track a similiar 32 bit number. The overflow flag has to be cleared > so wouldn't that mess up the other timer? No. The overflow is to TCNT reg. which is common to all compare registers. > > Or is there a better way to do this? > > Thanks in advance for the suggestions. > > Bob Lewis > YAHOO! GROUPS LINKS > > > Yahoo! Groups Links
Edward Karpicz wrote: >>I have a working 16 bit timer but now find that at low freq's we are >>getting overflow so I need to go to a 32 bit timer interrupt driven. >>Of course the ECT is 16 bit, so is this as simple as implementing an >>interrupt on the timer overflow and adding 10000 to a time count each >>time and then finally adding the capture timer to the 32 bit count on >>the final edge? > IMO it doesn't make sense to use TOV interrupt to generate long pulses or > periods. It's way easier to count 16bit overflows in TCx interrupts. > setup_for_long_delay() > { > TCx= t0 + loword(ticks); > if(hiword(ticks) ==0) {TCTL=} // in case ticks < 2^16 next OC event is > // the target event > clearTCxflag(); > } > > TCxISR() > { > // don't update TCx, just clear flag, and interrupt will fire every > 0x10000 ticks > > if(hiword(ticks)) hiword(ticks) = hiword(ticks) - 1; // overflows counter > if(hiword(ticks) ==0) {TCTL=} // after overflows counter reached 0 - > next OC > // event will be the > target event > clearTCxflag(); > } > Above pseudocode is oversimplified. loword(ticks) close to 0 are > troublesome. Interrupts latency or code execution time may make your > flagclear() too late. In case ticks&0xffff is very small I do divide > overflow period (2^16) into two halves and generate first interrupt at > t0+(0x8000+loword(ticks)), second interrupt at TCx+0x8000, further > interrupts (if any) every TCx+0x10000. > > char overhead; > #define minOCxperiod nnn > > setup_for_long_delay() > { > if(loword(ticks) { > overhead=1; > TCx = t0 + (0x8000 + loword(ticks)); > } > else > { > overhead=0; > TCx= t0 + loword(ticks); > } > if(hiword(ticks) ==0 && !overhead) {TCTL=} > // in case ticks < 2^16 next OC > event is > // the target event > clearTCxflag(); > } > > TCxISR() > { > if(overhead) TCx +=0x8000; > > if(hiword(ticks)) hiword(ticks) = hiword(ticks) - 1; // overflows counter > if(hiword(ticks) ==0) {TCTL=} // after overflows counter reached 0 - > next OC > // event will be the > target event > clearTCxflag(); > } >>I have to also drive a pin with the same freq captured and I am not >>sure of the sync issues. How do you use the input timer over flow >>interrupt while, driving the output and also needing the overflow flag >>to track a similiar 32 bit number. The overflow flag has to be cleared >> so wouldn't that mess up the other timer? > > HC11 pink book has good example how to measure long periods. > (http://www.freescale.com/files/microcontrollers/doc/ref_manual/M68HC11RM.pdf) > > IMO that's the only application for TOV interrupt ( to count >16bit ticks > from one IC event to another IC event). > >>Or is there a better way to do this? >> >>Thanks in advance for the suggestions. >> >>Bob Lewis > > Regards, > Edward > > Edward, Rob Thank you for the advice. I can't loose the accuracy or rescale the prescale because of the other timers that use the prescale. Having just one common timer really is a pain. I think I can capture the input now for the timer using 24 bits, but driving the output with the new computed value at 24 bits has me stumped. Bob Lewis Yahoo! Groups Links
> input now for the timer using 24 bits, but driving the output with the > new computed value at 24 bits has me stumped. Personally, I would just keep a ovf var. that I would increment for each TCx interrupt until it reaches the desired value and adjust the TCx compare value for sub 16 bit timing after the last desired overflow. rob Yahoo! Groups Links