Forum: Mikrocontroller und Digitale Elektronik geeigneter Algorithmus fuer Pruefsumme


von Paule (Gast)


Lesenswert?

Hei Leute,

ich will 15 Char-Bytes ueber die serielle Schnittstelle meines uC 
senden. Diesen 15 Bytes will ich ein 1-3 Byte langes Kontrollzeichen 
anhaengen. Habt ihr einen Vorschlag wie ich das am Besten machen 
koennte(CRC etc., vielleicht hat jemand ja einen passenden Alg. auf 
Lager) und habt ihr vor allem ein C-CODEBEISPIEL dafuer???
Vielen Dank.

Gruss Paule

von Stefan (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/CRC und der dort erwähnte Links 
ins Forum...

von Bertrik Sikken (Gast)


Lesenswert?

Have a look at the Fletcher's checksum:
http://en.wikipedia.org/wiki/Fletcher%27s_checksum

It's much simpler (and probably faster and less code too) to calculate 
than a real CRC and works almost as good.

von Sonic (Gast)


Lesenswert?

Programmierst du in C? Evtl. mit WinAVR? Da gibt's ne super Lib für CRC 
(8 und 16). Hab' ich auch benutzt, funktioniert prima!

von Paule (Gast)


Lesenswert?

Danke fuer die Antworten Jungs,

also so wie ich das verstanden hab benutzt man hauptsächlich CRC zur 
Prüfung.
Verstehe ich das dann richtig: wenn ich also 15Bytes CRC'en will und ich 
z.B. einen 16bit CRC-Polynom nehme, brauch ich 8 Byte als Anhang. Ist 
dementsprechend ein 32 bit Schlüssel schneller, langsamer oder 
gleichschnell im Bezug auf Rechenzeit, weil ich mit einem grösseren 
Polynom dann ja weniger Prüfzeichen senden müsste.

@Sonic: Ja ich programmier in C. genauer gesagt mit Dynamic C, ist eine 
ganz leicht abgewandelte Version davon. Leider gibts hier keine LIB's 
für CRC. Aber ein originaler C-Code würde mir schon reichen.

Gruss Paule

von A.K. (Gast)


Lesenswert?

Wie der Name schon sagt, besteht eine 16bit CRC aus 16 Bits. Macht die 
Übertragung 2 Bytes länger. Eine 32bit CRC macht sie folglich 4 Bytes 
länger. Und die Rechenzeit hängt auch davon ab, ob du eher auf Platz 
oder Zeit optimierst, wobei bei einer 32bit CRC eine von Haus aus 32bit 
breite Datenverarbeitung deutliche Vorteile hat.

von Florian (Gast)


Lesenswert?

Paule wrote:
>
> ich will 15 Char-Bytes ueber die serielle Schnittstelle meines uC
> senden. Diesen 15 Bytes will ich ein 1-3 Byte langes Kontrollzeichen
> anhaengen. Habt ihr einen Vorschlag wie ich das am Besten machen
> koennte(CRC etc., vielleicht hat jemand ja einen passenden Alg. auf
> Lager) und habt ihr vor allem ein C-CODEBEISPIEL dafuer???

Es kommt darauf an, ob Du Fehler erkennen und reparieren willst oder nur 
wissen willst, ob was falsch war und wie zuverlässig dies dann wiederum 
sein muß.
Am einfachsten ist eine Prüfsummenbildung durch Addition aller 
Datenbytes und anschließender UND Verknüpfung mit 0xFF. Das 
resultierende Byte ist als Prüfusmme für die wenige Nutzdatenbytes denke 
ich ausreichend.

von Paule (Gast)


Lesenswert?

@Florian.

Danke fuer die Antwort. Ich will nur pruefen, keine Korrektur vornehmen.
Aber was soll es bringen am Schluss eine UND-Verknuepfung mit FF zu 
machen, da aendert sich doch nichts am Pruefbyte oder?
Gruss Paule

von Florian (Gast)


Lesenswert?

Paule wrote:
> machen, da aendert sich doch nichts am Pruefbyte oder?

Doch, wenn Du mehrere Bytes addierst, kann es sein, daß Du ein Ergebnis 
bekommst, welches länger als ein Byte ist. Durch die Und-Verknüpfung 
reduzierst Du es auf das niederwertige Byte. Das spart Daten und genügt 
meistens als Genauigkeit

Bsp:
0x0A + 0xFA = 0x104
0x104 & 0xFF = 0x04 (Prüfbyte)

von Benedikt K. (benedikt)


Lesenswert?

Das &0xFF kann man sich sparen, wenn man die Variable nur 1Byte groß 
macht.
Ich mache das immer so:
Sender:
Checksum=Summe aller Daten Werte
Checksum =256-Checksum
Diesen Wert sende ich.

Empfänger:
Checksum=Summe aller empfangenen Werte (einschließlich Checksum)

Wenn die Checksumme 0 ist ist alles OK, ansonsten gab es einen Fehler.
Das ermöglicht eine sehr einfache Überprüfung beim Empfänger.

von Prüfer (Gast)


Lesenswert?

Im allgemeinen werden Bytes mittels XOR verknüpft.

1. auf der Senderseite das entstandene Prüfbyte als 16tes Byte 
übertragen
2. auf der Empfängerseite das Prüfbyte der ersten 15 Bytes bilden und 
mit dem empfangenen vergleichen.

von Paule (Gast)


Lesenswert?

Hei Leutz,
danke fuer die Antworten, haben mir sehr geholfen.
Ich hab jetzt meinen Algorithmus implementiert und er funktioniert auch 
ganz gut.
NUR: Wenn ich die Pruefsumme fuer einen konstanten String berechnen 
lasse, bekomme ich immer die gleiche Pruefsumme heraus, was ja logisch 
ist.
Aber wenn ich einen String, den ich jeweils vorher veraendert habe 
pruefen lasse kommen immer 5 verschiedene Ergebnisse heraus beim 
gleichen Datensatz.
Das liegt meiner Meinung nach garantiert nicht am Algorithmus, sondern 
z.B. an dem String oder seiner Speicherung. Ich habe den string immer an 
der gleichen Stelle gespeichert und schreibe nur neue Daten rein.
Hat vielleicht einer ne Idee woran das liegen koennte????????
VG Paule




.
.
root void SerDTransmitt(char *s) {

      checksum=CalculateChecksum(s);   //meine Fkt. die funktioniert
                                       //bei Eingabe der gleichen Werte 
kommen
                                       //5 verschiedene Pruefsummen 
heraus


      ch7=CalculateChecksum(s2);    //Konstante zum Test der Fkt.
.                                   //hier klappts
.

von usul27 (Gast)


Lesenswert?

Wie du die Funktion aufrufst, ist nicht sonderlich spannend. Es wäre 
wohl wichtiger, den Code deiner Checksum-Routine hier reinzustellen.

von Hansi L. (fabian87)


Lesenswert?

ich kann dir nen crc check mit 8 bytes in pascal geben ;)

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.