|
|
View previous topic :: View next topic |
Author |
Message |
che_chia
Joined: 09 May 2011 Posts: 6
|
RS-485 -- Can not Receive the data completely |
Posted: Tue May 17, 2011 3:15 am |
|
|
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: 19515
|
|
Posted: Tue May 17, 2011 3:48 am |
|
|
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 |
|
|
|
|
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
|