Pumpkin, Inc.

Pumpkin User Forums

Multiple Interrupts and OSTimer()

If you can't make Salvo do what you want it to do, post it here.

Multiple Interrupts and OSTimer()

Postby Unregistered User » Sun Dec 02, 2001 10:36 am

I have to generate a 4kHz waveform with accurate timing -- I can't tolerate any jitter from interrupts, etc. My code looks something like this:

code:
  ...
StartWaveform();
enable interrupts();
/* waveform is generated here */
...

StartWaveform() enables an interrupt-driven timer that outputs 10,000 samples 250us apart. After it's done, it disables its own interrupt enable flag.

How can I integrate OSTimer() into this system?

[This message has been edited by Unregistered User (edited December 02, 2001).]

Unregistered User
 
Posts: 36
Joined: Thu Aug 09, 2001 11:00 pm

Re: Multiple Interrupts and OSTimer()

Postby aek » Sun Dec 02, 2001 10:55 am

Most calls to OSTimer() will be very fast -- 20 cycles or so, plus the ISR overhead. But when a task times out, OSTimer() will require substantially more cycles, and that's when you would run into trouble. So your approach is a reasonable one.

Here's how I would do it (illustrated on a PIC16F877):

1) Use separate interrupt sources for the 4kHz timer (e.g. use Timer1) and OSTimer() (e.g. Timer0).

2) Disable Timer0's interrupts just before enabling Timer1's. When finished, re-enable Timer0's after disabling Timer1's.

Something like this:

code:
  ...
/* interrupts are enabled ... */
T0IE = 0;
sampleCounter = 10000;
T1IE = 1;
/* waveform is generated here, no other */
/* interrupt sources are active. */
do {
;
} while (T0IE = 0);
...

and

code:
void interrupt ISR ( void )
{
if ( T0IE && T0IF ) {
T0IF = 0;
TMR0 -= TMR0_RELOAD;
OSTimer();
}

if ( T1IE && T1IF ) {
T1IF = 0;
OutputSample();
if ( --sampleCounter == 0 ) {
T1IE = 0;
T0IE = 1;
}
}
}




This is just one way to do it. Another would be to stay inside the ISR altogether, and poll T1IF for when to send the next waveform. Or hard-code a loop to do it all inside the ISR.

How does this affect your application? Well, you can't do much while the waveform is being generated, mainly because the PIC doesn't enough horsepower to do 4kHz interrupts with an 8MHz clock. IOW, the time between samples is really too small to get much done in the background (i.e. mainline code), and it also doesn't tolerate disabling of interrupts in the background for more than a few cycles.

It also doesn't have much effect on timer services elsewhere in your code, assuming that you don't generate this waveform very often. Basically, you may "lose" a timer tick or two whenever the waveform is generated while TMR0 rolls over. You could compensate for this in the ISR() by calling OSTimer() "extra" times for the ones that were missed while Timer0 interrupts were disabled.

The point I'm trying to make here is that you can selectively disable the interrupt that is chained to OSTimer() and then re-enable it later without too much impact on your overall system. And with OSTimer() running you can use all of Salvo's delay services, etc.

One other thing you could do is use a single timer source (e.g. Timer0 at 4kHz), and use the prescalar to "slow down" OSTimer() to something like 400Hz.

------------------

[This message has been edited by aek (edited December 02, 2001).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Multiple Interrupts and OSTimer()

Postby aek » Sun Dec 02, 2001 11:07 am

I wrote:

quote:
The point I'm trying to make here is that you can selectively disable the interrupt that is chained to OSTimer() and then re-enable it later without too much impact on your overall system.

Of course, if you do all the generation inside the ISR (this way you'll get essentially 0 jitter) then you don't even have to worry about Timer0, OSTimer() or any other interrupt issues. You will be wasting a lot of cycles, since it probably only takes you 20 or so to output a sample, so the remaining 105 are wasted in a do-nothing loop, but perhaps that's OK for you ...

code:
void interrupt ISR ( void )
{
...
if ( T1IE && T1IF ) {
Output10kSamples();
T1IE = 0;
}
}

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Multiple Interrupts and OSTimer()

Postby luben » Mon Dec 03, 2001 2:53 am

Hello,

I'm afraid that 250uS delays on 4MHz clock will not produce good results if generating is made from some task with OS_Delay. Even if the task has the highest priority the output signal will have some fluctuation of phase and frequency. Well, the average frequence could be equal to 4 KHz, but the moment frequency will vary.

The power of SALVO is not exactly in generating some quick signals, but in the possibility to process simultaneously many algorytms (multitasking). I mean - the real advantage of SALVO is when you have to take complicated decisions, to process data streams, when you care for complicated responses, etc. You lose the advantages of SALVO when you try to do something out of it range.

At lest you have to increase the clock to 20MHz or to use TMR1 ISR to generate the signal. My experience is that such procedures don't take big time from ISR.

My recomendation is to move this process into ISR TMRn - this will guarantee fixed frequence.

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Multiple Interrupts and OSTimer()

Postby aek » Mon Dec 03, 2001 11:47 am

In general, we recommend at least 2000 processor cyles (and really 2000 instructions) per system tick when using OSTimer. On a 4MHz PIC, that's 2ms. You'd need a 32MHz PIC to have 250us system ticks -- doable only on a PIC18-series PIC. In that case you could actually drive the waveform generator from OS_Delay(), but the timing would still be +/- 250us, which would be unacceptable. You'd need something like a 100MHz PIC for good results, and that doesn't exist.

My point (and Luben's, I think) in this thread is that Salvo's normal services can co-exist nicely with this need for rock-solid timing at 250us. I pointed out several ways to use OSTimer() and control interrupts in a way that won't compromise the 4kHz waveform generation. Your system ticks will be compromised somewhat, but you can average out the error with some careful coding if that's necessary for your application. Otherwise I wouldn't worry about it.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm


Return to Coding

Who is online

Users browsing this forum: No registered users and 3 guests

cron