Searching \ for ' T0CK for slow INT' 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/index.htm?key=t0ck+slow+int
Search entire site for: 'T0CK for slow INT'.

No exact or substring matches. trying for part
PICList Thread
'[PICLIST] T0CK for slow INT'
2001\08\01@175653 by Hartung, Greg

flavicon
face
  My ISR routine takes a very long time to service.  About 70ms, longer
than the lowest frequency I can engineer with the dividers on a 20Mhz
crystal (20m/4/65536=.  I would like to call the ISR on a nice even
frequency of 10hz so the sampling is easy and intuitive to graph later.  The
dividers will reduce by up to 65,536, so...  a crystal of 10x? or a 555 of
10x? or is there an easier way?  I don't think I can do it the traditional
way of just interrupting more often and keeping a counter because my ISR
will skip interrupts on certain iterations.  Olin suggested trimming my ISR
code, but everything there needs to get done before the next iteration, so
that doesn't seem like the solution.

  Greg Hartung

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\08\01@184951 by myke predko

flavicon
face
Hi Greg,

If you know the amount of time for your ISR is 70 msecs, why don't you set
the TMR0 values to interrupt 30 msecs later?  Normally, the TMR0 is
reset/reloaded at the start of an ISR, what I'm suggesting is that you do it
later with a set delay.

myke

{Original Message removed}

2001\08\01@215414 by Gennette, Bruce

flavicon
face
Why not add a watch crystal (32oddkHz) as the driver for tmr0?
VERY cheap and reasonably accurate.  And once added you find lots of uses
for it.

Bye.

{Original Message removed}

2001\08\02@102719 by Roman Black

flavicon
face
Hartung, Greg wrote:
>
>    My ISR routine takes a very long time to service.  About 70ms, longer
> than the lowest frequency I can engineer with the dividers on a 20Mhz
> crystal (20m/4/65536=.  I would like to call the ISR on a nice even
> frequency of 10hz so the sampling is easy and intuitive to graph later.  The
> dividers will reduce by up to 65,536, so...  a crystal of 10x? or a 555 of
> 10x? or is there an easier way?  I don't think I can do it the traditional
> way of just interrupting more often and keeping a counter because my ISR
> will skip interrupts on certain iterations.  Olin suggested trimming my ISR
> code, but everything there needs to get done before the next iteration, so
> that doesn't seem like the solution.


Hi Greg, a good way to handle this is to use a fast
timer interrupt routine, which checks the timer and
makes an "event" every 100mS. This one-sec timer
routine at:
http://www.ezy.net.au/~fastvid/one_sec.htm

can be easily adapted to do that. Then with such
a long (70mS) task I suggest doing it OUTSIDE the
int routine, so the int routine just sets a bit, then
in your main non-int code you detect that bit and
start the 70mS task. That way the timer int keeps
perfect time while the task is being performed.
:o)
-Roman

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\08\02@105250 by Roman Black

flavicon
face
<re-sent with proper topic tag>

Hartung, Greg wrote:
>
>    My ISR routine takes a very long time to service.  About 70ms, longer
> than the lowest frequency I can engineer with the dividers on a 20Mhz
> crystal (20m/4/65536=.  I would like to call the ISR on a nice even
> frequency of 10hz so the sampling is easy and intuitive to graph later.  The
> dividers will reduce by up to 65,536, so...  a crystal of 10x? or a 555 of
> 10x? or is there an easier way?  I don't think I can do it the traditional
> way of just interrupting more often and keeping a counter because my ISR
> will skip interrupts on certain iterations.  Olin suggested trimming my ISR
> code, but everything there needs to get done before the next iteration, so
> that doesn't seem like the solution.


Hi Greg, a good way to handle this is to use a fast
timer interrupt routine, which checks the timer and
makes an "event" every 100mS. This one-sec timer
routine at:
http://www.ezy.net.au/~fastvid/one_sec.htm

can be easily adapted to do that. Then with such
a long (70mS) task I suggest doing it OUTSIDE the
int routine, so the int routine just sets a bit, then
in your main non-int code you detect that bit and
start the 70mS task. That way the timer int keeps
perfect time while the task is being performed.
:o)
-Roman

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


'[PIC]: Re: T0CK for slow INT'
2001\08\02@115019 by Andrew E. Kalman

flavicon
face
Roman wrote:

>Hi Greg, a good way to handle this is to use a fast
>timer interrupt routine, which checks the timer and
>makes an "event" every 100mS. This one-sec timer
>routine at:
>http://www.ezy.net.au/~fastvid/one_sec.htm
>
>can be easily adapted to do that. Then with such
>a long (70mS) task I suggest doing it OUTSIDE the
>int routine, so the int routine just sets a bit, then
>in your main non-int code you detect that bit and
>start the 70mS task. That way the timer int keeps
>perfect time while the task is being performed.
>:o)


If you're writing in HI-TECH C, you can use the freeeware version of
our RTOS (called Salvo Lite) to do exactly this very quickly. Here
are two ways to do it:

1) Call the system timer (OSTimer()) every, say, 10ms from inside an
ISR. Put the "big code" in a task. Have the task delay itself for
100ms (10 system ticks, via OS_Delay(10)), and you're done. About 20
lines of C plus your "big task". Code looks like this:


#define BIGTASK_P OSTCBP(1)

_OSLabel(BigTask1)

void BigTask( void )
{
  /* put 70ms task's initialization code here */

 for (;;) {
    /* delay 100ms */
    OS_Delay(10, BigTask1);

    /* put rest of 70ms task here */
  }
}

void main( void )
{
  /* do global inits (e.g. setup timer TMR2) here */

  /* initialize OS */
  OSInit();

  /* create a task with priority 5 */
  OSCreateTask(BigTask, BIGTASK_P, 5);

  /* enable interrupts */
  ei();

  /* start multitasking */
  for (;;)
    OSSched();
}

interrupt MyISR( void )
{
  /* clear interrupt flag, e.g. TMR2IF */

 /* call system timer */
  OSTimer();
}


2) Setup a 100ms interrupt that signals a binary semaphore via
OSSignalBinSem(). In the task, wait for the event (i.e. wait for the
binary semaphore to be signaled). Again, about 20 lines of C:

#define BIGTASK_P OSTCBP(1)
#define BINSEM1_P OSECBP(1)

_OSLabel(BigTask1)

void BigTask( void )
{
  /* put 70ms task's initialization code here */
 for (;;) {
    /* wait until signaled from ISR */
    OS_WaitBinSem(BINSEM1_P, BigTask1);

    /* put rest of 70ms task here */
  }
}

void main( void )
{
  /* do global inits (e.g. setup timer TMR2) here */

  OSInit();

  OSCreateTask(BigTask, BIGTASK1_P, 5);

  /* event has initially not happened */
  OSCreateBinSem(BINSEM1_P, 0);

  ei();

  for (;;)
    OSSched();
}

interrupt MyISR( void )
{
  /* clear interrupt flag, e.g. TMR2IF */

  /* signal event */
  OSSignalBinSem(BINSEM1_P);
}

Method 2) above is the method Roman is suggesting, using an RTOS to
handle the occurrence of an event. Salvo Lite handles up to 3 tasks
and 4 events on the PIC16. Count on around 600 words for the RTOS in
the examples above -- with the full version, you can shrink that down
considerably.

Since BigTask() is hogging resources for 70ms (what on earth takes
70ms = 70,000 cycles at 4MHz, BTW?), this is not such a good thing in
an RTOS environment. But it's easy to fix -- just add a couple of
OS_Yield()'s to BigTask() and then other, higher-priority tasks will
have a chance to execute if they become eligible sometime between
when BigTask() starts and when it finishes. Their total time to
execute must be less than 30ms (easily done) so that BigTask() can
run every 100ms for 70ms.

Even if you're not writing in C, the above examples may give you an
idea of how to use the concept of an event in the foreground (i.e.
interrupt) to trigger the execution of code in the background (i.e.
the main loop). The trouble you face is how to "chop up" the 70ms
task so that other things can happen. By putting it into the
background, then other interrupts can still occur, but you still are
faced with the problem of how to do "bigger" processing while
BigTask() is running. The RTOS solves that elegantly for you by
managing the "big" processing as tasks.

Regards,
--

 ______________________________________
Andrew E. Kalman, Ph.D.


Salvo(TM), The RTOS that runs in tiny places(TM)
Pumpkin, Inc.
750 Naples Street
San Francisco, CA 94112
tel: (415) 584-6360
fax: (415) 585-7948
web: http://www.pumpkininc.com
email: spam_OUTaekTakeThisOuTspampumpkininc.com

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


'[PIC]: T0CK for slow INT'
2001\08\02@120342 by Andrew E. Kalman

flavicon
face
(This time I added the subject tag correctly ... )

Roman wrote:

{Quote hidden}

If you're writing in HI-TECH C, you can use the freeeware version of
our RTOS (called Salvo Lite) to do exactly this very quickly. Here
are two ways to do it:

1) Call the system timer (OSTimer()) every, say, 10ms from inside an
ISR. Put the "big code" in a task. Have the task delay itself for
100ms (10 system ticks, via OS_Delay(10)), and you're done. About 20
lines of C plus your "big task". Code looks like this:


#define BIGTASK_P OSTCBP(1)

_OSLabel(BigTask1)

void BigTask( void )
{
  /* put 70ms task's initialization code here */

 for (;;) {
    /* delay 100ms */
    OS_Delay(10, BigTask1);

    /* put rest of 70ms task here */
  }
}

void main( void )
{
  /* do global inits (e.g. setup timer TMR2) here */

  /* initialize OS */
  OSInit();

  /* create a task with priority 5 */
  OSCreateTask(BigTask, BIGTASK_P, 5);

  /* enable interrupts */
  ei();

  /* start multitasking */
  for (;;)
    OSSched();
}

interrupt MyISR( void )
{
  /* clear interrupt flag, e.g. TMR2IF */

 /* call system timer */
  OSTimer();
}


2) Setup a 100ms interrupt that signals a binary semaphore via
OSSignalBinSem(). In the task, wait for the event (i.e. wait for the
binary semaphore to be signaled). Again, about 20 lines of C:

#define BIGTASK_P OSTCBP(1)
#define BINSEM1_P OSECBP(1)

_OSLabel(BigTask1)

void BigTask( void )
{
  /* put 70ms task's initialization code here */
 for (;;) {
    /* wait until signaled from ISR */
    OS_WaitBinSem(BINSEM1_P, BigTask1);

    /* put rest of 70ms task here */
  }
}

void main( void )
{
  /* do global inits (e.g. setup timer TMR2) here */

  OSInit();

  OSCreateTask(BigTask, BIGTASK1_P, 5);

  /* event has initially not happened */
  OSCreateBinSem(BINSEM1_P, 0);

  ei();

  for (;;)
    OSSched();
}

interrupt MyISR( void )
{
  /* clear interrupt flag, e.g. TMR2IF */

  /* signal event */
  OSSignalBinSem(BINSEM1_P);
}

Method 2) above is the method Roman is suggesting, using an RTOS to
handle the occurrence of an event. Salvo Lite handles up to 3 tasks
and 4 events on the PIC16. Count on around 600 words for the RTOS in
the examples above -- with the full version, you can shrink that down
considerably.

Since BigTask() is hogging resources for 70ms (what on earth takes
70ms = 70,000 cycles at 4MHz, BTW?), this is not such a good thing in
an RTOS environment. But it's easy to fix -- just add a couple of
OS_Yield()'s to BigTask() and then other, higher-priority tasks will
have a chance to execute if they become eligible sometime between
when BigTask() starts and when it finishes. Their total time to
execute must be less than 30ms (easily done) so that BigTask() can
run every 100ms for 70ms.

Even if you're not writing in C, the above examples may give you an
idea of how to use the concept of an event in the foreground (i.e.
interrupt) to trigger the execution of code in the background (i.e.
the main loop). The trouble you face is how to "chop up" the 70ms
task so that other things can happen. By putting it into the
background, then other interrupts can still occur, but you still are
faced with the problem of how to do "bigger" processing while
BigTask() is running. The RTOS solves that elegantly for you by
managing the "big" processing as tasks.

Regards,
--

 ______________________________________
Andrew E. Kalman, Ph.D.


Salvo(TM), The RTOS that runs in tiny places(TM)
Pumpkin, Inc.
750 Naples Street
San Francisco, CA 94112
tel: (415) 584-6360
fax: (415) 585-7948
web: http://www.pumpkininc.com
email: .....aekKILLspamspam@spam@pumpkininc.com
--

 ______________________________________
  Andrew E. Kalman, Ph.D.   aekspamKILLspampumpkininc.com

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\08\02@150017 by Barry Gershenfeld

picon face
>a long (70mS) task I suggest doing it OUTSIDE the
>int routine, so the int routine just sets a bit, then
>in your main non-int code you detect that bit and
>start the 70mS task. That way the timer int keeps
>perfect time while the task is being performed.
>:o)
>-Roman

Since the timing and measurement seem to be critical
I would modify that to say grab the sample off the
A/D first and then flag the outside routines to
run, and then exit the interrupt.

Barry

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


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