Wie das CRC in RFID-Protokoll berechnen
Frage
Wenn Daten von einem RFID-Lesegerät finden Sie einen CRC-CCITT über die Nutzlast finden. „Die CRC wird mit 0x3791 anstelle des üblichen Wert 0xFFFF initialisiert.“ Wie kann ich definiere die Funktion, das überprüft, dass der CRC in Ordnung ist.
Beispiel
data: { 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0xA0 }
CRC: {0x60, 0xE7}
eine weitere Probe
data: { 0x02, 0x41, 0x00, 0x00, 0x00, 0x00, 0xA4 }
CRC: {0x6F, 0xA5}
Lösung
Die einzige Art, wie ich dies an der Arbeit konnte, war durch den Bit-für-Bit-Algorithmus Implementierung (TMS37157 Datenblatt Abbildung 52).
UINT16 rfid_get_crc(const UINT8 * data, INT8 size)
{
static BOOL lsb;
static BOOL rxdt;
static UINT16 crc;
static UINT8 bits;
static UINT8 byte;
static UINT8 i;
const UINT16 RFID_CRC_INIT = 0x3791;
crc = RFID_CRC_INIT;
for (i=0; i<size; i++)
{
bits = 8;
byte = data[i]; // Next byte
while (bits --> 0)
{
lsb = crc & 1; // Store LSB
crc >>= 1; // Shift right 1 bit
rxdt = byte & 1;
if (rxdt)
crc |= 0x8000; // Shift in next bit
if (lsb) // Check stored LSB
crc ^= 0x8000; // Invert MSB
if (0x8000 == (crc & 0x8000)) // Check MSB
crc ^= 0x0408; // Invert bits 3 and 10
byte >>= 1; // Next bit
}
}
return crc;
}
Andere Tipps
Eine kompaktere Implementierung (in Pseudocode):
// Least significant bit first (little-endian)
// x^16+x^12+x^5+1 = 1000 0100 0000 1000 (1) = 0x8408
function crc(byte array string[1..len], int len) {
//Other RFID tags I have seen use initialization of 0x0000:
//rem := 0x3791;
rem := 0x3791;
for i from 1 to len {
rem := rem xor string[i]
for j from 1 to 8 { // Assuming 8 bits per byte
if rem and 0x0001 { // if rightmost (most significant) bit is set
rem := (rem rightShift 1) xor 0x8408
} else {
rem := rem rightShift 1
}
}
}
// A popular variant complements rem here
return rem
Dies kann in Codefragment gefunden werden 5 von:
http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks