Searching \ for '[PIC]: Interrupt USART + TMR0' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'Interrupt USART + TMR0'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Interrupt USART + TMR0'
2005\01\30@195950 by Padu

face picon face
Is that possible to use interrupts for both USART (Rx) AND TMR0 at the same time? If yes, how can I distinguish who invoked the interrupt handler?
Although my question is a generic one, I'm using a 16F877A in my development board. I'll probably use a 18F452 in production, but I suspect the concept will be the same for both of them.

The application of this: I have to send commands from a PC to the PIC using RS232, and in this commands I'm sending time intervals to create a PWM signal. It's for controlling a R/C servo. I've read somewhere that some PIC's already have a PWM feature, but for this type of application, a timer would be better (is that so?)

I've already created one test app that does that but has a few limitations, first it relies on delaying the main loop of the app. The obvious disadvantage is that I won't have time for much else, and I need to control more than 1 servo simultaneously (2 to 4). My idea then is to create 4 timeslots of 5ms each, one timeslot for each servo. This way, for each 5ms, timeslot, I spend 1-2ms with a delay and I'll probably have plenty of cpu time to do other stuff. Am I going the right direction?

Padu

2005\01\30@222503 by Josh Koffman

face picon face
I'm sure others will chime in with a better response. Here is my super
tired, on the way to bed answer.

When you get an interrupt, you check the flags of the interrupts you
are interested in. look for the xxxIF flags. Remember, you have to
clear those flags too.

Josh
--
A common mistake that people make when trying to design something
completely foolproof is to underestimate the ingenuity of complete
fools.
       -Douglas Adams

On Sun, 30 Jan 2005 17:01:24 -0800, Padu <spam_OUTpaduTakeThisOuTspammerlotti.com> wrote:
> Is that possible to use interrupts for both USART (Rx) AND TMR0 at the same time? If yes, how can I distinguish who invoked the interrupt handler?
> Although my question is a generic one, I'm using a 16F877A in my development board. I'll probably use a 18F452 in production, but I suspect the concept will be the same for both of them.

2005\01\31@100749 by Mike Hord

picon face
> I'm sure others will chime in with a better response. Here is my super
> tired, on the way to bed answer.
>
> When you get an interrupt, you check the flags of the interrupts you
> are interested in. look for the xxxIF flags. Remember, you have to
> clear those flags too.
>
> Josh

Note that this allows for (something like) priority in interrupt
handling, even in 12- and 14-bit core chips.  Multiple simultaneous
interrupts will be serviced in the order they are checked.  Any
interrupt NOT serviced will cause an immediate return to the interrupt
vector upon RETFIE.  This doesn't mean that a lower priority interrupt
can be interrupted by a higher priority interrupt, just that more time
critical ones can be allowed to finish their business before less time
critical ones.

Also remember that not all interrupt flags are cleared by clearing
their respective flag; for example, USART interrupt flags are cleared
by taking the appropriate action on the involved register (writing
TXREG, reading RCREG).

Mike H.

2005\01\31@102032 by Jan-Erik Soderholm

face picon face
On Sun, 30 Jan 2005 22:13:40 -0700, Robert Rolf wrote:

> In my application I have a half dozen interrupts going
> at once, so I have to poll the receive flag multiple
> places in the ISR to ensure I don't miss any characters.

In "multiple places" ??

Are you saying that you have some part of your IST taking
to long time to finish, so you have to check other flags and,
if needed, "call" another part of the ISR temporarily ?

Or, in other words, you are normaly (when not inside the ISR)
letting the interrupt system do it's stuff, but while inside
the ISR, you are actualy polling the receive flag ?

I'm sure you have thought of moving some of the larger
parts of the ISR out of the ISR, right ? (So it could be
"interrupted" the normal way by the receive interrupt...)
Why didn't that work ?

Jan-Erik.




2005\01\31@104111 by Wouter van Ooijen

face picon face
> Note that this allows for (something like) priority in interrupt
> handling, even in 12- and 14-bit core chips.  Multiple simultaneous
> interrupts will be serviced in the order they are checked.  Any
> interrupt NOT serviced will cause an immediate return to the interrupt
> vector upon RETFIE.  This doesn't mean that a lower priority interrupt
> can be interrupted by a higher priority interrupt, just that more time
> critical ones can be allowed to finish their business before less time
> critical ones.

I am not sure this is a good idea. It will reduce the *average*
interrupt latency for the higher priority serivice code, but it might
not reduce the *worst case* latency. This will make latency-related
problems harder to reproduce. As a user, I (grudgingly) prefer a program
that misbehaves only once an day. As a tester I much prefer a program
that misbehaves each second!

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\01\31@112609 by Mike Hord

picon face
> > Note that this allows for (something like) priority in interrupt
> > handling, even in 12- and 14-bit core chips.  Multiple simultaneous
> > interrupts will be serviced in the order they are checked.  Any
> > interrupt NOT serviced will cause an immediate return to the interrupt
> > vector upon RETFIE.  This doesn't mean that a lower priority interrupt
> > can be interrupted by a higher priority interrupt, just that more time
> > critical ones can be allowed to finish their business before less time
> > critical ones.
>
> I am not sure this is a good idea. It will reduce the *average*
> interrupt latency for the higher priority serivice code, but it might
> not reduce the *worst case* latency. This will make latency-related
> problems harder to reproduce. As a user, I (grudgingly) prefer a program
> that misbehaves only once an day. As a tester I much prefer a program
> that misbehaves each second!

So what's the solution?  The intuitive method for dealing with
multiple interrupts is to check the most important interrupt first,
deal with it, check another, deal with it, check another, etc. until
all interrupts have been serviced, the RETFIE.  If we only check one
interrupt, then RETFIE, the possibility exists that if that interrupt
recurs before the RETFIE, it could block all other interrupts from
being serviced.  Another possibility is checking different interrupts
at different places within the ISR; I'm not sure I like that.  So
what's your candidate for best solution, Wouter?

Mike H.

2005\01\31@120617 by Jan-Erik Soderholm

face picon face
Mike Hord wrote :

> So what's the solution?  The intuitive method for dealing with
> multiple interrupts is to check the most important interrupt first,
> deal with it, check another, deal with it, check another, etc. until
> all interrupts have been serviced, the RETFIE.  If we only check one
> interrupt, then RETFIE, the possibility exists that if that interrupt
> recurs before the RETFIE, it could block all other interrupts from
> being serviced.

So you have one specific interrupt with a shorter interrupt
intervall then it takes to process *one* of them ? How
do you expect that to work, no matter what else the PIC
is doing ?

> Another possibility is checking different interrupts
> at different places within the ISR; I'm not sure I like that.

It's signal to you that you have some design problem.

> So what's your candidate for best solution, anyone ?

Make sure that the longest ISR take a shorter time then the
fastest intervall for a single interrupt. Then you will
always have cycles to run your application. There's no magic
in that...

Regards,
Jan-Erik



2005\01\31@123648 by Padu

picon face
Mike wrote:
> So what's the solution?  The intuitive method for dealing with
> multiple interrupts is to check the most important interrupt first,
> deal with it, check another, deal with it, check another, etc. until
> all interrupts have been serviced, the RETFIE.  If we only check one
> interrupt, then RETFIE, the possibility exists that if that interrupt
> recurs before the RETFIE, it could block all other interrupts from
> being serviced.  Another possibility is checking different interrupts
> at different places within the ISR; I'm not sure I like that.  So
> what's your candidate for best solution, Wouter?


Humnn, never thought about this. The nice thing about this list is that you
ask something and end with answers to questions you actually never asked...
=^)

2005\01\31@125312 by Mike Hord

picon face
> > So what's the solution?  The intuitive method for dealing with
> > multiple interrupts is to check the most important interrupt first,
> > deal with it, check another, deal with it, check another, etc. until
> > all interrupts have been serviced, the RETFIE.  If we only check one
> > interrupt, then RETFIE, the possibility exists that if that interrupt
> > recurs before the RETFIE, it could block all other interrupts from
> > being serviced.
>
> So you have one specific interrupt with a shorter interrupt
> intervall then it takes to process *one* of them ? How
> do you expect that to work, no matter what else the PIC
> is doing ?

No, see below.

> > Another possibility is checking different interrupts
> > at different places within the ISR; I'm not sure I like that.
>
> It's signal to you that you have some design problem.

Agreed.

> > So what's your candidate for best solution, anyone ?
>
> Make sure that the longest ISR take a shorter time then the
> fastest intervall for a single interrupt. Then you will
> always have cycles to run your application. There's no magic
> in that...

Agreed.  But you're still assigning a priority to the interrupts in
your system by the fact of the order in which you check them.
Wouter was suggesting that prioritization is a mistake.  I'm
asking how to avoid it, since my limited experience leads me
to the solution of check one, deal with it, check the next, etc.,
and make certain that the worst case latency for dealing with
all of them won't cause another one to be missed.

Mike H.

2005\01\31@125740 by Dave VanHorn

flavicon
face

>
>So what's the solution?  The intuitive method for dealing with
>multiple interrupts is to check the most important interrupt first,
>deal with it, check another, deal with it, check another, etc. until
>all interrupts have been serviced, the RETFIE.  If we only check one
>interrupt, then RETFIE, the possibility exists that if that interrupt
>recurs before the RETFIE, it could block all other interrupts from
>being serviced.  Another possibility is checking different interrupts
>at different places within the ISR; I'm not sure I like that.  So
>what's your candidate for best solution, Wouter?

The answer depends on how fast the ints come, and how critical they are.

If you're connecting to something that needs very tight coupling, high
priority, and short interval between hits, then maybe an int isn't the best
mechanism.

Serial ports are a good example of something that works well under ints.
They happen relatively infrequently (even at 115200) and generally don't
have a lot of logic attached.

It would be a mistake to do a lot of processing in any ISR, you're far
better off to stuff the data in a buffer, signal that it's arrived, and
carry on, and let a non-int task figure out what to do with it.  Same goes
for the outbound side, the ISR should just pump bytes.

In the AVR, we don't have this flexibility, but the ints are vectored, and
I don't HAVE to push/pop anything for some ints.
What we have is fixed priority, and a guarantee of at least one non-int
instruction executing between ints, even if several are stacked up.



2005\01\31@130425 by William Couture

face picon face
On Mon, 31 Jan 2005 16:20:31 +0100 (MET), Jan-Erik Soderholm
<.....jan-erik.soderholmKILLspamspam@spam@telia.com> wrote:
{Quote hidden}

I have an application like that.  There are 2 sources of
interrupt, an incoming RS232 message at 115,200 baud and
a PID control loop at 2Khz.

The PID calculations MUST be in the ISR to reduce timing
jitter as much as possible (the code originally had the TMR1
interrupt setting a flag that was used in the main loop to start
the PID calculations, but the timing jitter was too noticable,
and so the calculations were moved into the ISR).

And more than 2 characters can come in during the PID
calculations, so characters could be lost.  The solution
was to check the RCIF flag in several places in the ISR
and buffer the incoming queue.  The extra microsecond
or two in strategic locations did not give significant timing
jitter in the PID calculations, and no characters were lost.

Bill

2005\01\31@140908 by olin_piclist

face picon face
Mike Hord wrote:
> So what's the solution?  The intuitive method for dealing with
> multiple interrupts is to check the most important interrupt first,
> deal with it, check another, deal with it, check another, etc. until
> all interrupts have been serviced, the RETFIE.  If we only check one
> interrupt, then RETFIE, the possibility exists that if that interrupt
> recurs before the RETFIE, it could block all other interrupts from
> being serviced.  Another possibility is checking different interrupts
> at different places within the ISR; I'm not sure I like that.  So
> what's your candidate for best solution, Wouter?

I'm not Wouter, but I check interrupt conditions in priority order, handle
the first one I find, then get out as quickly as possible.  If there are
multiple interrupt conditions, then a new interrupt will be taken
immediately after RETFIE.  This takes the least number of cycles to handle
the most important interrupt.  Most of the time, interrupts do not overlap
anyway, so the extra cycles that optimize for that case usually pessimize
the overall system.  If your highest priority interrupt occurs so frequently
that you have another interrupt immediately after finishing the previous,
you're processor is overloaded and you've got other problems anyway.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\01\31@141208 by Bob Ammerman

picon face
I see nothing wrong with an architecture that checks (polls) for higher
priority interrupts while in the middle of processing a lower priority
interrupt. It is effectively no different than an implementation that
supports multiple priority levels in hardware.

You do have to be sure you have enough processing power to get everything
done in time, but that is again no different than the hardware supported
case.

Also, there is really nothing intrinsically wrong with doing significant
processing in an interrupt handler. It can often simplify coding because the
interrupt handler code doesn't have to worry about task level code changes
things out from under it, whereas task level code must constantly be
concerned about interrupt level code changing things.

I have written applications where interrupt level code occupies over 85% of
the CPU (but with a guarantee that it will not exceed a fixed number <
100%).

You can look at my multiple UAR(no T) code stored on PICLIST.COM for a
program that does a lot at interrupt level.

The 'virtual peripherals' championed by Ubicom on the SX processors are also
high-cpu interrupt handlers.

Bob Ammerman
RAm Systems


{Original Message removed}

2005\01\31@145222 by olin_piclist

face picon face
William Couture wrote:
> The PID calculations MUST be in the ISR to reduce timing
> jitter as much as possible

No, only the measurement of the inputs and the writing of the output.  The
computation only needs to be done between these and can jitter all it wants
as long as the results are computed in time to write them to the outputs.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\01\31@154718 by William Couture

face picon face
On Mon, 31 Jan 2005 14:51:45 -0500, Olin Lathrop
<olin_piclistspamKILLspamembedinc.com> wrote:
> William Couture wrote:
> > The PID calculations MUST be in the ISR to reduce timing
> > jitter as much as possible
>
> No, only the measurement of the inputs and the writing of the output.  The
> computation only needs to be done between these and can jitter all it wants
> as long as the results are computed in time to write them to the outputs.

No, I meant what I wrote.

If the PID calculation was done in the background loop, there would be
a variable number of instructions between the setting of the DO_IT_NOW
flag and the start of the PID update.  The effect of this is that, while in the
long run the PID was updated at 2Khz, there would be a considerable
jitter in the timing, which showed up in the accuracy of position hold.

If the PID calculation was done in the ISR, the jitter was much smaller,
and the accuracy of the position hold was much better.

As for the idea of "read inputs in ISR, set outputs in ISR, do calculations
in background" that doesn't always work very well.

In our application, phase lag was a serious problem.  There can also
be a problem with when interrupts occur.  Since there are a limited
number of timers to play with and we have to keep things on schedule,
the "best" solutions are:
  1) interrupt is at 2Khz, read current inputs and set outputs based on
      previous interrupt.  Unacceptable due to phase lag.

  2) interrupt is at 4Khz, alternating interrupts read inputs and set
      outputs.  Better (though not very good) phase lag, but interrrupt
      overhead is getting significant.

  3) interrupt is a higher multiple of 2Khz, reading inputs and setting
      outputs on appropriate interrupts.  Good resolution on phase
      lag, but interrupt overhead has changed timing (increased phase
      lag) with respect to just doing the entire PID in the isr.

So, though it does not appeal to you, the entire PID was done in
the ISR.  If you want to debate it, I'll pass you over to our control
systems engineer.

Bill

2005\01\31@161924 by Wouter van Ooijen

face picon face
> So what's the solution?  The intuitive method for dealing with
> multiple interrupts is to check the most important interrupt first,

My approach is to start using no interrupts at all. In an awfull lot of
cases where interrupts are used they are not needed. Just a big loop,
maybe synchronised to a counter overflow, can do a lot. We had a class
last year where six groups of ~5 students had to build and program a
remote controlled robot using stepper motors. 5 groups used interrupts
(often they used interrupts for everything). None of these groups got a
reliably working system. The 6th group used a 1ms main loop polling a
number of state machines. Worked flawlessly...

If you have one time-criticall issue that must be served faster than
your mainloop can cycle you might use an interrupt. This will often be
the receiving part of some communication, maybe the sending part too.

If you need multiple interrupts that can each tolerate a latency equal
to the execution time of the longest interrupt use a 'serve one
interrupt source' approach. Is does not matter which one you serve
first. (But also take the frequency of the interrupt into account!).

If each interrupt can tolerate a latency equal to the total interrupt
handlers time you can (but need not) use a 'serve all sources' approach.

If you feel you need more than one interrupt and they are all critical
(can't tolerate much latency) you are in trouble. Maybe solvable
trouble.

> If we only check one
> interrupt, then RETFIE, the possibility exists that if that interrupt
> recurs before the RETFIE, it could block all other interrupts from
> being serviced.

But only if it would consume >100% CPU time, which indicates some design
problem.

> So what's your candidate for best solution, Wouter?

Definitely the 'no interrupts' approach. Second place: if interrupts are
used, be prepared to think them over very very well, not just the code
but also the timing. If you can't prove to your pet or spouse that it
will work (not just functionally, but also with respect to timing) you
probably should not use interrupts.

Examples of interrupt use that I do like (when needed):
- wakeup from sleep on pin change
- (serial) communication buffer
- virtual peripherals (SX-style)

BTW I often use an interrupt flag (for instance the timer interrupt
flag) without interrupts. Just poll the interrupt flag in the main loop.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\01\31@161958 by Bob Ammerman

picon face
> In our application, phase lag was a serious problem.  There can also
> be a problem with when interrupts occur.  Since there are a limited
> number of timers to play with and we have to keep things on schedule,
> the "best" solutions are:
>   1) interrupt is at 2Khz, read current inputs and set outputs based on
>       previous interrupt.  Unacceptable due to phase lag.
>
>   2) interrupt is at 4Khz, alternating interrupts read inputs and set
>       outputs.  Better (though not very good) phase lag, but interrrupt
>       overhead is getting significant.
>
>   3) interrupt is a higher multiple of 2Khz, reading inputs and setting
>       outputs on appropriate interrupts.  Good resolution on phase
>       lag, but interrupt overhead has changed timing (increased phase
>       lag) with respect to just doing the entire PID in the isr.
>

save/restore etc omitted for clarity of exposition

InterruptHandler:
   incf      Phase,F
   btfss    Phase,0
   goto    get_inputs

   .... update outputs ....
   .... adjust timer to go off in 'n' uSec, relative to last interrupt ....
   retfie

get_inputs:
   .... fetch inputs ...
   ...  adjust timer to go off in 500-n uSec, relative to last interrupt
...
   bsf    data_avail_flag
   retfie

Net result:

two interrupts per PID cycle
near zero jitter
minimal jitter-free phase lag

Note however, that unlike some others on the list, I see nothing wrong with
embedding the PID update in the interrupt handler.

Bob Ammerman
RAm Systems




2005\01\31@165719 by Mike Hord

picon face
> > So what's the solution?  The intuitive method for dealing with
> > multiple interrupts is to check the most important interrupt first,
>
> My approach is to start using no interrupts at all. In an awfull lot of
> cases where interrupts are used they are not needed. Just a big loop,
> maybe synchronised to a counter overflow, can do a lot. We had a class
> last year where six groups of ~5 students had to build and program a
> remote controlled robot using stepper motors. 5 groups used interrupts
> (often they used interrupts for everything). None of these groups got a
> reliably working system. The 6th group used a 1ms main loop polling a
> number of state machines. Worked flawlessly...

<details snipped>

That's very interesting, Wouter.  Goes against what I was taught- interrupts
are the "easy" way to do it.  Although I suppose it's pretty similar to what
I've been doing lately.

I usually evaluate what I'm doing before deciding what to do.  Anything which
does something periodic is a candidate for interrupts; I find it far easier to
setup a timer interrupt for every 200 ms or 4 s or whatever than to muck
about with waitloops and such.

Huh.  Something to think about.

Mike H.

2005\01\31@171403 by Wouter van Ooijen

face picon face
> No, I meant what I wrote.
>
> If the PID calculation was done in the background loop, there would be
> a variable number of instructions between the setting of the DO_IT_NOW
> flag and the start of the PID update.

I don't grok this. Which instructions would be inbetween? There are
techniques to re-start a loop at fixed intervals, with zero jitter.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\01\31@173823 by Wouter van Ooijen

face picon face
> That's very interesting, Wouter.  Goes against what I was
> taught- interrupts are the "easy" way to do it.

I am trying to teach the opposite - interrupts are like assembler (as
alternative to a HLL like C): in nearly all cases you won't need it, but
in the remaining case you will need it badly. But it is by no means
easy.

> I usually evaluate what I'm doing before deciding what to do.
>  Anything which
> does something periodic is a candidate for interrupts; I find
> it far easier to
> setup a timer interrupt for every 200 ms or 4 s or whatever
> than to muck
> about with waitloops and such.

It might be easier to code, but is it also easier to
- test
- debug
- prove correct

Or rephrase: can you realy understand the (logic and timing) properties
of a program with 3 or more interrupt sources? Can you calculate the
worst case response time for each interrupt? Are you sure the interrupts
will never interfere (in timing or in logic) in a bad way with the main
code or with each other?

I think I might be able to do that (in fact I did such work for space
and defense projects) but I'd rather not if I can avoid it :)

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\01\31@174747 by Mike Hord

picon face
> Or rephrase: can you realy understand the (logic and timing) properties
> of a program with 3 or more interrupt sources? Can you calculate the
> worst case response time for each interrupt? Are you sure the interrupts
> will never interfere (in timing or in logic) in a bad way with the main
> code or with each other?

Nope.  Not easily, anyway.  But then, the only time I knee-jerk hands-down
use an interrupt is if the entire system is based on regularly occuring events.

A rarity, at best.  But it happens.  Once or twice I've had a system which
did nothing but interrupts.  Again, a rarity.  But it happens.  Those are almost
always what someone with many more years experience than I would call
"trivial".  I don't yet consider very many things at all trivial.  ;-)

Mike H.

2005\01\31@195013 by William Couture

face picon face
On Mon, 31 Jan 2005 23:14:01 +0100, Wouter van Ooijen <.....wouterKILLspamspam.....voti.nl> wrote:
> > No, I meant what I wrote.
> >
> > If the PID calculation was done in the background loop, there would be
> > a variable number of instructions between the setting of the DO_IT_NOW
> > flag and the start of the PID update.
>
> I don't grok this. Which instructions would be inbetween? There are
> techniques to re-start a loop at fixed intervals, with zero jitter.

while (TRUE)
  {
   if (DO_IT_NOW)
     pid_calculations();
  code_a();
  code_b();
  code_c();
  code_d();
  }

since the DO_IT_NOW flag could be set at any time by
the interrupt (or the TMR1IF flag), the PID code could run
immediately, or after all the other routines, or...

Bill

2005\01\31@202441 by Andrew Warren

flavicon
face
William Couture <EraseMEpiclistspam_OUTspamTakeThisOuTmit.edu> wrote:

> while (TRUE)
>    {
>     if (DO_IT_NOW)
>       pid_calculations();
>    code_a();
>    code_b();
>    code_c();
>    code_d();
>    }
>
> since the DO_IT_NOW flag could be set at any time by the interrupt
> (or the TMR1IF flag), the PID code could run immediately, or after
> all the other routines

   ... and the only alternative to that code is to do everything
   inside the ISR?

   Your issues, Bill, seem to be with a particular(ly bad)
   IMPLEMENTATION of an architecture, not with the architecture
   itself.  It isn't impossible to make your pid_calculations() code
   run always at a fixed time after the DO_IT_NOW flag was set; it
   just takes a little more creativity or experience or whatever.

   -Andy

=== Andrew Warren -- aiwspamspam_OUTcypress.com
=== Principal Design Engineer
=== Cypress Semiconductor Corporation
=== (but open to offers)
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

2005\01\31@212912 by William Couture

face picon face
On Mon, 31 Jan 2005 17:30:30 -0800, Andrew Warren <@spam@aiwKILLspamspamcypress.com> wrote:

> It isn't impossible to make your pid_calculations() code
>run always at a fixed time after the DO_IT_NOW flag was set; it
>just takes a little more creativity or experience or whatever.

Feel free to enlighten us with your splendid code.

Bill


'[PIC]: Interrupt USART + TMR0'
2005\02\01@015522 by Wouter van Ooijen
face picon face
> while (TRUE)
>    {
>     if (DO_IT_NOW)
>       pid_calculations();
>    code_a();
>    code_b();
>    code_c();
>    code_d();
>    }
>
> since the DO_IT_NOW flag could be set at any time by
> the interrupt (or the TMR1IF flag), the PID code could run
> immediately, or after all the other routines, or...

But that's because you want your code to do too much. If sum of your pid
+ code_a + code_b etc execuation times takes more time than the timer
interval you should not execute all code_a + code_b + code_c + code_d,
but for intsnace only one of them (round robin fashion), or transform
one or more to a state machine that speads the execution time over more
than one call.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\01@020150 by Wouter van Ooijen

face picon face
> while (TRUE)
>    {
>     if (DO_IT_NOW)
>       pid_calculations();
>    code_a();
>    code_b();
>    code_c();
>    code_d();
>    }

Sorry, I did not look at your code long enough. The standard 'fixed
interval loop' looks more like this:

while( TRUE ){
  while( ! DO_IT_NOW ){}
  pid_calculations();
  code_a();
  code_b();
  code_c();
  code_d();
}

Of course the total excution time must be less than the timer interval.
If not read my previous post.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\01@065125 by William Couture

face picon face
On Tue, 1 Feb 2005 07:55:20 +0100, Wouter van Ooijen <KILLspamwouterKILLspamspamvoti.nl> wrote:

{Quote hidden}

Now you're saying I need to change the requirements.  That's something
you need to take up with my employer.

Bill

2005\02\01@113658 by Bob Ammerman

picon face
I have often use a scheme like this:

   for (;;)
   {
       if (task1())
           continue;
      if (task2())
           continue;
      if (task3())
           continue;
   }

Where the tasks are listed in order of priority. Each task is typically
written as a state machine. Each state starts with code that quickly
determines if the task has any significant work to do. If not the function
returns false. Otherwise the task performs a 'step' in its operation and
returns true.

Bob Ammerman
RAm Systems


2005\02\01@142636 by Bob Axtell

face picon face
General note, my thoughts:

I agree with Olin's view: do as little as possible during the interrupt
itself. Except
for serial characters being received (I stuff those immediately), just
set up flags
so that they can be serviced in the main code in a prioritized manner.

--Bob

--Bob

Wouter van Ooijen wrote:

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
RemoveMEattachTakeThisOuTspamengineer.cotse.net .
1-866-263-5745 USA/Canada
http://beam.to/azengineer

2005\02\01@145734 by Herbert Graf

flavicon
face
On Tue, 2005-02-01 at 12:26 -0700, Bob Axtell wrote:
> General note, my thoughts:
>
> I agree with Olin's view: do as little as possible during the interrupt
> itself. Except
> for serial characters being received (I stuff those immediately), just
> set up flags
> so that they can be serviced in the main code in a prioritized manner.

Really it depends on the app, how the programmer thinks, and what feels
most "natural".

There are cases where doing "heavy stuff" in the interrupt MIGHT be a
good idea. Heck I've had cases where doing EVERYTHING in the ISR and
having the main program consist of just "goto start" all the time made
sense.

A good example outside of the embedded world is windows programs, most
are pretty much completely "interrupt" driven.

However, in general, an ISR is meant to be a "quick" thing, something
that needs to be done at a certain time quickly so that it doesn't
interfere with the "main" program. But I see NO reason that if you
understand the implications doing heavy stuff in the ISR is "wrong".
TTYL


-----------------------------
Herbert's PIC Stuff:
http://repatch.dyndns.org:8383/pic_stuff/

2005\02\01@154516 by olin_piclist

face picon face
Herbert Graf wrote:
> There are cases where doing "heavy stuff" in the interrupt MIGHT be a
> good idea. Heck I've had cases where doing EVERYTHING in the ISR and
> having the main program consist of just "goto start" all the time made
> sense.

I had a case once where I needed to convert a single serial data stream
(sortof like Manchester) into synchronous clock and data.  There were only
something like 5 instructions per half-bit on a 20MHz PIC.  I did this by
using the interrupt input like a "GOTO 4" input pin.  There was no main code
after initialization.  There was no RETFIE instruction and the stack just
overflowed, but that didn't matter because there were no calls.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\01@160244 by Bob Axtell

face picon face
Herb,

Good example! - as without question Microsoft makes the
world's worst software, too.

Here's why I think this way:

1. Significant problems can occur when the INSIDE INT code
runs longer than the routine timer event. For example, if you
interrupt every 1ms, and your interrupt code exceeds that
frequently, the  attempt to "catch up" can be a problem.

2. Detecting interrupt overruns can be difficult to do. It is much
safer to set flags and execute the needed code in the main loop.

3. INT adds a lot of overhead. If all you need to do is set a few flags
in global registers, there is no need to save W, status, FSR, or PClath
if all you need to do is set a few flags.

--Bob

Herbert Graf wrote:

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
spamBeGoneattachspamBeGonespamengineer.cotse.net .
1-866-263-5745 USA/Canada
http://beam.to/azengineer

2005\02\01@165128 by Jan-Erik Soderholm
face picon face
Bob Axtell wrote :

> 3. INT adds a lot of overhead. If all you need to do is set a
> few flags in global registers, there is no need to save W,
> status, FSR, or PClath if all you need to do is set a few flags.

And, on the PIC18-line, that (saving of the "important" regs)
is done on the fly without any extra cycles. So *very* short
ISR's can be much faster on the 18's then on the 16's (if you
need the context saving).

And, yes, this doesn't work well (or at all) if you use both
interrupt priority levels, since there is only one set of
shadow context registers... Well, you can't get everything,
can you ? :-) :-)

Jan-Erik.



2005\02\02@025601 by Wouter van Ooijen

face picon face
> I had a case once where I needed to convert a single serial
> data stream
> (sortof like Manchester) into synchronous clock and data.  
> There were only
> something like 5 instructions per half-bit on a 20MHz PIC.  I
> did this by
> using the interrupt input like a "GOTO 4" input pin.  There
> was no main code
> after initialization.  There was no RETFIE instruction and
> the stack just
> overflowed, but that didn't matter because there were no calls.

IMHO this is a typical case (of the virtual peripheral type) where using
interrupts (or in fact using *any* obscure feature that gets the work
done) is appropriate.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\02@025606 by Wouter van Ooijen

face picon face
> Now you're saying I need to change the requirements.  That's something
> you need to take up with my employer.

You did not state your requirements, so I could not take them into
account. If your requirements are that you should code your program in
the way you did I have to rest my case, but chaning your boss might be a
good idea. But if your requirements were stated in a
functional/performance way I don't see how changing the program struture
forces you to talk to your boss.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\02@030314 by Wouter van Ooijen

face picon face
> A good example outside of the embedded world is windows programs, most
> are pretty much completely "interrupt" driven.

Probably counterintuitive again, a lot of my objections to interrupts do
not apply to using threads in interactive programs. For an interactive
program responsiveness is a 'level of effort' goal, not a real-time
requirement. Hence it makes sense to make good use of every CPU cycle
available, yet there is no need to prove a certain time requirement. For
real-time program it's often the opposite: you must be very sure that
the timing requirement(s) are met, but it does often not make much sense
to do better.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu



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