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

question of getc()

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



Joined: 12 Dec 2003
Posts: 16

View user's profile Send private message

question of getc()
PostPosted: Mon Apr 12, 2004 6:36 pm     Reply with quote

I have got a problem with getc() when I use RS3227 data output -----> RS232 data input.

It is often stuck on the third getc(), I check the manual, it wrote:

If a built-in USART is used the hardware can buffer 3 characters otherwise GETC must be active while the character is being received by the PIC.

Is the above reason why I got stuck on the third getc()? How can I solve this problem? How can I 'active' as the manual mentioned?

Thanks,
Oliver
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Mon Apr 12, 2004 7:14 pm     Reply with quote

PIC can buffer two charcters. If it receives a third character before the software reads the previous one it will report an overrun error and stop receiving anymore data:

Quote:

The RCREG is a double buffered register (i.e., it is a two deep FIFO). It is possible for two bytes of data to be received and transferred to the RCREG FIFO and a third byte to begin shifting to the RSR register. On the detection of the STOP bit of the third byte, if the RCREG register is still full, the overrun error bit OERR (RCSTA<1>) will beset. The word in the RSR will be lost. The RCREG register can be read twice to retrieve the two bytes in the FIFO. Overrun bit OERR has to be cleared in software.
This is done by resetting the receive logic (CREN is cleared and then set). If bit OERR is set, transfers from the RSR register to the RCREG register are inhibited, and no further data will be received. It is therefore, essential to clear error bit OERR if it is set.


You may not be reading the data from the receive buffer fast enough. Check the OERR bit and see if it getting set.
Oliver
Guest







How to clean and set CREN
PostPosted: Tue Apr 13, 2004 11:33 am     Reply with quote

Hi, Ali:

Thanks for your reply, it is really helpful!

Would you tell me how to cleared and set CREN with CCS compiler?
I want to try it.

Oliver
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: How to clean and set CREN
PostPosted: Tue Apr 13, 2004 11:47 am     Reply with quote

Oliver wrote:
Hi, Ali:

Thanks for your reply, it is really helpful!

Would you tell me how to cleared and set CREN with CCS compiler?
I want to try it.

Oliver


Using the ERRORS option when declaring the serial port will cause the compiler to do this automaticly.

You can also access the OERR and FERR from the RS232_ERRORS byte.
DragonPIC



Joined: 11 Nov 2003
Posts: 118

View user's profile Send private message

gets()
PostPosted: Tue Apr 13, 2004 12:46 pm     Reply with quote

You could try using gets(). This will receive a string of characters until a RETURN is received. If this is not an option, try using some sort of handshaking to let the transmitter know the receiver is ready to receive another byte.

//transmitter

printf("a"); //or putc('a');
getc();
printf("b");
getc();
printf("c");
getc();

//receiver
char data;
data = getc();
printf("1");
do_something(data);
data = getc();
printf("1");
do_something(data);
data = getc();
printf("1");
do_something(data);
Oliver Lai



Joined: 12 Dec 2003
Posts: 16

View user's profile Send private message

my source code
PostPosted: Tue Apr 13, 2004 7:07 pm     Reply with quote

Thanks ALL for very helpful advices!

I have added ERROR option in my program, but still have got stuck. The transmiter side is out of my control, I can just received data stream, eg. 10 02 9D 03 45 56 78 91 F0 67 4D EB 10 03, totally 14 bytes, the first two 10 20 are start bytes, the next two 9D 03 are function bytes (9D 06 are another function for example), 10 03 are stop bytes.

Below is my code, it is quite simple:

Code:


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <input.c>
#include <lcd.c>
#include <readFloat64.c>

unsigned int dataArray[15], data1, data2, data3, data4;
int stop=1, i, j=0;
float flowRate;

void main() {

   lcd_init();

   while (stop) {

      dataArray[0] = getc();                    //sometimes it stuck here
      if (dataArray[0] == 0x10) {
         dataArray[1] = getc();
         if (dataArray[1] = 0x02) {
            for (i=2; i< 15; i++)                 //The most it stuck here
            dataArray[i] = getc();

            if (dataArray[2] == 0x9D && dataArray[3] == 0x03) {
               data1 = dataArray[12];
               data2 = dataArray[11];
               data3 = dataArray[10];
               data4 = dataArray[9];

               flowRate = READ_FLOAT(data1, data2, data3, data4);
               flowRate = 3600*flowRate;
               if (j%10) {
                  lcd_gotoxy(1,1);
                  printf (LCD_PUTC, "FR: %12.8f", flowRate);
                }
                j++;
            }
         }
      }
   }
}



When starting to run the program, sometimes it can start immediately, sometimes have to be pressed RESET until it works. After the program works properly, it will be stucked in 2 minutes or longer.

By the way, from the transmitter it is RS3227, the receiver is SP232A (similar to MAX232).

The baud rate is 57600

Any advises and test suggestions to find why it stuck!
Thanks,
Oliver
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Apr 13, 2004 8:36 pm     Reply with quote

I would gess that it is hung on the LCD and not the serial port at all. If you have the printf statement changed to print a static value does it still hang? If you just print random values without the serial port involved does it still hang?
Humberto



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

View user's profile Send private message

PostPosted: Tue Apr 13, 2004 8:55 pm     Reply with quote

Quote:

#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)


Why do you make a UART hardware setup and then you never enable the interrupt
to handle it ?


Quote:

I have added ERROR option in my program, but still have got stuck. The transmiter side is out of my control, I can just received data stream, eg. 10 02 9D 03 45 56 78 91 F0 67 4D EB 10 03, totally 14 bytes, the first two 10 20 are start bytes, the next two 9D 03 are function bytes (9D 06 are another function for example), 10 03 are stop bytes.



It will be easier to receive and store the stream in a buffer and then you will recover the data to analize it.

Code:

// your packet
// DLE STX Dd Dd Dd Dd Dd Dd Dd Dd Dd Dd DLE ETX
//
#define Buffer_Size         14
#define Header             STX
#define Trailer            ETX

#INT_RDA
void isr_serial_rcv()
{
int char rcved;
 
       char_rcved = getc();

       if( !data_valid )
         {
           if( char_rcved == Header)    // Start of mssge flag
             {
               next_in = 1; 
               dataArray[next_in] = char_rcved;   
               data_valid = TRUE;
             }
         }
       else
         {
          next_in++;
                   
          if( next_in > Buffer_Size )
            {
             data_valid = FALSE;       // Stop receiving
             next_in = Buffer_Size;
            }
          if( char_rcved == Trailer ) // End of mssge flag
            {
             data_valid = FALSE;
            }
          if( !data_valid )
            {
             stream_complete = TRUE; // We get full mssge !!!       
            }
          dataArray[next_in] = char_rcved;
         }
}

//------------------------------------------------------------
//------------------------------------------------------------

void main()
{
 stream_complete = FALSE;
 data_valid = FALSE;
 enable_interrupts(INT_RDA);
 enable_interrupts(GLOBAL);
 
 while()
   {
    // do other stuff ...  while stream_complete == FALSE

   if( stream_complete )
     {
       disable_interrupts(INT_RDA);
   
    // Disable receiving further char while
    // analising the received stream
     
      if(( dataArray[2]==0x9D) && (dataArray[3]==0x03))
        {
           data1 = dataArray[12];
           data2 = dataArray[11];
           data3 = dataArray[10];
           data4 = dataArray[9];
           ....................
           // your code...
           ....................
        }
       enable_interrupts(INT_RDA);
     }
   }
}

//------------------------------------------------------------
//------------------------------------------------------------


Hope you understand the idea,

Humberto
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