s. http://www.mikrocontroller.net/forum/read-1-190635.html Der Code ist genauso einfach wie trickreich. Es gibt zahllose Beschreibungen, z.B. Dallas/Maxim AppNote27 http://pdfserv.maxim-ic.com/en/an/AN27.pdf oder als hmtl: http://www.maxim-ic.com/appnotes.cfm/appnote_number/27 Den von Dir genannten Code kann man weiter optimieren, und zwar - den Übertrag des Bits an den Anfang des Schieberegisters (Stage 1) kann man mit dem XOR mit-erledigen - die Reihenfolge der einzenen Schritte kann günstiger gelegt werden. Das Ergebnis dieser Überlegungen kannst Du hier lesen: http://www.mikrocontroller.net/forum/read-1-321069.html?#321285 zuerst eine Wertetabelle für xor x y e 0 0 0 0 1 1 1 0 1 1 1 0 d.h. das Ergebnis ist 0, wenn die Bits x und y gleich sind oder x wird invertiert, wenn y=1 oder y wird invertiert, wenn x=1 Machen wir doch mal das Beispiel der AppNote27 (Figure 4 links): Variable j c d b b&1 c/=2 d/=2 c/=2^p BitNummer fedcba9876543210 76543210 76543210 0 9 0 f 1 7 5 8 4 0 4878 3a 1001000011110001 01110101 10000100 zuerst xor-en wir das Low-Bit (das entspricht in Figure 3 dem rechten XOR-Gatter (x15 xor Input Data (gemeint ist das Bit 0 davon))). Das mache ich in 2 Schritten: b=c^d xor des ganzen (low-)Bytes (f1 xor 75 = 84) b&1 nur Bit0 ist von Interesse (84 and 01 = 00) Wenn das Ergebnis (entspricht X0 in Figure3) 0 ist, braucht man nur CRC nach rechts schieben, da von links eine 0 reingeschoben wird und x2 und x15 nicht invertiert werden. Wenn das Ergebnis 1 ist, schiebe ich CRC nach rechts und invertiere die Bits f, d und 0 (vor dem Shift waren das die Bits X0, X2 und X15), indem ich CRC mit 40961 (0xa001 = 1010 0000 0000 0001) xor-e. das könnte man mit if(b&1)crc^=0xA001; bewerkstelligen, jedoch ist b&1?crc^=40961:0; 2 Buchstaben kürzer, was mit persönlich gefällt (das :0 braucht man nur aus syntaktischen Gründen). (außerdem geht if() nicht in der runden for-Klammer s.u.) also, geschoben werden muss immer: c=c >> 1 gleichbedeuten mit c>>=1 gleichbedeutend mit c/=2 (zumindest wenn c unsigned ist) Beim nächsten Durchgang ist Bit1 von Input Data von Interesse, also schiebe ich es an die Stelle d0: d=d >> 1 c>>=1 c/=2 statt for(j=0;j<8;j++) schreibe ich for(j=8;j;j--) wieder 2 Buchstaben gespart (-; (das mittlere j ist eine Kurzform für j!=0) und statt for(j=8;j;j--){b=c^d;c/=2;d/=2;if(b&1)crc^=0xA001;} schreibe ich kurz for(j=8;j;j--,b=c^d,c/=2,d/=2,b&1?c^=40961:0); schade, dass das überflüssige :0 syntaktisch sein muss Das war's auch schon. Variable j c d b b&1 c/=2 d/=2 c/=2^p BitNummer fedcba9876543210 76543210 76543210 0 9 0 f 1 7 5 8 4 0 4878 3a 1001000011110001 01110101 10000100 1 4 8 7 8 3 a 4 2 0 243c 1d 0100100001111000 00111010 01000010 2 2 4 3 c 1 d 2 1 1 121e 0e b21f 0010010000111100 00011101 00100001 3 b 2 1 f 0 e 1 3 1 590f 07 f90e 1011001000011111 00001110 00010011 4 f 9 0 e 0 7 0 9 1 7c87 03 dc86 1111100100001110 00000111 00001001 5 d c 8 6 0 3 8 5 1 6e43 01 ce42 1101110010000110 00000011 10000101 6 c e 4 2 0 1 4 3 1 6721 00 c720 1100111001000010 00000001 01000011 7 c 7 2 0 0 0 2 0 0 6390 00 1100011100100000 00000000 00100000 8 6 3 9 0 <-- Ergebnis 0100001110010000 CRC8 / CRC16 / CRC32 unterscheiden sich nur in der Breite der Variablen c und dem Wert (Polynom) von p.