Searching \ for '[PIC:] getting serial overrun on 16F877 in HT PICC' 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/ios.htm?key=serial
Search entire site for: 'getting serial overrun on 16F877 in HT PICC'.

Exact match. Not showing close matches.
PICList Thread
'[PIC:] getting serial overrun on 16F877 in HT PICC'
2004\01\05@160612 by William Couture

picon face
Hi!

I'm having a problem with serial overrun errors, and I can't
see how.  I'm hoping someone can give me a clue.

I'm using HiTech PICC, version 8.02 with a PIC16F877 at
18.43Mhz.

I have 3 interrupts that can occur, one is a periodic
TMR1 interrupt at 2Khz, one is a TX interrupt (very
occasional), and a RX interrupt (say about about 60 chars
per second, timed sporaticly), with TX and RX at 115Kbaud
(so about 1ms per character).

Originally, my (simplified) interrupt code looked like this:

interrupt void isr()
  {
  if (TMR1IF)
     { /* fairly long processing, but well under 500us */ }
  if (TXIF)
     { /* TXIF code, seems to work */ }
  while (RCIF)
     {
     if (RCSTA & 0x06)  /* if OERR or FERR */
        { /* error processing */ }
     else
        txbuf[txbufptr++] = RCREG;
     }
  }

However, I was getting overrun errors.  No clue as to how.
So, I changed my (simplified) interrupt code to:

interrupt void isr()
  {
  if (TMR1IF)
     { /* fairly long processing, but well under 500us */ }
  if (TXIF)
     { /* TXIF code, seems to work */ }
  while ((RCIF) || (RCSTA & 0x06))
     {
     if (RCSTA & 0x06)  /* if OERR or FERR */
        { /* error processing */ }
     else
        txbuf[txbufptr++] = RCREG;
     }
  }

Yet, somehow, I'm still getting overrun errors.

I've verified that I'm getting RCIF interrupts indepedent
of TMR1IF interrupts.

Clues?

Thanks!
  Bill

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spam_OUTlistservTakeThisOuTspammitvma.mit.edu with SET PICList DIGEST in the body

2004\01\05@163744 by steve

flavicon
face
I've had trouble with that in the past (with a 16F873).
I don't have my notes from the time at hand, or my final solution,
although I know that this will work.
This is done in the foreground (not in the ISR) and I can't remember if I
proved that it matters.
If you experiment further and find the ultimate solution, please share it.
Otherwise, I apologise for the code but it will give you a starting point.

       temp = RCSTA;
       if (temp != 0x90)
       {
           if (temp & 0x04)    // FERR
                   temp = RCREG;
           else
           {
               RCSTA = 0x80;
               RCSTA = 0x90;
           }
       }


Steve.


==========================================
Steve Baldwin                          Electronic Product Design
TLA Microsystems Ltd             Microcontroller Specialists
PO Box 15-680, New Lynn                http://www.tla.co.nz
Auckland, New Zealand                     ph  +64 9 820-2221
email: .....steveKILLspamspam@spam@tla.co.nz                      fax +64 9 820-1929
=========================================

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservspamKILLspammitvma.mit.edu with SET PICList DIGEST in the body

2004\01\05@164158 by Chris Emerson

flavicon
face
On Fri, Jan 02, 2004 at 11:25:45AM -0800, William Couture wrote:
> I have 3 interrupts that can occur, one is a periodic
> TMR1 interrupt at 2Khz, one is a TX interrupt (very
> occasional), and a RX interrupt (say about about 60 chars
> per second, timed sporaticly), with TX and RX at 115Kbaud
> (so about 1ms per character).

Isn't 115Kbaud about 0.1ms per character?  With 500us of processing on
your timer interrupt, that would explain the overruns.

{Quote hidden}

Does the code for TMR1IF really need to be in the interrupt handler at
all?  Unless it's really that time-critical (which seems unlikely with
that much processing), I'd just set a flag in the isr and let the main
loop handle it.  Depends on application needs, of course.

Chris

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam.....mitvma.mit.edu with SET PICList DIGEST in the body

2004\01\05@164613 by Wouter van Ooijen

face picon face
> Does the code for TMR1IF really need to be in the interrupt handler at
> all?  Unless it's really that time-critical (which seems unlikely with
> that much processing), I'd just set a flag in the isr and let the main
> loop handle it.  Depends on application needs, of course.

No need to handle it in the interrupt at all: TMR1IF can be used as the
flag as long as the corresponding interrupt enable bit is not set.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu with SET PICList DIGEST in the body

2004\01\05@165409 by Igor Pokorny

flavicon
face
You should consider two things. First, you have to clear OERR by clearing
CREN and set it again. Second, if you are not able to read RXreg before
transmition of a new byte starts you got OERR. So, when you try to send two
bytes with a gap that is less than 500 uS you got overrun error. Try to
serve RX interrupt first.

Regards

Igor




{Original Message removed}

2004\01\05@171323 by Olin Lathrop

face picon face
William Couture wrote:
> with TX and RX at 115Kbaud (so about 1ms per character).

Huh?  115.2Kbaud comes out to 11.52Kchar/sec or 89uS per char.

> interrupt void isr()
>    {
>    if (TMR1IF)
>       { /* fairly long processing, but well under 500us */ }

500uS is still a long time when characters could come in at 89uS intervals.

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

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservspamspam_OUTmitvma.mit.edu with SET PICList DIGEST in the body

2004\01\05@200632 by Bill Couture

picon face
On Mon, 5 Jan 2004, Chris Emerson wrote:

> > per second, timed sporaticly), with TX and RX at 115Kbaud
> > (so about 1ms per character).
>
> Isn't 115Kbaud about 0.1ms per character?  With 500us of processing on
> your timer interrupt, that would explain the overruns.

Yup, it does.  I found that myself before I left work, though I didn't
have a chance to update my question before now.

Damn... I drop a value of 10 when dividing in my head.  I must be getting
old...

> >    if (TMR1IF)
> >       { /* fairly long processing, but well under 500us */ }
>
> Does the code for TMR1IF really need to be in the interrupt handler at
> all?  Unless it's really that time-critical (which seems unlikely with
> that much processing), I'd just set a flag in the isr and let the main
> loop handle it.  Depends on application needs, of course.

It's actually about 300us out of the 500us between TMR1 interrupts.

And, yes, it does have to be done in the interrupt.  As noted elsewhere,
I could use the TMR1IF flag to poll when the PID loop needs to execute,
but I found that the resultant jitter could be seen (and heard!) in the
mechanical system.

Bill  {who needs to go review his basic division}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email @spam@listservKILLspamspammitvma.mit.edu with SET PICList DIGEST in the body

2004\01\06@082944 by

picon face
Bill Couture wrote :

> It's actually about 300us out of the 500us between TMR1
> interrupts.
> And, yes, it does have to be done in the interrupt.
> As noted elsewhere, I could use the TMR1IF flag to poll
> when the PID loop needs to execute, but I found that the
> resultant jitter could be seen (and heard!) in the
> mechanical system.

Note that it isn't a choice between doing *everything* in
the ISR and doing *nothing* in the ISR (with regard to the
TMR1 iterrupt).

Let the TMR1IF generate an interrupt (as now). Then in the ISR
just set your own "PID-flag" saying that your PID routine has
to be run now (or rather "soon"). Then leave the ISR and
let your main-loop detect your PID-flag and run the PID
code. During that time, you are able to service other
interrupts like the UART receive interrupt. Make sure that
you make *that* ISR code as short as possible also (just
saving the received byte) so you don't hold up your
PID calculations unnecessarily.

When your PID code is finished, your mail-loop will detect
that there was a byte recevied (through a similiar user-defined
"byte-received-flag"), and your main code can go on
processing *that* task (and still be able to response to
other interrupts).

As have been said many time before, running tasks
*inside* an ISR, doen't give your PIC more processing
cycles to use, it just prevents the PIC from responding
to *other* interrupts during that time...

Use the interrupt sub-system to just *detect* that something
some to be done, then let your main code do the actual
processing. You'll get a much smoother flow in your
application and less chance to "miss" an event.

Best Regards
Jan-Erik.

--
http://www.piclist.com hint: To leave the PICList
KILLspampiclist-unsubscribe-requestKILLspamspammitvma.mit.edu

2004\01\06@083359 by hael Rigby-Jones

picon face
>-----Original Message-----
>From: Jan-Erik Soderholm XA (TN/PAC)
>[RemoveMEjan-erik.xa.soderholmTakeThisOuTspamERICSSON.COM]
>Sent: 06 January 2004 13:27
>To: spamBeGonePICLISTspamBeGonespamMITVMA.MIT.EDU
>Subject: Re: [PIC:] getting serial overrun on 16F877 in HT PICC?

>Let the TMR1IF generate an interrupt (as now). Then in the ISR
>just set your own "PID-flag" saying that your PID routine has
>to be run now (or rather "soon"). Then leave the ISR and let
>your main-loop detect your PID-flag and run the PID code.
>During that time, you are able to service other interrupts
>like the UART receive interrupt.

Note that there is no need to even have an interrupt if it's only purpose is
to set a flag. Simple using the TMR1IF flag in the main loop will work fine
without the extra interrupt overhead.

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.
=======================================================================
Any questions about Bookham's E-Mail service should be directed to
TakeThisOuTpostmasterEraseMEspamspam_OUTbookham.com.

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestspamTakeThisOuTmitvma.mit.edu

2004\01\06@090311 by

picon face
Michael Rigby-Jones wrote :

> >Let the TMR1IF generate an interrupt (as now). Then in the ISR
> >just set your own "PID-flag" saying that your PID routine has
> >to be run now (or rather "soon"). Then leave the ISR and let
> >your main-loop detect your PID-flag and run the PID code.
> >During that time, you are able to service other interrupts
> >like the UART receive interrupt.
>
> Note that there is no need to even have an interrupt if it's
> only purpose is to set a flag. Simple using the TMR1IF flag
> in the main loop will work fine without the extra interrupt
> overhead.

Correct. Maybe I was thinking of one project of my
own where I did something similar. In that case I actulay
had *some* processing in the TMR-ISR. Such as updating an
secondary counter and, if *that* also overflowed, set an
second flag for another task to be run and re-initalized
that counter. Then I leaved the ISR to let the mail code
process one (or sometimes two) tasks.

Anyway, my main point is that stuffing to much into the ISR,
doesn't make you PIC run faster, it just prevents *other*
interrupts to be serviced timely...

Jan-Erik.

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestEraseMEspam.....mitvma.mit.edu

2004\01\06@183345 by Bill Couture

picon face
On Tue, 6 Jan 2004, Jan-Erik Soderholm XA (TN/PAC) wrote:

{Quote hidden}

Actually, the original code was implemented by using TMR1IF as
a "do PID now" flag, no interrupt necessary.

I found that the PID *HAD* to be in the interrupt, *IN IT'S ENTIRETY*
(otherwise, the part of the PID that was not in the interrupt had
to look for it's flag, and there was no advantage to having ANY of the
PID in the interrupt).

The background loop has a fair amount of processing (none of it time
critical), and the jitter associated with getting around to see if
the PID flag was set could be seen in the mechanical system (and even
heard!).

Since the PID is in the interrupt, it runs EXACTLY on schedule.  Although,
there is some jitter, based on the values in the loop.  For example, with
PID, Kp, and delta_position all long ints
  PID += Kp * delta_position;
is *MUCH* slower (about a factor of 2) if delta_position is negative
intead of positive. In fact, if you do it right, you can save processing
time with statements like
  pos_delta_pos = (current - desired);
  neg_delta_pos = (desired - current);
  if (current > desired)
     PID += Kp * pos_delta_pos;
  else
     PID -= Kp * neg_delta_pos;
(you do have to be careful that you don't spend more time saving time,
but if you're careful you can save considerable time.)

Bill

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspammitvma.mit.edu

2004\01\07@040939 by

picon face
Bill Couture wrote :

> I found that the PID *HAD* to be in the interrupt, *IN IT'S ENTIRETY*
> (otherwise, the part of the PID that was not in the interrupt had
> to look for it's flag,

No, the main-loop should do the flag-checking that and call the
PIC code when needed.

> and there was no advantage to having ANY of the
> PID in the interrupt).

Maybe...

But...
You also said that you missed bytes on the serial link
sometimes, didn't you ?

That is, as I understand things, becuse you have locked-up
the PIC in the PID-ISR for a to long time (with regard to
the response time needed to not miss anything on the serial
link).


> The background loop has a fair amount of processing (none of it time
> critical), and the jitter associated with getting around to see if
> the PID flag was set could be seen in the mechanical system (and even
> heard!).
>
> Since the PID is in the interrupt, it runs EXACTLY on
> schedule.

But that wasn't the problem, was it ? Was it not the
missed bytes on the serial link that was the problem ?
Anyway, that was what I was trying to address...

Jan-Erik.

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2004\01\07@041807 by

picon face
Hi again, just another small note...

Bill Couture wrote :

{Quote hidden}

This app is written in C, right ?
Maybe you could speed up the PID calculation by
re-writing it in optimized ASM and calling that from
your C code ?

Jan-Erik.

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

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