Hallo,
ich versuche gerade die CRC vom Scratchpad von einem DS18S20 zu
berechnen. Laut der Appnote 27 von Maxxim wird mit dem LSB vom Byte 0
angefangen.
Ich hab von
http://werner.dichler.at/sites/default/files/attachment/prj21_CRC%20Einfuehrung.pdf
die Vorwärts Berechnung so geändert, das mit dem LSB begonnen.
Leider stimmt die CRC in Byte 8 nicht mit dem berechneten aus den ersten
8 Bytes überein. Wo liegt hier mein Fehler ?
Ich hab die Appnote so verstanden das die beiden LSB über xor verrechnet
werden. Der Inhalt des Schieberegisters wird denn um eins nach rechts (
zum LSB ) verschoben und denn mit dem Ergebnis aus den beiden LSBs über
xor verrechnet. Das Ergebnis der beiden LSBs kommt "ins" MSB.
Hab ich die Appnote so richtig verstanden ?
Gruß JackFrost
Beitrag "Onewire + DS18x20 Library"
Das funktioniert. Deine Routine sieht komisch aus, ein Modulo ist in
einer CRC nie drin.
Es gibt auch noch die rein serielle Variante. Hab ich aber damals
verworfen, wei die Nibbleversion deutlich schneller ist. Finde sie auch
nicht mehr. Ohne Gewähr, so könnte es stimmen.
1
uint8_tonewire_crc(constuint8_t*data,uint8_tcnt){
2
uint8_tcrc,i,tmp,poly=0x8C;
3
4
// serial CRC calculation,
5
6
// first byte is not changed, since CRC is initialized with 0
@Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
>In der avr-libc gibt's fertigen Code dafür.
In allen Varianten? CRC ist vielfältig, mal links, mal recht schieben,
vorher die CRC auf Null oder FF setzen, am Ende invertieren oder nicht .
. .
http://www.ross.net/crc/download/crc_v3.txt
Der Klassiker!
Falk B. schrieb:>> In der avr-libc gibt's fertigen Code dafür.>> In allen Varianten?
In vielen Varianten, und insbesondere in der, die Dallas, ähem,
Maxim für 1-wire benutzt.
Hallo,
danke für eure Hilfe.
@Falk danke für die Funktion. Mit dieser ist das Ergebnis über alle 9
Bytes 0. Auch mit deiner Variante mit den Nibbels. Was mich etwas
verwundert hat, das wenn ich es nur auf den ersten 8 Bytes anwende, dann
kommt eine andere CRC als die im 9. Byte vom Scratchpad raus. Ich hab
meine Funktion geändet und die Variante direkt vom Wiki für die CRC32
genommen. Mit dieser kommt bei den 9 Bytes auch 0 raus und bei 8 Bytes
der Wert der CRC im 9. Byte.
Ich hab einen Screenshot vom Inhalt des Arrays gemacht. Die Bytes 0 - 8
sind die vom Scratchpad.
Die Bytes 9 und 10 wurde mit folgender Funktion berechnet :
Der Rest mit der von dir geschriebenen.
Mit deinenen Funktionen kann ich die CRC beliebiger Daten bestimmen und
prüfen , oder ? Die Variante mit den Nibbels sollte ja schneller gehen
als das Byteweise verarbeiten der Daten.
@ Jörg, ich verwende einen xMega128A1. Wo finde ich die Libc beim der
Toolchain wenn ich das Atmel Studio installiert habe ?
Gruß JackFrost
@ Bastian Werner (jackfrost)
>@Falk danke für die Funktion. Mit dieser ist das Ergebnis über alle 9>Bytes 0.
Ist das nicht der Sinn einer CRC? Mal die Kommentare im Quelltexte
gelesen?
> Auch mit deiner Variante mit den Nibbels. Was mich etwas>verwundert hat, das wenn ich es nur auf den ersten 8 Bytes anwende, dann>kommt eine andere CRC als die im 9. Byte vom Scratchpad raus.
Auch das ist normal. Die echte CRC erhälst du nur, wenn du die
empfangene CRC zwischenspeicherst, im Array auf 0 setzt und über 9 Byte
berechnest. Siehe Quelltext!!!
> Ich hab>meine Funktion geändet und die Variante direkt vom Wiki für die CRC32>genommen. Mit dieser kommt bei den 9 Bytes auch 0 raus und bei 8 Bytes>der Wert der CRC im 9. Byte.
Das ist eher Zufall.
>uint8_t calc_forward_CRC8_LFSR(const char *data, uint8_t length)
Sieht immer noch komisch aus.
> for(;length>0;length--)> {> currentByte = *data++;> for(int i=0; i<8; i++)> {> inputBit = currentByte & 0x01;
OK.
> currentByte = currentByte >> 1;> //helper = ((reg & 0x01)^(inputBit))<<7;> if ((reg & 0x01) != (inputBit))
DAS ist vollkommen komisch. Ich glaube nicht, dass damit die CRC stimmt.
>Mit deinenen Funktionen kann ich die CRC beliebiger Daten bestimmen und>prüfen , oder ?
Ja sicher!
> Die Variante mit den Nibbels sollte ja schneller gehen>als das Byteweise verarbeiten der Daten.
Logisch, steht ja auch im Quelltext.
Falk B. schrieb:> Auch das ist normal. Die echte CRC erhälst du nur, wenn du die> empfangene CRC zwischenspeicherst, im Array auf 0 setzt und über 9 Byte> berechnest. Siehe Quelltext!!!
Wer lesen kann ist klar im Vorteil. Macht man es so wie im Quelltext
steht gehts :)
Falk B. schrieb:>>@Falk danke für die Funktion. Mit dieser ist das Ergebnis über alle 9>>Bytes 0.>> Ist das nicht der Sinn einer CRC? Mal die Kommentare im Quelltexte> gelesen?
Das war mir bewusst das hier eine Null stehen muss wenn die Daten
richtig übertragen wurden.
Falk B. schrieb:>> Ich hab>>meine Funktion geändet und die Variante direkt vom Wiki für die CRC32>>genommen. Mit dieser kommt bei den 9 Bytes auch 0 raus und bei 8 Bytes>>der Wert der CRC im 9. Byte.>> Das ist eher Zufall.
Ich habs bei 10 verschiedenen Werten ( Temperaturen ) Scratchpad
probiert und immer hat die Berechnete CRC aus den ersten 8 Bytes mit dem
9. Byte bzw. mit den Werten aus deiner Funktion übereingestimmt. Wobei
es egal ist, da die Nibbelvariante Vorteile hat.
Gruß JackFrost
Bastian W. schrieb:> @ Jörg, ich verwende einen xMega128A1. Wo finde ich die Libc beim der> Toolchain wenn ich das Atmel Studio installiert habe ?
Die hängt implizit hinten am Compiler mit dran …
Doku (für den CRC-Teil) ist hier:
http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
_crc_ibutton_update() ist der 1-wire-Algorithmus.