|
|
View previous topic :: View next topic |
Author |
Message |
kondra
Joined: 23 Sep 2003 Posts: 4
|
CRC |
Posted: Tue Sep 23, 2003 6:23 am |
|
|
HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.
I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources
THX _________________ the next guy has always a better life |
|
|
TSchultz
Joined: 08 Sep 2003 Posts: 66 Location: Toronto, Canada
|
|
Posted: Tue Sep 23, 2003 7:32 am |
|
|
There are a variety of methods used for error detection in a data stream, and as the method gets more reliable, the complexity also increases. What you want to use will depend on your actual application, if you can tolerate a bad packet, and how much code/processor you want to allocate to the task.
For short packets a simple XOR addition works well and requires very little overhead. The reliability is even further improved if the packet is framed. I have a simple protocol I use for multi-drop application that is as follows;
BOF, ID, LEN, ... DATA ... FCS, EOF
BOF = Begining of frame marker
ID = device ID to address
LEN = number of data bytes in packet
DATA = variable number of data bytes, 0 - 60
FCS = XOR addition of ID, LEN, and DATA bytes
EOF = End of frame marker
Here I use only a simple XOR addition, but also the framing must be correct and the ID must also be correct. Using this method I can calculate the FCS on the fly and when I include the received FCS I should have a zero value if the packet is good. In addition I time-out if I have not recieved a full packet within a set amount of time. My receive and transmit routines are interrupt based, and upon reciept of a valid pakcet I set a flag that my main routines sees and the packet is then decoded and handled.
CRC usually involves a more complicated polynomial method but results in better bit error detection. A quick google search will yield a number of sources for such routines. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: CRC |
Posted: Tue Sep 23, 2003 8:05 am |
|
|
kondra wrote: | HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.
I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources
THX |
This works with MODBUS packet formating. This is as highly optimized as I could make it. If you improve on this please be so kind as to post your work. You can read more at www.modbus.org
Code: |
#inline // Inline code runs faster
void Make_Check_CRC(void) // This function can be used to create or check CRC
{ good_crc = 0; // Assume this packet is bad
crcacc = 0xFFFF; // Initialize the CRC accumuliator
PacketIndex = 0; // First byte indexed as zero
while(PacketIndex < PacketSize) // Use all byte except CRC
{ crcdata = PacketBuffer[PacketIndex]; // Use direct addressing on copy of data value
crcacc_lo = crcacc_lo^crcdata;
for(c=8;c>0;c--) // Process the data bits
{ if(LS_BIT_crcacc) // Should XOR be performed
{ crcacc = crcacc >> 1; // Shift CRC 1 bit right load high with 0
crcacc = crcacc^0xA001; // then XOR
}
else
{ crcacc = crcacc >> 1; // Shift CRC 1 bit right load high with 0
}
} // Processed all bits of byte
PacketIndex++; // Advance index to the next byte
} // Solved values for CRC
PacketSize=PacketSize+1; // Index CRC_hi
if((crcacc_lo == PacketBuffer[PacketIndex]) && (crcacc_hi == PacketBuffer[PacketSize]))
good_crc = 1; // The packet recieved was good
}
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Sep 23, 2003 9:18 am |
|
|
Maybe this will shave a couple of instructions off
Code: |
#inline // Inline code runs faster
void Make_Check_CRC(void) // This function can be used to create or check CRC
{ good_crc = 0; // Assume this packet is bad
crcacc = 0xFFFF; // Initialize the CRC accumuliator
PacketIndex = 0; // First byte indexed as zero
while(PacketIndex < PacketSize) // Use all byte except CRC
{ crcdata = PacketBuffer[PacketIndex]; // Use direct addressing on copy of data value
crcacc_lo = crcacc_lo^crcdata;
for(c=8;c>0;c--) // Process the data bits
{
crcacc = crcacc >> 1; // Shift CRC 1 bit right load high with 0
if(LS_BIT_crcacc) // Should XOR be performed
crcacc = crcacc^0xA001; // then XOR
} // Processed all bits of byte
PacketIndex++; // Advance index to the next byte
} // Solved values for CRC
PacketSize=PacketSize+1; // Index CRC_hi
if((crcacc_lo == PacketBuffer[PacketIndex]) && (crcacc_hi == PacketBuffer[PacketSize]))
good_crc = 1; // The packet recieved was good
}
|
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Sep 23, 2003 10:08 am |
|
|
I forgot to include these variable declarations.
Code: |
int16 crcacc; // CRC accumuliator
#byte crcacc_lo = crcacc // Alias name for CRC accumuliator low byte
#byte crcacc_hi = crcacc + 1 // Alias name for CRC accumuliator high byte
#bit LS_BIT_crcacc = crcacc.0 // Alias name for bit zero of CRC accumuliator
|
crcacc can't shift before checking the least bit because it gets shifted out. Sorry for the confusion. I got all excited for a second because this routine eats a lot of time on an irregular interval. Anything I can shave off of this allows the system tick to run faster. I though about trying to multiplex the CRC calculations but it was more than I could manage to solve in an elegant manner. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Sep 23, 2003 10:29 am |
|
|
Sorry, I didn't look that closely at the test expression. Have you ever thought about using a lookup table? Here are some code snippets from some XYModem file transfer routines. It creates a ram based table but this could easily be put into a rom table.
Code: |
/****************************************************************************
InitCRC16 pre-computes a table of constants, using a bitwise algorithm.
These constants allow fast computation of the CRC.
CCITT CRC16 generating polynomial is x^16+x^12+x^5+1, with
binary representation 0x11021. The leading term is implied.
*/
static unsigned int crcTable[256];
static void InitCRC16(void)
{
static int crcDone = 0; /* Only compute it once */
unsigned i, j, crc;
if (crcDone) return;
for(i=0; i <256; i++) {
crc = (i << 8);
for(j=0; j < 8; j++)
crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
crcTable[i] = crc & 0xffff;
}
crcDone = 1;
}
static int XYSendPacket(XYMODEM *pXY, BYTE *pBuffer, int length)
{
int i;
int crc = 0; /* Accumulate CRC for data and padding */
int checksum = 0; /* Accumulate checksum for data and padding */
ASSERT(pBuffer);
ASSERT(pXY);
/* Compute the check value now, so that we don't pause in the middle
of sending to do it. */
if (pXY->crc.enabled) {
for (i=0; i<length; i++)
crc = crcTable[((crc >> 8) ^ pBuffer[i]) & 0xFF] ^ (crc << 8);
for (; i<128; i++)
crc = crcTable[((crc >> 8) ^ SUB) & 0xFF] ^ (crc << 8);
if (i > 128)
for (; i<1024; i++)
crc = crcTable[((crc >> 8) ^ SUB) & 0xFF] ^ (crc << 8);
} else {
for (i=0; i<length; i++) checksum += pBuffer[i];
if (i > 128) checksum += (1024 - i) * SUB;
else checksum += (128 - i) * SUB;
}
/* Clear any garbage from receive queue */
StsRet(XYGobble(pXY,0));
/* start sending the data */
if (length <= 128) StsRet(XYSendByte(pXY, 0x01));
else StsRet(XYSendByte(pXY, 0x02));
StsRet(XYSendByte(pXY, (BYTE)pXY->packetNumber));
StsRet(XYSendByte(pXY, (BYTE)~pXY->packetNumber));
/* Send the data, pad to 128 or 1024 bytes */
StsRet(XYSendBytes(pXY, pBuffer, length));
for (i=length; i < 128; i++) StsRet(XYSendByte(pXY,SUB));
if (i > 128) for (; i<1024; i++) StsRet(XYSendByte(pXY, SUB));
/* Send the check value */
if (pXY->crc.enabled) {
StsRet(XYSendByte(pXY, (BYTE)(crc >> 8)));
StsRet(XYSendByte(pXY, (BYTE)crc));
} else {
StsRet(XYSendByte(pXY, (BYTE)checksum));
}
StsRet(XYWaitForSentBytes(pXY));
return xyOK;
}
static int XYReceivePacket(XYMODEM *pXY, int *pPacketNumber,
BYTE *pBuffer, long *pLength)
{
BYTE startOfPacket = 0;
BYTE packet = 0;
BYTE packetCheck = 0;
ASSERT(pPacketNumber);
ASSERT(pBuffer);
ASSERT(pXY);
/* This loop searches the incoming bytes for a valid packet start. */
/* This reduces our sensitivity to inter-packet noise. */
/* We also check here for EOT and CAN packets. */
StsRet(XYReadBytesWithTimeout(pXY,pXY->timeout,&packetCheck,1));
if (packetCheck == EOT) return xyEOT;
do {
startOfPacket = packet; packet = packetCheck;
StsRet(XYReadBytesWithTimeout(pXY,pXY->timeout,&packetCheck,1));
if ((packetCheck == CAN) && (packet == CAN)) return StsWarn(xyFailed);
} while ( ( (startOfPacket != 0x01) && (startOfPacket != 0x02) )
|| ( ((packet ^ packetCheck) & 0xFF) != 0xFF ) );
/* We've received a valid packet start, receive the packet data */
if (startOfPacket == 0x01) *pLength = 128;
else *pLength = 1024;
StsRet(XYReadBytesWithTimeout(pXY,2,pBuffer,*pLength));
*pPacketNumber = packet;
/* Compute the check value and compare it to the received one. */
if (pXY->crc.enabled) {
unsigned crc = 0;
long length = *pLength;
BYTE crcByte;
unsigned rxCRC;
while (length-- > 0) /* Accumulate CRC */
crc = crcTable[((crc >> 8) ^ *pBuffer++) & 0xFF] ^ (crc << 8);
crc &= 0xFFFF;
StsRet(XYReadBytesWithTimeout(pXY,2,&crcByte,1));
rxCRC = (crcByte & 0xFF) << 8;
StsRet(XYReadBytesWithTimeout(pXY,2,&crcByte,1));
rxCRC |= (crcByte & 0xFF);
if (crc != rxCRC) return StsWarn(xyBadPacket);
} else {
unsigned checksum = 0;
BYTE receivedChecksum;
long length = *pLength;
while (length-- > 0) /* Accumulate checksum */
checksum += *pBuffer++;
checksum &= 0xFF;
StsRet(XYReadBytesWithTimeout(pXY,2,&receivedChecksum,1));
if ((BYTE)checksum != receivedChecksum) return StsWarn(xyBadPacket);
}
pXY->crc.certain = TRUE; /* Checksum/crc mode is now known */
if (*pLength > 128) {
pXY->longPacket.enabled = TRUE;
pXY->longPacket.certain = TRUE;
}
return xyOK;
}
|
|
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Wed Sep 24, 2003 8:58 am |
|
|
you could use the dallas onewire CRC algorithm -- quick to run, easy to implement, very few instructions, no ROM space lost, very little RAM required, no fuss, no muss, It Just Works...
Code: |
int onewire_crc(int oldcrc, int newbyte) {
// see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf
int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8; j++) { // for each bit
data_bit = (newbyte >> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}
|
ps, my onewire primitives library is here:
http://losdos.dyndns.org:8080/public/onewire/lib-onewire.html
regards.
jds-pic |
|
|
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
Re: CRC |
Posted: Wed Sep 24, 2003 11:52 am |
|
|
kondra wrote: | HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.
I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources |
XOR
|
|
|
dvdb
Joined: 12 Jan 2004 Posts: 6 Location: Brussels, Belgium
|
|
Posted: Mon Jan 12, 2004 1:38 pm |
|
|
jds-pic wrote: | you could use the dallas onewire CRC algorithm -- quick to run, easy to implement, very few instructions, no ROM space lost, very little RAM required, no fuss, no muss, It Just Works...
Code: |
int onewire_crc(int oldcrc, int newbyte) {
// see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf
int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8; j++) { // for each bit
data_bit = (newbyte >> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}
|
ps, my onewire primitives library is here:
http://losdos.dyndns.org:8080/public/onewire/lib-onewire.html
regards.
jds-pic |
Hi,
This a my asm implementation for the same CRC.
It is about 10X faster, 30 bytes less code and used no RAM.
It's based on http://www.dattalo.com/technical/software/pic/crc_8bit.c which exploits a pecularity of this particular polynomial described in http://pdfserv.maxim-ic.com/en/an/app27.pdf.
This allows bytewise processing without bit shifting.
I ported the algorith to asm, it turns out this can be done with no additional RAM, and with bit twiddling only in w, so its very fast and dense code.
Don't work too hard!
Code: |
int calc_CRC(int* data,int byte_cntr)
{
int crc=0;
#ASM
MOVF DATA,W //copy pointer to first databyte..
MOVWF FSR //..to pointer register
loop:
MOVF INDF,W //load w with next databyte
xorwf crc,f // xor with accumulated crc (accumulated crc is no longer valid now)
movlw 0 //w will ccumulate the new crc
btfsc crc,0
xorlw 0x5e //could also be iorlw
btfsc crc,1
xorlw 0xbc
btfsc crc,2
xorlw 0x61
btfsc crc,3
xorlw 0xc2
btfsc crc,4
xorlw 0x9d
btfsc crc,5
xorlw 0x23
btfsc crc,6
xorlw 0x46
btfsc crc,7
xorlw 0x8c
movwf crc //store accumulated crc
INCF FSR //increment indirection register to point to next databyte
decfsz byte_cntr,F
goto loop //next databyte
//done, crc is in w
movwf crc //store in result
#ENDASM
return(crc);
} |
_________________ Dirk Van den Berge |
|
|
rrb011270
Joined: 07 Sep 2003 Posts: 51
|
|
Posted: Tue Jan 13, 2004 6:33 pm |
|
|
Mabuhay!
I guess the better way to trust your data for a data communication is use the method called CRC (cyclic redundancy check). Their are many CRC method one is the basic XOR calculation, the other is to use polynomial CRC calculation.
The program code below use the XOR method to calculate checksum or CRC
Code: |
void convertData_ToAscii() // convert RFdata to ascii for serial xmit
{
char cHexBuff[2]; // temp hex buffer
char cDtaBuff[20]; // data buffer for time, date, log, deviceID
// start hex to ascii conversion
for (dummy=0; dummy<8; dummy++)
{
sprintf(cHexBuff,"%X",gaMemRFbuffer[dummy]);
txbuffer[dummy*2] = cHexBuff[0];
txchksm ^= txbuffer[dummy*2];
txbuffer[dummy*2+1] = cHexBuff[1];
txchksm ^= txbuffer[dummy*2+1];
tx_in = (dummy*2)+2;
}
sprintf(cDtaBuff,"%02u:%02u%02u-%02u-%02u%02u%C%04LX",
hours,minutes,mthdays,months,y2kyrs,years,gcLogMode,deviceID);
for (dummy=0; dummy<20; dummy++)
{
txbuffer[dummy+16] = cDtaBuff[dummy];
txchksm ^= txbuffer[dummy+16];
++tx_in;
}
txbuffer[tx_in] = txchksm; // store checksum or CRC
++tx_in;
}
|
I hope this provide you a picture on CRC checking and calculation. |
|
|
kypec
Joined: 20 Sep 2003 Posts: 54
|
CRC16-CCITT implementation |
Posted: Wed Feb 18, 2004 5:20 am |
|
|
Here is my bit-by-bit algorithm of 16-bit CRC computation according
to CCITT specification. It's surely not as fast as table driven implementations rather it is very comprehensible.
Functions are based mainly upon the following document:
http://www.riccibitti.com/crcguide.htm
Well, here it is (tested on PIC18F452): Code: |
////////////////////////////////////////////////////////////////////////////////
//CRC16-CCITT bit-by-bit algorithm
////////////////////////////////////////////////////////////////////////////////
int16 const CRC_POLYNOMIAL=0x1021; //CRC16-CCITT specific
int16 const CRC_INIT_VALUE=0xFFFF; //CRC16-CCITT specific
union { //0xHEAD_REMAINDER_TAIL organization is useful for bit shifting operations
int32 whole;
struct {
int8 tail;
int16 remainder;
int8 head;
} part;
} crc16;
void one_byte_crc16(int8 new) { //process single message byte
int8 i;
crc16.part.tail=new; //store new message byte in the end
for (i=0; i<8; i++) { //repeat for all 8 bits in the message byte
crc16.whole<<=1; //new message bit goes in and MSb of remainder goes out
if (crc16.part.head & 0x01) crc16.part.remainder^=CRC_POLYNOMIAL; //XOR if necessary
};
}
int16 get_crc16 (int16 pointer,int8 length) { //process entire message
int8 i;
crc16.part.remainder = CRC_INIT_VALUE; //initialize remainder
for (i=0;i<length;i++) one_byte_crc16(*(pointer+i)); //process all message bytes
one_byte_crc16(0x00); //augment message = append as many zero bits
one_byte_crc16(0x00); //as the width of polynomial is = 16
return crc16.part.remainder;
}
int8 message[64];
int16 calculated_crc;
void main(void) {
message[0]='1';
message[1]='2';
message[2]='3';
message[3]='4';
message[4]='5';
message[5]='6';
message[6]='7';
message[7]='8';
message[8]='9';
calculated_crc=get_crc16(message,64);
}
|
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: CRC16-CCITT implementation |
Posted: Wed Feb 18, 2004 7:51 am |
|
|
kypec wrote: | Here is my bit-by-bit algorithm of 16-bit CRC computation according
to CCITT specification. It's surely not as fast as table driven implementations rather it is very comprehensible.
Functions are based mainly upon the following document:
http://www.riccibitti.com/crcguide.htm
Well, here it is (tested on PIC18F452): Code: |
////////////////////////////////////////////////////////////////////////////////
//CRC16-CCITT bit-by-bit algorithm
////////////////////////////////////////////////////////////////////////////////
int16 const CRC_POLYNOMIAL=0x1021; //CRC16-CCITT specific
int16 const CRC_INIT_VALUE=0xFFFF; //CRC16-CCITT specific
union { //0xHEAD_REMAINDER_TAIL organization is useful for bit shifting operations
int32 whole;
struct {
int8 tail;
int16 remainder;
int8 head;
} part;
} crc16;
void one_byte_crc16(int8 new) { //process single message byte
int8 i;
crc16.part.tail=new; //store new message byte in the end
for (i=0; i<8; i++) { //repeat for all 8 bits in the message byte
crc16.whole<<=1; //new message bit goes in and MSb of remainder goes out
if (crc16.part.head & 0x01) crc16.part.remainder^=CRC_POLYNOMIAL; //XOR if necessary
};
}
int16 get_crc16 (int16 pointer,int8 length) { //process entire message
int8 i;
crc16.part.remainder = CRC_INIT_VALUE; //initialize remainder
for (i=0;i<length;i++) one_byte_crc16(*(pointer+i)); //process all message bytes
one_byte_crc16(0x00); //augment message = append as many zero bits
one_byte_crc16(0x00); //as the width of polynomial is = 16
return crc16.part.remainder;
}
int8 message[64];
int16 calculated_crc;
void main(void) {
message[0]='1';
message[1]='2';
message[2]='3';
message[3]='4';
message[4]='5';
message[5]='6';
message[6]='7';
message[7]='8';
message[8]='9';
calculated_crc=get_crc16(message,64);
}
|
|
If you change the for loops to count down you will have code that compiles better. It will run about ~10% faster and compile smaller slightly.
for(i=8;i>0;i--) |
|
|
yellowbanana Guest
|
|
Posted: Wed Feb 18, 2004 9:16 am |
|
|
Hi!
does someone know about a CRC that does not just detect errors, but that can also correct some of them? |
|
|
Dargar
Joined: 12 Dec 2003 Posts: 25
|
|
Posted: Sat Oct 29, 2005 1:11 pm |
|
|
dvdb wrote: |
Hi,
This a my asm implementation for the same CRC.
It is about 10X faster, 30 bytes less code and used no RAM.
It's based on http://www.dattalo.com/technical/software/pic/crc_8bit.c which exploits a pecularity of this particular polynomial described in http://pdfserv.maxim-ic.com/en/an/app27.pdf.
This allows bytewise processing without bit shifting.
I ported the algorith to asm, it turns out this can be done with no additional RAM, and with bit twiddling only in w, so its very fast and dense code.
Don't work too hard!
Code: |
int calc_CRC(int* data,int byte_cntr)
{
int crc=0;
#ASM
MOVF DATA,W //copy pointer to first databyte..
MOVWF FSR //..to pointer register
loop:
MOVF INDF,W //load w with next databyte
xorwf crc,f // xor with accumulated crc (accumulated crc is no longer valid now)
movlw 0 //w will ccumulate the new crc
btfsc crc,0
xorlw 0x5e //could also be iorlw
btfsc crc,1
xorlw 0xbc
btfsc crc,2
xorlw 0x61
btfsc crc,3
xorlw 0xc2
btfsc crc,4
xorlw 0x9d
btfsc crc,5
xorlw 0x23
btfsc crc,6
xorlw 0x46
btfsc crc,7
xorlw 0x8c
movwf crc //store accumulated crc
INCF FSR //increment indirection register to point to next databyte
decfsz byte_cntr,F
goto loop //next databyte
//done, crc is in w
movwf crc //store in result
#ENDASM
return(crc);
} |
|
This generates an 8-bit CRC code if I'm not mistaken?
How big data-sets would be practical to use before an 8-bit CRC becomes to small? 10 bytes of data? 20? 50?
-I realise this is a trade-off between how much processing power and overhead can be set aside for the CRC, and how accurately the CRC catches errors, but I do not really understand how the number of data-bytes in a packet affects this?
According to the following link
http://www.ciphersbyritter.com/ARTS/CRCMYST.HTM
a (specific) CRC-8 has a "99.29"% probability of catching errors... is this number in any way dependant on the size of the data the CRC is based on? -If not, an 8 bit crc should be enough for all but the most horrible of conditions, up to several hundred bytes.
Having no idea of what I'm doing (I'm not good with math), could I say that, if the data which the crc is performed on is 10 bytes long, then the percent chance of detecting all possible errors in the 10 bytes is 0.9929^10 = appr. 93%? If so, then whether or not 8-bit crc is enough for my application comes down to how much I trust my transmission line...
---
since the asm version is so fast, would it make sense to include 2 crc-8's in one package as opposed to a 16-bit crc? Doing it like this:
[msg header][address][ack][len][Data1][Data2][Data n][CRC1][Data n+1][Data x][CRC2]
Sorry about the long post.. hope someone is brave enough to attempt an answer to (parts) this post! _________________ Owner of PCWH v. 3.224
Consider myself beginer\intermediate as far as CCS and Microchip PIC's goes.
Bachelor in Space Engineering and Undergraduate Masters in Space Engineering
soon to be undergrad Aerospace |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Oct 29, 2005 6:40 pm |
|
|
Quote: | This generates an 8-bit CRC code if I'm not mistaken? | Yes, this is the 8-bit CRC used by Dallas in the 1-wire protocol.
Quote: | How big data-sets would be practical to use before an 8-bit CRC becomes to small? 10 bytes of data? 20? 50? | I don't know. CRC8 is limited and I think a practical maximum block size is around 20 bytes but this isn't based on any scientific grounds. Anyone having a pointer to background info here?
The number you reference here is for a standard 8-bit checksum, not a CRC-8. A CRC-8 does better than this, it will detect 255/256=99,61% of all possible error bit patterns. Note that this is only the percentage of the number of error patterns recognized, depending on the type of errors in your system a 100% detection rate might apply, for example 1-bit errors are always detected.
Quote: | since the asm version is so fast, would it make sense to include 2 crc-8's in one package as opposed to a 16-bit crc? Doing it like this:
[msg header][address][ack][len][Data1][Data2][Data n][CRC1][Data n+1][Data x][CRC2] | I wouldn't do this, a CRC-16 is more safe than a CRC-8 and you are sending 16 bits of CRC anyway. I posted a very efficient CRC-16 function in the code library which is just as efficient as the CRC-8 above. http://www.ccsinfo.com/forum/viewtopic.php?t=24977 |
|
|
|
|
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
|