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

RS-485 -- Can not Receive the data completely

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



Joined: 09 May 2011
Posts: 6

View user's profile Send private message

RS-485 -- Can not Receive the data completely
PostPosted: Tue May 17, 2011 3:15 am     Reply with quote

I can receive the data from transceiver completely.


Support it transmited 6 bytes (TXDbuffer[6]) in the transceiver, as

TXDbuffer[0] =0x01
TXDbuffer[1] =0x02
TXDbuffer[2] =0x03
TXDbuffer[3] =0x04
TXDbuffer[4] =161 // This value is got from CRC operation
TXDbuffer[5] =43 // This value is got from CRC operation

In my code, I can receive TXDbuffer[0]~TXDbuffer[4], but can't receive TXDbuffer[5] and TXDbuffer[6] currently. Should I clear the serial buffer?

My code as following:

Code:

#include <16F1947.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT
#Fuses INTRC_IO
#use delay(clock=32000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)

unsigned int uchCRCHi, uchCRCLo;
unsigned int8 TXDbuffer[6];
unsigned int8 RXDbuffer[6];
unsigned int8 RevCnt=0;

unsigned int const auchCRCHi[256] = {//CRC Matrix};
unsigned int const auchCRCLo[256] = {//CRC Matrix };

void xor_check(unsigned int *puchMsg, unsigned int crc_count)
{
   unsigned int uindex;   
   uchCRCHi = 0xff;
   uchCRCLo = 0xff;
   while( crc_count )
  {
      uindex = uchCRCHi ^ *puchMsg;
      puchMsg++;
      uchCRCHi = uchCRCLo ^ auchCRCHi[uindex];
      uchCRCLo = auchCRCLo[uindex];         
     crc_count--;
   }
}

#INT_RDA
void serial_isr()   
{
  unsigned int RevTempData;
  if( kbhit() )
   {
     RevTempData=getc();
     if (RevCnt==0 && RevTempData==0x01)
       {
         RXDBuffer[0]=RevTempData;
         RevCnt++;
        }
     else if (RevCnt>=1 && RevCnt<=5)
       {
         RXDBuffer[RevCnt]=RevTempData;
         RevCnt++;
        }
     else if (RevCnt>=6)
       {
         RevCnt=0;   
         xor_check((unsigned int *)RXDBuffer, 4);
        }
    }
}

void main (void)
{
  enable_interrupts(INT_RDA);
  enable_interrupts(GLOBAL);   
  output_bit(PIN_G0,0);
  while(1)
  {}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Tue May 17, 2011 3:48 am     Reply with quote

First, there is no need for the kbhit in the INT_RDA. The interrupt triggers _because_ there is a character ready to receive.
Second, add 'errors' to your RS232 declaration. This should _always_ be present when using the hardware RS232, unless _you_ are handling hardware overruns. without this the UART can become locked.

Now, big comments. You talk about TXDbuffer[6]. You have no such location in your buffer. In C, by default arrays are zero referenced. Your array is 0 to 5, does not have a location 6....
Then realistically, _do not_ perform the CRC operation in the UART code. You also don't seem to actually do anything with the calculated CRC. Checking it against the received value?. Asking for a re-transmission or throwing away the data if it is wrong?.
The code won't work properly as posted, since you send six bytes, but do not perform the CRC check, till a seventh arrives.

So, something like:
Code:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS)

int1 have_packet=false;
#INT_RDA
void serial_isr()  {
  unsigned int RevTempData;
  RevTempData=getc();
  if (RevCnt==0 && RevTempData==0x01) {
     RXDBuffer[0]=RevTempData;
     RecvCnt++;
  }
  else {
     if (Revcnt>=6) return; //throw data if buffer would overflow
     RXDBuffer[RevCnt]=RevTempData;
     RevCnt++;
     if (RevCnt>=6) have_packet=true;
  }
}

void main (void)
{
  unsigned int8 localbuffer[6];
  rs232_errors=0; //avoid compiler error message for rs232_errors
  enable_interrupts(INT_RDA);
  enable_interrupts(GLOBAL);   
  output_bit(PIN_G0,0);
  do {
     if (have_packet) {
        disable_interrupts(INT_RDA);
        memcpy(localbuffer,RXDbuffer,6);
        have_packet=false;
        RevCnt=0;
        enable_interrupts(INT_RDA); //copy received dats to local storage, and
        //start looking for the next packet
        xor_check(local_buffer,4);
        //need to modify the xor code to verify the CRC matches locations
        //4, and 5, and do something if it doesn't....

     }       
  } while (TRUE); //avoids compiler error message for while loop
}


Best Wishes
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