Forum: Mikrocontroller und Digitale Elektronik CRC Funktion übersetzen (so das diese auf GCC läuft)


von Jens Meisen (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

ich möchte gerne einen Maxon Motor via UART Ansteuern
(EPOS2 Motion Controller), alle Befehle bekommen hier
eine Prüfsumme (siehe Seite 23-24 im
Anhang, falls es jemanden interessiert).

Diese Beispiel müßte ich jedenfalls zum laufen kriegen.
1
WORD CalcFieldCRC(WORD* pDataArray, WORD numberOfWords) {
2
3
  WORD shifter, c;
4
  WORD carry;
5
  WORD CRC = 0;
6
7
  //Calculate pDataArray Word by Word
8
  while(numberOfWords--) {
9
10
    shifter = 0x8000;   //Initialize BitX to Bit15
11
    c = *pDataArray++;   //Copy next DataWord to c
12
13
    do {
14
      carry = CRC & 0x8000;     //Check if Bit15 of CRC is set
15
      CRC <<= 1;           //CRC = CRC * 2
16
      if(c & shifter) CRC++;     //CRC = CRC + 1, if BitX is set in c
17
      if(carry) CRC ^= 0x1021;   //CRC = CRC XOR G(x), if carry is true
18
      shifter >>= 1;         //Set BitX to next lower Bit, shifter = shifter/2
19
    } while(shifter);
20
  }
21
  return CRC
22
}

habe ich soweit für GCC "übersetzt" :)
1
uint16_t CalcFieldCRC(volatile uint16_t *pDataArray, uint16_t numberOfWords) {
2
3
  uint16_t shifter;
4
  uint16_t c;
5
  uint16_t carry;
6
  uint16_t _CRC = 0;
7
8
  //Calculate pDataArray Word by Word
9
  while(numberOfWords--) {
10
11
    shifter = 0x8000;   //Initialize BitX to Bit15
12
    c = *pDataArray++;   //Copy next DataWord to c
13
14
    do {
15
      carry = _CRC & 0x8000;     //Check if Bit15 of _CRC is set
16
      _CRC <<= 1;           //_CRC = _CRC * 2
17
      if(c & shifter) _CRC++;     //_CRC = _CRC + 1, if BitX is set in c
18
      if(carry) _CRC ^= 0x1021;  //_CRC = _CRC XOR G(x), if carry is true
19
      shifter >>= 1;         //Set BitX to next lower Bit, shifter = shifter/2
20
    } while(shifter);
21
  }
22
  return _CRC;
23
}

als genanntes Beispiel müßte der
Datensatz 0x10 0x01 0x03 0x20 0x01 0x02 0x00 0x00
0xA888 ergeben, ich komme so aber auf 0x497E

Weiß jemand vielleicht von Euch, ob man die Bitshift
Anweisungen in GGC so auch übernehmen kann?
(Ich kenne mich mit Bitshift leider nicht aus, habe ich
alles soweit übernommen)

Über Hilfe würde ich mich sehr freuen.

Vielen Dank & Viele Grüße
Jens

von Dr. Sommer (Gast)


Lesenswert?

Typedef kennst du?
1
typedef uint16_t WORD;
und deine "Übersetzung" wäre fertig. Oder einfach die Header einbinden, 
die vom Original-Code eingebunden werden, dann hast du auch die "WORD" 
Definition, denn die hat nichts mit dem Compiler zu tun... Die findet 
sich zB in der <windows.h>

von Stefan E. (sternst)


Lesenswert?

Jens Meisen schrieb:
> als genanntes Beispiel müßte der
> Datensatz 0x10 0x01 0x03 0x20 0x01 0x02 0x00 0x00
> 0xA888 ergeben, ich komme so aber auf 0x497E

Bist du denn auch sicher, die Funktion überhaupt richtig zu "füttern"? 
Mich macht es z.B. stutzig, dass du hier deinen Datensatz in Form von 
Bytes präsentierst, die Funktion aber offensichtlich einen Datensatz aus 
Words erwartet.

von TestX .. (xaos)


Lesenswert?

@jens
nächstes mal die anleitung lesen... unter 5.1.8 siehst du wie die frame 
aufgebaut werden müssen...hier so gehts:

zum einen erwartet die funktion wie schon erwähnt 16bit werte, zum 
anderen musst du aufpassen wie die werte zusammengestezt werden 
(high/low byte)
1
#include <unistd.h>
2
#include <stdint.h>
3
#include <stdio.h>
4
#include <string.h>
5
6
uint16_t CalcFieldCRC(volatile uint16_t *pDataArray, uint16_t numberOfWords) {
7
8
  uint16_t shifter;
9
  uint16_t c;
10
  uint16_t carry;
11
  uint16_t _CRC = 0;
12
13
  //Calculate pDataArray Word by Word
14
  while(numberOfWords--) {
15
16
    shifter = 0x8000;   //Initialize BitX to Bit15
17
    c = *pDataArray;   //Copy next DataWord to c
18
    pDataArray++;
19
20
    do {
21
      carry = _CRC & 0x8000;     //Check if Bit15 of _CRC is set
22
      _CRC <<= 1;           //_CRC = _CRC * 2
23
      if(c & shifter) _CRC++;     //_CRC = _CRC + 1, if BitX is set in c
24
      if(carry) _CRC ^= 0x1021;  //_CRC = _CRC XOR G(x), if carry is true
25
      shifter >>= 1;         //Set BitX to next lower Bit, shifter = shifter/2
26
    } while(shifter);
27
  }
28
  return _CRC;
29
}
30
31
32
33
int main(){
34
35
   uint16_t data[] = {0x1001, 0x2003, 0x0201, 0x0000};
36
37
   uint16_t crc = CalcFieldCRC(data, 4);
38
39
   printf("%x \n", crc);
40
41
return 0;
42
}

von Jens Meisen (Gast)


Lesenswert?

Ganz herzlichen Dank!!!

Die Zusammensetzung von den vier uint16_t ist ja tückisch.
- Erster Wert wird normal zusammengesetzt aus zwei uint8_t
- Zweiter Wert ist uint16_t, bleibt alles wie es ist
- Dritter Wert high/low vertauscht, aus zwei uint8_t

und dann stimmt die Prüfsumme :)

und alles wird dann wieder auseinander genommen und mit
in uint8_t (uint16_t high/low getauscht, jetzt aber nur der
zweite Wert und die Prüfsumme) an die Motoren geschickt...

ohgottogott, zum Glück gibt das Forum :)

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.