Modbus CRC-16-Rechner
Fügen Sie die Bytes eines Modbus-RTU-Frames ein und erhalten Sie die CRC in der Reihenfolge, in der sie auf die Leitung geht. Endet der Frame schon mit einer CRC, prüft der Rechner sie.
Bytes
BeispielMit oder ohne CRC am Ende. 11 03 00 6B 00 03, 1103006B0003 und 0x11,0x03 funktionieren.
Ergebnis
| CRC-16/MODBUS | |
|---|---|
| CRC-Bytes wie gesendet (Low-Byte zuerst) | |
| Frame mit CRC | |
| LRC (Modbus ASCII) | |
| Modbus-ASCII-Frame |
Läuft komplett in Ihrem Browser. Ihre Eingaben werden an keinen Server gesendet.
CRC-16/MODBUS im Code
Startwert 0xFFFF, Polynom 0xA001 (0x8005 gespiegelt), kein abschließendes XOR. Das Low-Byte wird zuerst gesendet.
uint16_t modbus_crc16(const uint8_t *buf, size_t len)
{
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; i++) {
crc ^= buf[i];
for (int bit = 0; bit < 8; bit++)
crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
}
return crc; /* send crc & 0xFF first, then crc >> 8 */
}
def modbus_crc16(data: bytes) -> bytes:
crc = 0xFFFF
for b in data:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
return crc.to_bytes(2, "little") # low byte first, ready to append
So funktioniert die Modbus-CRC
Jeder Modbus-RTU-Frame endet mit einer 16-Bit-CRC über alle Bytes davor: Geräteadresse, Funktionscode und Daten. Der Empfänger berechnet denselben Wert und verwirft den Frame ohne Antwort, wenn er nicht passt. Die CRC wird mit dem Low-Byte zuerst gesendet, also umgekehrt wie Registerwerte. Deshalb erscheint die CRC 0x8776 des Frames 11 03 00 6B 00 03 auf der Leitung als 76 87.
Modbus TCP hat keine CRC, die TCP-Verbindung prüft die Daten bereits. Modbus ASCII nutzt stattdessen eine einfachere 8-Bit-LRC, die hier ebenfalls angezeigt wird.
Typische Fehler
- Vertauschte CRC-Bytes. Das High-Byte zuerst zu senden ist der häufigste Fehler in selbst geschriebenen Treibern. Das Gerät schweigt. Der Rechner meldet, wenn ein Frame die richtige CRC in falscher Reihenfolge hat.
- CRC über die falschen Bytes. Die CRC umfasst alles von der Geräteadresse bis zum letzten Datenbyte, nicht mehr und nicht weniger. Bei Modbus-TCP-Gateways gehört der MBAP-Header nicht dazu.
- Text statt Bytes. Die CRC wird über die binären Bytes berechnet, nicht über die Zeichen „0“, „1“, „0“, „3“. Hex-Text aus einem Log muss erst umgewandelt werden, was der Rechner für Sie erledigt.
- Eine richtige CRC reicht nicht. Antwortet das Gerät trotzdem nicht, prüfen Sie Baudrate, Parität, Stoppbits, Geräteadresse und den Busabschluss.
Fragen aus der Praxis
Warum wird die Modbus-CRC mit dem Low-Byte zuerst gesendet?
Die CRC wird mit einem gespiegelten Algorithmus berechnet, der Bits nach rechts schiebt, und die Spezifikation überträgt das Ergebnis mit dem Low-Byte zuerst. Registerdaten gehen mit dem High-Byte zuerst, die CRC ist also die einzige Ausnahme im Frame. Einen Frame mit vertauschten CRC-Bytes ignoriert das Gerät.
Wie lautet die CRC von 01 03 00 00 00 01?
84 0A, die vollständige Anfrage zum Lesen eines Holding-Registers an Adresse 0 von Gerät 1 lautet also 01 03 00 00 00 01 84 0A. Für zehn Register (01 03 00 00 00 0A) ist es C5 CD.
Verwendet Modbus TCP eine CRC?
Nein. Modbus-TCP-Frames beginnen mit einem 7 Byte langen MBAP-Header und tragen keine CRC, weil TCP die Daten schon schützt. Eine CRC gibt es nur bei Modbus RTU, auch bei RTU over TCP, wo der serielle Frame unverändert getunnelt wird.
Welche CRC-16-Variante verwendet Modbus?
CRC-16/MODBUS: Polynom 0x8005 in gespiegelter Form (0xA001), Startwert 0xFFFF, Ein- und Ausgabe gespiegelt, kein abschließendes XOR. Andere CRC-16-Varianten wie CCITT oder XMODEM liefern andere Ergebnisse und funktionieren nicht.
Was ist der Unterschied zwischen CRC und LRC?
Modbus RTU nutzt die 16-Bit-CRC über den binären Frame. Modbus ASCII sendet den Frame als Hex-Text zwischen Doppelpunkt und CR LF und schützt ihn mit einer 8-Bit-LRC: dem Zweierkomplement der Summe aller Bytes. Die LRC ist viel schwächer, aber leicht zu berechnen.
Verwandte Werkzeuge
- Register-DecoderFloat32, Int32, UInt16 und Bits in jeder Byte-Reihenfolge, dazu „Wert finden“.
- Adress-Umrechner40001 ↔ Offset 0, Schreibweise 4x/3x/0x/1x, 5- und 6-stellige Adressen.
- Wert-KodiererEinen Wert wie 230.5 in Register für jede Byte-Reihenfolge umwandeln.