CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

OERR bit on PIC18F4525

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Nono



Joined: 16 Sep 2008
Posts: 3
Location: France

View user's profile Send private message

OERR bit on PIC18F4525
PostPosted: Tue Sep 16, 2008 9:27 am     Reply with quote

Hello everybody,

I've looking answers for my problem on your forum and found a lot of good things, but nothing to solve it.

Here is my config :
MPLAB v7.42, PIC18LF4525 @ 20MHz, 3.3V, baud rate @57600, CCS compiler v4.078.

The problem is that sometimes I have an overflow error (OERR bit) on the communication line. There are only two activated interruptions (RDA and Timer2) in my program and a big main. The timer2 is used with the PWM1 to manage a motor (frequency of PWM : 19.5kHz).
First I thought it was due to the speed of the serial com, but even with a speed @9600bds, the problem is still here.
Then I wanted to use the priority level of the PIC. I put the HIGH_INTS=TRUE in my code and the keyword HIGH after the #INT_RDA but the compile failed with the error "Invalid Pre-Processor directive". If I don't use the keyword HIGH, the IPEN = 1 but RCIP = 0 (low level) and there are no line code @ vector 0x0008 (normally the high-priority interruption vector).

Code:
#INT_RDA
void receive_isr (void)
{
   do
   {
      m_cBufferFifo[m_message.nIndexWrite]   =   RCREG;
      
      if(OERR)
      {   //error reset module
         CREN=0;
         CREN=1;
         m_message.bError = 1;
      }
      if (FERR)
      {
         m_message.bError = 1;
      }
   
      m_message.nIndexWrite++;
         
      if(m_message.nIndexWrite >= MAX_BUFFER_FIFO)
         m_message.nIndexWrite=0;   
      
      if(m_message.nIndexWrite == m_message.nIndexRead)
         m_message.bError = 1;
   } while (kbhit());
   RCIF = 0;
}

#INT_TIMER2
void moteur_isr ()
{
   //timer system
   m_lPerTimer2Module   +=VAL_PR2/2;
   m_lPerTimer2Module++;
   if (m_lPerTimer2Module>=INT_TIMER2_TIME_FACTOR)    //with Prescale to 1
   {
      m_lPerTimer2Module   -=   INT_TIMER2_TIME_FACTOR;
      m_lOverflowCounterTmr2++;    //current time
   }

   TMR2IF = 0;
}


Maybe can I change the 20MHz crystal by a 10MHz crystal and activate the x4 PLL inside the PIC in order to have better computing performances ?

It will be great if anyone could help me.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Sep 17, 2008 4:52 pm     Reply with quote

Your code is not complete so it is possible there are problems in other parts of your code.

Your RDA interrupt routine doesn't look like it is the problem. Including the interrupt overhead it is about 240 instructions, at 20MHz that allows you to receive 20.800 characters per second. With a baudrate of 57.600 you receive a maximum of about 5700 characters, much less than the ISR can handle.

Are you sure it is the OERR flag that's causing you troubles? You are setting the same bError flag for different types of errors. It will be a good thing to make sure you are not hunting the wrong problem. See also the bug described below that might well be the cause of your problems.

I only see one problem in your code:
Code:
      if(m_message.nIndexWrite == m_message.nIndexRead)
         m_message.bError = 1;
Here you detect the error of your ring buffer being full but there is no code to prevent overflow of the ringbuffer. After setting the error flag the next received character will be written to the ring buffer, nIndexWrite is increased and many nasty buffer overwrites will happen before you detect the error again.

Try changing to:
Code:
...
      if (FERR)
      {
         m_message.bError = 1;
      }
   
      temp = m_message.nIndexWrite;          // added a temp variable

      m_message.nIndexWrite++;
      if(m_message.nIndexWrite >= MAX_BUFFER_FIFO)
         m_message.nIndexWrite=0;   
     
      if(m_message.nIndexWrite == m_message.nIndexRead)
      {
         m_message.bError = 1;
         m_message.nIndexWrite = temp;     // in case of overflow set the pointer back to last position
      }


The HIGH interrupt is not going to solve your problem when you only have these two interrupts. With the high priority interrupt you can interrupt the other interrupts when these are active but your timer2 interrupt is very fast, no need to add the overhead of the high priority interrupt.
Nono



Joined: 16 Sep 2008
Posts: 3
Location: France

View user's profile Send private message

PostPosted: Thu Sep 18, 2008 2:56 am     Reply with quote

thanks for your answer ckielstra. I really think that the problem is coming from the OERR because I put a breakpoint everywhere in the interrupt and it stops on the OERR fault. I will try your code.
Nono



Joined: 16 Sep 2008
Posts: 3
Location: France

View user's profile Send private message

PostPosted: Thu Oct 02, 2008 10:54 am     Reply with quote

I found the problem. It was really tricky. It concerns the write in EEPROM. Indeed, all the interruption are disable during a write and I used this function often. That's why the problem appeared randomly.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group