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 support@ccsinfo.com

INT_RDA not detected, need more help

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



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

INT_RDA not detected, need more help
PostPosted: Mon Oct 13, 2003 10:08 pm     Reply with quote

Hi,

I read a previous post where it was said that the USART could get an overrun error

I would like to know how I can detect this error. In my program I am using the INT_RDA interrupt sometimes this interrupt is not generated, one of the remedies suggested was that the #use rs232 directive must contain the ERROR parameter, this would clear the error bits.

It was also suggested that I should clear the bit manually twice , by polling for the error bit..

Kindly advise how I can do this.....??


thanks
arun

NOTE: The use of the error parameter has improved the performance of the communication of my application, although I notice the problem is still there...
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Oct 14, 2003 12:25 pm     Reply with quote

It's not feasible to help you if we doesn't know:

1) The compiler version.
2) The microcontroller you are using.
3) The header and configuration settings.
4) The lines of codes involved in the problem.
5) The routine to service #INT_RDA.
6) Minimum hardware description.

Regards,

Humberto
mfilion



Joined: 17 Sep 2003
Posts: 1
Location: Montreal, Canada

View user's profile Send private message

Re: INT_RDA not detected, need more help
PostPosted: Tue Oct 14, 2003 2:56 pm     Reply with quote

arunb wrote:
Hi,

I read a previous post where it was said that the USART could get an overrun error

I would like to know how I can detect this error. In my program I am using the INT_RDA interrupt sometimes this interrupt is not generated, one of the remedies suggested was that the #use rs232 directive must contain the ERROR parameter, this would clear the error bits.

It was also suggested that I should clear the bit manually twice , by polling for the error bit..

Kindly advise how I can do this.....??


thanks
arun

NOTE: The use of the error parameter has improved the performance of the communication of my application, although I notice the problem is still there...


You could poll the changes on the RS-232_ERRORS variable that is generated by the #USE RS232
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Oct 14, 2003 3:52 pm     Reply with quote

This is right out of the data sheet.

RCSTAx: RECEIVE STATUS AND CONTROL REGISTER
bit 7 SPEN: Serial Port Enable bit
1 = Serial port enabled (configures RX/DT and TX/CK pins as serial port pins)
0 = Serial port disabled
bit 6 RX9: 9-bit Receive Enable bit
1 = Selects 9-bit reception
0 = Selects 8-bit reception
bit 5 SREN: Single Receive Enable bit
Asynchronous mode:
Don’t care
Synchronous mode - Master:
1 = Enables single receive
0 = Disables single receive
This bit is cleared after reception is complete.
Synchronous mode - Slave:
Don’t care
bit 4 CREN: Continuous Receive Enable bit
Asynchronous mode:
1 = Enables receiver
0 = Disables receiver
Synchronous mode:
1 = Enables continuous receive until enable bit CREN is cleared (CREN overrides SREN)
0 = Disables continuous receive
bit 3 ADDEN: Address Detect Enable bit
Asynchronous mode 9-bit (RX9 = 1):
1 = Enables address detection, enables interrupt and load of the receive buffer
when RSR<8> is set
0 = Disables address detection, all bytes are received, and ninth bit can be used as parity bit
bit 2 FERR: Framing Error bit
1 = Framing error (can be updated by reading RCREG register and receive next valid byte)
0 = No framing error
bit 1 OERR: Overrun Error bit
1 = Overrun error (can be cleared by clearing bit CREN)
0 = No overrun error
bit 0 RX9D: 9th bit of Received Data
This can be Address/Data bit or a parity bit, and must be calculated by user firmware


So to test for framing errors


Code:

if(bit_test(RS232_ERRORS,2))                          // Found Framing Errors
     
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 14, 2003 10:23 pm     Reply with quote

Hi,

The details are given below, please note that the error still comes up even while using the ERRORS parameter, also when it is cleared.

Please suggest how I can clear /reset the USART module..

thanks
arun

Compiler Version : PCM 3.169
Microcontroller : PIC 16F877


#use delay(clock=4000000)
#use fast_io(B)
#use fast_io(D)
#use fast_io(A)
#use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7,parity=n,brgh1ok,errors)

void main()
{

initialise();

do
{
restart_wdt();

if (RS232_ERRORS!=0)
RS232_ERRORS=0; //To clear the error


if (bShowField==1)
{
showfielddata();
bShowField=0;
}


} while(TRUE);

}


#INT_RDA
usart_isr()
{
disable_interrupts(INT_TIMER1);

if (nUSARTCmd==0)
get_command(getc());
else
process_command(getc());

enable_interrupts(INT_TIMER1);
}
mcafzap



Joined: 07 Sep 2003
Posts: 46
Location: Manchester, UK

View user's profile Send private message

RS232
PostPosted: Wed Oct 15, 2003 5:48 am     Reply with quote

I use the following, within the 'main' loop, to pick up both overrun and framing errors:


#byte RCSTA = 0x18
#byte RCREG = 0x1A

if (RCSTA & 0x06){
RCSTA = 0x80;
j = RCREG;
j = RCREG;
j = RCREG;
RCSTA = 0x90;
}



Steve
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Wed Oct 15, 2003 7:34 am     Reply with quote

Hi,

How does one clear the error ??? also how to prevent it.????

cheers
arun
Ttelmah
Guest







PostPosted: Wed Oct 15, 2003 7:49 am     Reply with quote

arunb wrote:
Hi,

How does one clear the error ??? also how to prevent it.????

cheers
arun

You prevent the error, by ensuring that you service the interrupt quickly enough. The commonest reasons for overrun errors, are having large sections of the main code with interrupts disabled, or putting too much code in the interrupt handler. It is important to realise, that if you call a function in the interrupt handler, and the same function inside the main code, then the compiler will disable interrupts inside this function in the main code (since it does not support re-entrancy).
You clear the error, by disabling the 'continuous receive' bit in the UART, re-enabling it, and reading the characters that are waiting in the buffers at the time. You can do this in the main code, or in the interrupt handler (the interrupt will be called _once_ with the error flag set, then if the error is not cleared, will not be called again).
The compiler is meant to clear the error automatically, if the 'errors' directive is used, but this still leaves the buffers full, so the interrupt code should check before exiting, if there is another character waiting, or there is a high risk of the error re-asserting very quickly.

Best Wishes
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Oct 15, 2003 9:10 am     Reply with quote

Hi Arunb,

Ttelmah made a brigth description concerning how to prevent frame and overrun errors.
Below you have my small contribution:
I made some changes in your code. I assume you are receiving a char, not a string.

Best wishes,

Humberto

Code:


#use delay(clock=4000000)
#use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7,errors)
#use fast_io(B)
#use fast_io(D)
#use fast_io(A)

void main()
{

initialise();

   do
     {
       restart_wdt();

       if (RS232_ERRORS!=0)
       RS232_ERRORS=0; //To clear the error

       if (bShowField==1)
         {
           showfielddata();
           bShowField=0;
         }

      if (get_command)
         {
           disable_interrupts(INT_RDA;
           // your function().....

           get_command = FALSE;
         }

      if (process_command)
         {
           disable_interrupts(INT_RDA;
          // your function().....

           process_command = FALSE;
         }
 
    } while(TRUE);
}

// Keep your isr as short as possible and don´t call any
// function, just set a flag.
#INT_RDA
usart_isr()
{
 int rcved_char;

  disable_interrupts(INT_TIMER1);

  if (nUSARTCmd==0)
     {
       rcved_char = getc();
       
       if (rcved_char == 'X')            //   Where 'X' the char expected
         {
          get_command = TRUE;
         }
       else
         {
          process_command = TRUE;
         }
     }
     
 enable_interrupts(INT_TIMER1);
}

Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 15, 2003 9:30 am     Reply with quote

The code posted could still present problems since you are not always reading the char when the int occurs. Also it is not necessary to disable interrupts inside an interrupt.

Code:

#INT_RDA
usart_isr()
{
  int rcved_char;

  if (kbhit())
  {
    rcved_char = getc();
    if (nUSARTCmd==0)
    {
      if (rcved_char == 'X')            //   Where 'X' the char expected
      {
        get_command = TRUE;
      }
      else
      {
        process_command = TRUE;
      }
    }
  }
}


Mark
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Wed Oct 15, 2003 10:11 am     Reply with quote

This routine checks for a framing error that indicates a bad baud rate. The bad baud rate indicates a need to change baud on the fly. Dealing with an overrun error should be just as easy. Remember you must always clear the buffer for a new byte by reading the it. The errors are cleared by the built in getc() function and stored in RS232_ERRORS. If you assemble this you will see that it is a very small routine.

Code:

// Channel A Receive Interrupt
#int_RDA                                                 //**************
RDA_isr()                                                // BYTE RECIEVED
{  int8 x;                                               // Create byte storage
   x = fgetC( chanA );                                   // Get incomming byte from buffer
   if(bit_test(RS232_ERRORS,2))                          // Found Framing Errors
   {  ++ChA_Errors;
      if(ChA_Errors & 8)
      {  ChA_Errors=0;
         ChA_Change_Baud();                              // Jump to a new baud rate
      }
   }
   else
   {  ChA_PacketBuffer[ChA_PacketIndex++] = x;           // Place incomming byte in PacketBuffer
      if( bit_test(ChA_PacketIndex,6))                   // If packet index larger than packetbuffer (64)
         ChA_PacketIndex = 0;                            // Zero packet index value
   }
}
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE
PostPosted: Wed Oct 15, 2003 9:49 pm     Reply with quote

Hi,

Thank you very much for the help.

You say the error is due to a bad baud rate, I am using a 4 MHz xtal , will changing to 20 Mhz improve things ???

cheers
arun
Pete Smith



Joined: 17 Sep 2003
Posts: 55
Location: Chester, UK

View user's profile Send private message Visit poster's website MSN Messenger ICQ Number

Re: RE
PostPosted: Thu Oct 16, 2003 3:38 am     Reply with quote

arunb wrote:
Hi,

Thank you very much for the help.

You say the error is due to a bad baud rate, I am using a 4 MHz xtal , will changing to 20 Mhz improve things ???

cheers
arun


Your best bet is to switch to a crystal that is a multiple of a baud rate.

We use 1.8432MHz crystals, because you can get all the common baud rates from this, eg divide it by 192 to get 9600 etc.

If you need ~4MHz, then go for a 3.6864MHz one. If you actually want 20MHz, try a 18.432MHz one.

HTH

Pete.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Thu Oct 16, 2003 6:15 am     Reply with quote

For a 20MHz or a 4MHz clock and 9600 baud rate, the error rate if 0.16% which is fine. You actual baud rate will be 9615.

Your orginal routine did not always read the data byte from the receive register. This is important to do or else you won't get another int!
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: RE
PostPosted: Thu Oct 16, 2003 8:05 am     Reply with quote

arunb wrote:
Hi,

Thank you very much for the help.

You say the error is due to a bad baud rate, I am using a 4 MHz xtal , will changing to 20 Mhz improve things ???

cheers
arun


The routine I posted checks for a framing error indicating a bad baud rate. An overrun error is a different error all together. A framing error means that the bit time within the received byte is wrong. An overrun error indicates that a byte was shifted in and placed in the received byte register before the last byte received was read from that buffer. This means the bytes are coming in faster than they are being removed from the buffer. An overrun error means you missed a byte in the incoming data stream.

Changing to a crystal that is 5 times faster will help prevent overruns because you can read from the buffer 5 times faster. The baud rate error will also be lessened and should eliminate framing errors.
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