Flera av dessa metoder saknar ju någon form av felkoll, så jag har gjort en enkel rutin för att beräkna en 8-bitars crc-kod, för att använda vid dataöverföring.
funktionen används så här:
1) du sätter den globala variabeln crc till 0xff (eller annan valfri startkod, dock helst ej 0x00 - se nedan)
2) för varje byte du sänder så anropas funktionen med databyten som argument.
3) när sista byten är överförd skickar du crc. (man kan också välja att skicka t.ex. 0xff - crc eller liknande)
konstanten CRCPOLYNOM kan ha olika värden, men inte vilket värde som helst. Det finns regler för det. 0x07 motsvarar polynomet x8+x2+x+1 vilket förekommer inbyggt i en del kretsar, t.ex. AD-omvandlare med SPI-buss.
på mottagarsidan gör du exakt samma sak, fast med de mottagna byten. Du måste ha en bestämd längd på datapaketet, alternativ ange antalet bytes i början, så att du vet när du ska förvänta dig en crc.
när du tar emot crc-koden gör du en koll om den stämmer med din globala variabel crc. Jag brukar returnera skillnaden från mottagarrutinen så att jag får ett värde som skiljer sig från noll om det blivit fel.
Man kan faktiskt använda crc-koden för att göra enkel diagnostik: om alla data består av 0xff så kommer du att få samma kod (om du har ett fixt antal bytes), likaså för 0x00. Dessa situationer uppstår oftare än andra, t.ex. pga en oansluten enhet, strömbortfall, logisk felkoppling eller kapad kabel. Då kan man i mjukvaran skilja på dessa tillstånd och andra överföringsfel. Att man inte ska använda 0x00 som startvärde beror på att crc alltid kommer att bli 0x00 om alla data också är 0x00... det är ju inte så osannolikt att alla data blir 0x00 om man saknar ett pull-up motstånd t.ex. Då är det tråkigt om mjukvaran inte detekterar det felet.
Här kommer beräkningsfunktionen:
Kod: Markera allt
uint8_t crc; // global variabel
void crccalc(uint8_t data) { // 8 bitars CRC rutin
// crc ändras för varje databyte in, startvärde ska vara 0.
// argument: data = inkommen / skickad byte
#define CRCPOLYNOM 0x07
uint8_t i, bit;
for (i=7;i<8;i--) {
bit = ( crc ^ data );
crc<<=1;
data<<=1;
if (bit & 0x80 )
crc^= CRCPOLYNOM;
}
}