1 | // CRC-16(CRC-CCITT) Polynom x^16 + x^12 + x^5 + 1 --> 0x1021
|
2 |
|
3 | unsigned short calculate_crc16_checksum(unsigned char *data, unsigned char count)
|
4 | {
|
5 | unsigned char i = 0;
|
6 | unsigned short crc16_checksum = 0;
|
7 |
|
8 | // Die 4 Checksum Register auf 0x00 zurücksetzen
|
9 | CRC.CTRL = (CRC.CTRL & (~CRC_RESET_gm)) | CRC_RESET_RESET0_gc;
|
10 |
|
11 | // Den CRC-Kern anhalten, indem keine Quellec angegeben wird
|
12 | CRC.CTRL = (CRC.CTRL & (~CRC_SOURCE_gm)) | CRC_SOURCE_DISABLE_gc;
|
13 |
|
14 | // Den CRC-Kern auf CRC16 konfigurieren
|
15 | CRC.CTRL &= ~CRC_CRC32_bm;
|
16 |
|
17 | // IO als Quelle für den CRC-Kern auswhählen
|
18 | CRC.CTRL = (CRC.CTRL & (~CRC_SOURCE_gm)) | CRC_SOURCE_IO_gc;
|
19 |
|
20 | //ACHTUNG IST RESET IMMER NOCH 1?
|
21 | CRC.CTRL &= ~CRC_RESET_gm;
|
22 |
|
23 | for(i=0; i<count; i++)
|
24 | {
|
25 | CRC.DATAIN = data[i];
|
26 | }
|
27 |
|
28 | // Das Busy Flag muss im CRC IO-Modus gelöscht werden, indem eine 1 in das Register geschrieben wird
|
29 | CRC.STATUS |= CRC_BUSY_bm;
|
30 |
|
31 | while((CRC.STATUS & CRC_BUSY_bm) == CRC_BUSY_bm)
|
32 | {
|
33 | // Nichts machen solange der CRC-Kern noch beschäftigt ist
|
34 | }
|
35 |
|
36 | crc16_checksum = ((unsigned short) CRC.CHECKSUM0 & 0x00FF);
|
37 | crc16_checksum |= (((unsigned short) CRC.CHECKSUM1 << 8) & 0xFF00);
|
38 |
|
39 | // Den CRC-Kern anhalten, indem keine Quellec angegeben wird
|
40 | CRC.CTRL = (CRC.CTRL & (~CRC_SOURCE_gm)) | CRC_SOURCE_DISABLE_gc;
|
41 |
|
42 | return crc16_checksum;
|
43 | }
|
44 |
|
45 | //Im Hauptprogramm erzeuge ich ein Array mit 8 Bytes (vorbelegt)
|
46 |
|
47 | /*Dann rufe ich die Funktion auf und übertrage die Checksumme an den PC über eine RS232 Leitung. Jedoch kommt immer als Checksumme 0 raus. HIIILFE*/
|
48 |
|
49 | unsigned char crc_testdata[8] = {0x43, 0x23, 0x83, 0x10, 0x82, 0x44, 0x92, 0x31};
|
50 | unsigned short crc16_checksum = 0;
|
51 |
|
52 | crc16_checksum = calculate_crc16_checksum(&crc_testdata[0], 8);
|
53 |
|
54 | printf("Die Checksumme lautet: %d", crc16_checksum);
|