Forum: Mikrocontroller und Digitale Elektronik CRC Berechnung


von Oteph (Gast)


Lesenswert?

Ich möchte einen Frequenzumrichter über modbus ansteuern dafür benötige 
ich am ende jeder Übertragung eine crc.
Im datenblatt steht dazu
Der CRC-Code ist ein 16-Bit Datum, das 8-Bit Blöcke beliebiger Länge 
generiert.
• Der CRC-Code wird durch ein Polynom CRC-16 erzeugt (X16+ X15+ X2+ 1).

Weiterhin sind darin Beispiele angegeben:

zB.

1 Slave-Adresse *1
08
2 Funktion
01
3 Coil Startadresse
(high byte) / C001
00
4 Coil Startadresse
(low byte) / C001
06
5 Anzahl Coils
(high byte) *2 /
C001-C006
00
6 Anzahl Coils
(low byte) *2 /
C001-C006
06
7 CRC-16 (high byte)
0D
8 CRC-16 (low byte)
50


Die fetten Werte sollen übertragen werden.

Nun habe ich versucht die Checksumme nachzurechen. Ich habe dafür den 
Rechner unter http://www.lammertbies.nl/comm/info/crc-calculation.html

Verwendet. Leider stimmt das dortige Ergebnis nicht mit dem aus dem 
Datenblatt überein. Die Zahl welche ich eingegeben habe lautete 
080100060006

Datenblatt Umricher 
http://www.kurz-automation.de/downloads/unterlagen/hitachi/frequentumrichter/sj200/modbussj200.pdf

von Zac Hobson (Gast)


Lesenswert?

Ja. Der CRC ist immer so eine Sache. Da gibt es beliebig viele 
Implementationen. Man kann zB nach links oder nach rechts schieben. Am 
besten laesst du dir den CRC Code geben und vergleichst dann.

von Stefan W. (dl6dx)


Lesenswert?

Hi,

zunächst mal dürfte dich 
http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf 
interessieren.

Der Rechner auf lammertbies.nl liefert für das dort angegebene Beispiel 
den korrekten Wert. (Eingabemodus "Hex" nicht vergessen!)

Auch bei dem Beispiel "Antwort" auf Seite B10 in dem von dir verlinkten 
Dokument passt der CRC.

An der Stelle ist übrigens ein schwerwiegender Fehler: Beim "Modbus-CRC" 
wird zuerst das low byte gesendet, dann das high byte.

Das ist in beiden Beispielen falsch angegeben. Im Beispiel "Antwort" 
sind die Werte aber mit 12 1A (erst low, dann high) aber korrekt! 
(08010117 -> CRC = 1A12).

Der korrekte CRC für das linke Beispiel wäre 905C, gesendet als 5C 90.

Übrigens befindet sich auf der Seite von Lammert Bies auch ein ZIP-File 
mit einer Implementation.

Teste die Modbus-CRC-Funktion doch mal mit dem FU. (Ach ja: Die Variable 
für den CRC mit 0xFFFF vorladen!)

Grüße

Stefan

von Alexander S. (agentbsik)


Lesenswert?

Hi,

ich habe für meine Bachelor-Arbeit auch einen CRC16 Generator für den 
Modbus geschrieben.

Eventuell hilt dir meine Funktion weiter:

//###################################################
// Checksumme CRC16 Berechnung
// Berechnet die CRC Summe eines input[] Arrays der Länge lenght
//###################################################
int32_t  checkSum(int32_t input[],uint8_t length)
{
  int32_t crc = 0xFFFF;
  int32_t mask = 0x01;
  int32_t CRC = 0xA001;



  for (uint8_t i=0 ; i<length ; i++)
  {
    crc = crc ^input[i];

    for (uint8_t j=0 ; j<8 ; j++)
    {
      if((crc & mask) == 0)
      {
        crc = crc >> 1;
      }
      else

      {
        crc = crc >> 1;
        crc = crc ^ CRC;
      }
    }
  }




return crc;

}



Aufrufen kannst du sie wie folgt:

int temp;
int num = checkSum(array,length);

  temp = (uint8_t) num; //(Lowbyte. uint8_t oder char typcasten)
  temp = (uint8_t) (num>>8); // Highbyte

von Oteph (Gast)


Lesenswert?

Danke für deine Funktion

Habe sie getestet und sie gibt auch die CRCs wie bei der von mir 
genannten Seite aus. Nur weiß ich leider immer noch nicht wie die Maske, 
welche der Frequenzumrichter verwendet, genau ausschaut. Hitachi scheint 
da ihre eigene Suppe zu kochen...

Weder 0xA001 noch 0x8005 stimmen (initialisiertmit 0x0 bzw 0xffff).

Bei dem Grät handelt es sich um einen Hitachi SJ200. Kennt sich jemand 
damit aus?

von CRC16-Tab (Gast)


Lesenswert?

Wer noch ein paar Byte mehr im Flash frei hat, kann die CRC16-Berechnung 
mit Hilfe einer vorberechneten Tabelle fast in einem 3-Zeiler erledigen.
(Beispiel in C)
https://www.modbustools.com/modbus_crc16.html

von Jemand (Gast)


Lesenswert?

Alexander S. schrieb:
> int32_t crc
> crc >> 1;

An den zufälligen Googler: Das ist Pfusch.

CRC16-Tab schrieb:
> Wer noch ein paar Byte mehr im Flash frei hat, kann die CRC16-Berechnung
> mit Hilfe einer vorberechneten Tabelle fast in einem 3-Zeiler erledigen.
> (Beispiel in C)
> https://www.modbustools.com/modbus_crc16.html

Zum Glück kann man sich die Definitionen von BYTE und WORD anhand des 
Kontexts erraten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.