Guten Tag, Kann vielleicht einer mit dem C Code hierfür helfen? Habe selbst hunderte Varianten probiert, aktuell keine Ideen mehr. Der kurze Beitrag und kein Eigenvorschlag sind der Frustration geschuldet. Schönes Wochenende und liebe Grüße
Alex schrieb: > Kann vielleicht einer mit dem C Code hierfür helfen? Du hast vergessen, den C-Code anzuhängen, zu dem du Hilfe erbittest.
Steve van de Grens schrieb: > Alex schrieb: >> Kann vielleicht einer mit dem C Code hierfür helfen? > > Du hast vergessen, den C-Code anzuhängen, zu dem du Hilfe erbittest. Hat er nicht. Er will das wir ihm den liefern. Natürlich für lau. Ein typischer Nassauer.
Alex schrieb: > Kann vielleicht einer mit dem C Code hierfür helfen? > Habe selbst hunderte Varianten probiert, Das wage ich zu bezweifeln. Man könnte es auch eine glatte Lüge nennen. > aktuell keine Ideen mehr. Doch. Jammern und einen auf dumm machen. > Der kurze Beitrag und kein Eigenvorschlag sind der Frustration > geschuldet. Jaja, schöne Ausrede. > Schönes Wochenende und liebe Grüße Gleichfalls! Ansonsten, siehe CRC. HIer gibt es auch eine CRC-Funktion, die kann man leicht auf das Polynom anpassen. Beitrag "Re: Onewire + DS18x20 Library"
c-hater schrieb: > Natürlich für lau. Erwartest Du, dass er Dir Geld überweist? Vielleicht hat jemand den Code parat oder Lust, das Problem zu knacken, und dann einfach wie ein ganz normaler hilfsbereiter Mensch zu antworten, der nicht die Frage infrage stellt.
MaWin schrieb: > Immer wieder diese freundlichen und hilfsbereiten Leute im Forum hier. Auch Falk hat dem TO den entscheidenden Tipp gegeben - neben meinem Hinweis auf die Wikipedia. Eine Lösung ‚frei Haus‘ zu liefern hilt dem TO bei seinen Hausaufgaben jedenfalls nicht: Die aufgezeichneten Beispiele sind sehr einfach nachvollziehbar - und ich bin der Ansicht, diese kleine Mühe sollte der TO sich schon selbst machen. Aber ich kann mich natürlich auch täuschen...
Eine 3 Bit CRC ... 8 mögliche Werte. Du kannst jedes Bit einzeln auswerten. Bei 1 gibt es für jeden Wert genau einen Folgewert, bei 0 einen anderen.
Ich hab die CRC3 Berechung mal zusammengebastelt. Funktioniert. Aber den Quelltext gibt's nicht so einfach. Dazu muss der OP schon etwas Eigeninitiative vorweisen. Hier mal der Anfang ;-)
1 | uint8_t crc3(uint16_t data) { |
2 | |
3 | uint8_t i, crc, poly=0x3; |
4 | |
5 | // insert your code here
|
6 | |
7 | return crc; |
8 | }
|
:
Bearbeitet durch User
Hier ist eine ausführliche Erklärung zur CRC Berechnung: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html Um die PSI5 3-Bit CRC zu implementieren reicht im Prinzip "3. Concept of the CRC shift register". Dazu dann aus der PSI5 Spezifikation "3.2.2 Error Detection" und man bekommst das mit ein paar Zeilen C Code hin, der dann auch die gewünschten Ergebnisse liefert (das Polynom ist 0x03, die Registerlänge natürlich 3 Bit, initialisiert wird das Register mit 0x7 und die drei "0" Bits laut der PSI5 Spezifikation sollte man nicht vergessen.)
Jester schrieb: > https://de.wikipedia.org/wiki/Zyklische_Redundanzpr%C3%BCfung#Umsetzung Das nervt kollossal, wenn Schlaumeier wie du auf WP linken! Das hat der TE ganz sicher direkt auch gemacht. Was er aber wissen wollte ist, wie er das macht, weil er die Seite nicht versteht.
Kritiker schrieb: > Was er aber wissen wollte ist, wie er das macht, weil er die Seite nicht > versteht. Dann hätte er in der Vorlesung besser aufpassen sollen.
Nop schrieb: > Dann hätte er in der Vorlesung besser aufpassen sollen. Darum geht es nicht. Fragen stellen ist vollkommen OK, das ist der Sinn dieses Forums. Aber einen auf dumm machen und sich die Lösung auf dem Silbertablett servieren lassen nicht. Beitrag "Einheitlicher Umgang mit faulen Schülern etc.?" Hilfe zur Selbsthilfe.
Vielleicht hilft dieser Link weiter: https://books.google.at/books?id=qydjLSpxqlYC&pg=PA62&lpg=PA62&dq=crc+schieberegister&source=bl&ots=p3vVZXvhT2&sig=ACfU3U0VCoM1tI4c-DZrLWEwQfG24GtLEQ&hl=de&sa=X&ved=2ahUKEwjYiZmtnsz7AhWjXvEDHQvsCfkQ6AF6BAglEAI#v=onepage&q=crc%20schieberegister&f=false Man braucht nur die Schaltung in eien C-Code umsetzen. Man braucht sich nur an die Anleitung zu halten. Bei Bedarf kann ich eine Anleitung zur Umsetzung geben.
:
Bearbeitet durch User
Gerald K. schrieb: > Man braucht nur die Schaltung in eien C-Code umsetzen. Ach so, NUR einfach umsetzen. Na dann . . . > Man braucht sich nur an die Anleitung zu halten. Bei Bedarf kann ich > eine Anleitung zur Umsetzung geben. Was DU so alles kannst, beeindruckend!
Falk B. schrieb: > Gerald K. schrieb: > >> Man braucht nur die Schaltung in eien C-Code umsetzen. > > **Ach so, NUR einfach umsetzen. Na dann** . . . >> Man braucht sich nur an die Anleitung zu halten. Bei Bedarf kann ich >> eine Anleitung zur Umsetzung geben. > > Was DU so alles kannst, beeindruckend! Eine Anleitung zur schnellen (Implementierung) bitweisen Lösung in Pseudsprache: 1. initalisierung:
1 | { |
2 | C0=0; |
3 | C1=0; |
4 | C2=0; |
5 | } |
2. Schrittweise (bitweise) CRC3 Berechnung:
1 | { |
2 | Temp= LSBeingangsdatenbit xor C0; |
3 | C1=C2; |
4 | C0=C2 xor Temp; |
5 | C2=Temp; |
6 | } |
Nächstes Eingangsbit ins LSB schieben und Schritt 2 bis zum letzten Eingangsbit wiederholen. Dann steht der CRC3 in den Bits C2, C1 und C0 zur Verfügung. Der Pseudocode braucht nur in die gewünschte Sprache ASM,C, Pascal, VHDL ... übersetzt werden. Durch byteweise Verarbeitung wird die Programmausführung schneller, ist aber vom Algorithmus anspruchsvoller.
:
Bearbeitet durch User
Gerald K. schrieb: > Durch byteweise Verarbeitung wird die Programmausführung schneller, ist > aber vom Algorithmus anspruchsvoller. Bei nur 10 Bit Telegrammlänge könnte man auch einfach eine Tabelle mit 1024 Einträgen machen. Aber auch die muss erstmal berechnet werden 8-)
Falk B. schrieb: > Gerald K. schrieb: > >> Durch byteweise Verarbeitung wird die Programmausführung schneller, ist >> aber vom Algorithmus anspruchsvoller. > > Bei nur 10 Bit Telegrammlänge könnte man auch einfach eine Tabelle mit > 1024 Einträgen machen. Aber auch die muss erstmal berechnet werden 8-) Geht dann natürlich schneller, dafür ist der Speicheraufwand (2^10 x 3Bit) für den Programmcode (nur Tabelle) viel größer. Mit eiem Trick (1/2 Bit pro Eintrag) kommt man mit 512 Bytes aus.
:
Bearbeitet durch User
Unglaublich wie hier über ein paar triviale C Code Zeilen diskutiert wird. Man könnte das z.B. so machen (Optimieren kann man das später beliebig):
1 | /* |
2 | |
3 | PSI5 3-bit CRC |
4 | |
5 | see http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html |
6 | |
7 | "3. Concept of the CRC shift register" |
8 | |
9 | Implement Step 2: |
10 | |
11 | Shift in the input stream bit by bit. If the popped out MSB is a '1', |
12 | XOR the register value with the generator polynomial. |
13 | |
14 | Input: 3-bit CRC register (uint8_t crc) |
15 | one data bit (bool bBit) |
16 | |
17 | Return: updated CRC register |
18 | |
19 | */ |
20 | |
21 | uint8_t psi5_crc_3bit(uint8_t crc, bool bBit) |
22 | { |
23 | const uint8_t polynom = 0x03; /* g(x)= 1 + x + x^3 */ |
24 | |
25 | /* shift in data bit */ |
26 | |
27 | crc = (crc << 1) | (bBit ? 0x01 : 0x00); |
28 | |
29 | /* check if popped out MSB of 3-bit register is set */ |
30 | |
31 | if(crc & 0x08) |
32 | crc = crc ^ polynom; |
33 | |
34 | /* 3-bit register */ |
35 | |
36 | return crc & 0x07; |
37 | } |
Den CRC Register beim Start korrekt zu initialiseren und die Funktion für die einzelnen Datenbits aufzurufen sollte ja klar sein.
Dieter schrieb: > const uint8_t polynom = 0x03; /* g(x)= 1 + x + x^3 */ Stimmt das Polynom? In der Schaltung mit den Schieberegistern ist zwischen C0 und C1 eine Lücke.
Es fehlt C2 x^3
:
Bearbeitet durch User
Gerald K. schrieb: > > Stimmt das Polynom? So steht es zumindest in der PSI5 Technical Specification V1.3 auf Page 16/46, Kapitel "3.2.2 Error Detection".
Nach dem wir genügend Vorarbeit geleistet haben kann Alex einmal den Code ausprobieren. Dann werden wir sehen.
Dieter schrieb: > Gerald K. schrieb: > >> Es fehlt C2 x^3 > > Das CRC Register ist 3-Bit lang, x^3 wäre Bit 4. Für x^0 gibt es kein Register. Dann sind es wieder 3. Aber ich kann mich durchaus irren.
Gerald K. schrieb: > Nach dem wir genügend Vorarbeit geleistet haben kann Alex einmal den > Code ausprobieren. Dann werden wir sehen. Bei meinem Test mit obigen Code kam das raus was in "3-bit_CRC.png" zu sehen ist. Den Hinweis mit der richtigen Initialisierung des CRC Register und den drei zusätzlichen "0" Bits haben ich bereits gegeben. Man kann das Ganze auch ohne Programmierung mit dem passenden Tool, z.B. CRC RevEng verifizieren.
Gerald K. schrieb: > > Für x^0 gibt es kein Register. Dann sind es wieder 3. Nein, die höchste Stelle des Polynom ist hier überflüssig. x^0 ist das LSB des Polynom. Im Bild aus der PSI5 Spezifikation sieht man das gut (auch wenn die Datenbits von links rein kommen, von rechts wäre es noch offensichtlicher).
Es zählen nur die Terme mit den Rückkopplungen über xor. Das Polynom bezieht sich nicht auf die Bit, sondern auf die Rückkopplungen. Mit ist noch ein Unterschied zur Schaltung im Link https://books.google.at/books?id=qydjLSpxqlYC&pg=PA62&lpg=PA62&dq=crc+schieberegister&source=bl&ots=p3vVZXvhT2&sig=ACfU3U0VCoM1tI4c-DZrLWEwQfG24GtLEQ&hl=de&sa=X&ved=2ahUKEwjYiZmtnsz7AhWjXvEDHQvsCfkQ6AF6BAglEAI#v=onepage&q=crc%20schieberegister&f=false aufgefallen. Die Schieberichtung ist umgekehrt.
:
Bearbeitet durch User
Dieter schrieb: > Gerald K. schrieb: >> >> Es fehlt C2 x^3 > > Das CRC Register ist 3-Bit lang, x^3 wäre Bit 4. Das ist korrekt und Eigenschaft ALLER CRC-Polynome.
Gerald K. schrieb: >> Das CRC Register ist 3-Bit lang, x^3 wäre Bit 4. > > Für x^0 gibt es kein Register. Dann sind es wieder 3. > > Aber ich kann mich durchaus irren. Das tust du ;-) X^0 ist Bit 0
Guten Tag, nachdem ich den Anfang vom Thread gelesen habe, habe ich länger nicht mehr reingeschaut. Vielen Dank an alle, die sich zum Thema beteiligt haben. Hier ist meine Lösung, die ganz sicher funktioniert. Das ist nicht komplett meine, aber ich habe es soweit angepasst, dass es passt. In meinem Fall sind es 20 Bits Nutzdaten. Kann jeder nachrechnen.
1 | uint8_t crc_calc(uint32_t Input) { |
2 | volatile uint8_t CRC[3]={1,1,1}; |
3 | volatile uint8_t CRCa[3]; |
4 | |
5 | for(int i=0; i<=22 ; i=i+1){ |
6 | CRCa[2]= CRC[1]; |
7 | CRCa[1]= CRC[0]^CRC[2]; |
8 | CRCa[0] = CRC[2]^((Input >> i) & 0x01); |
9 | crc = ((CRCa[2] << 2) | (CRCa[1] << 1) | (CRCa[0] & 0x01)); |
10 | }
|
11 | return crc; |
12 | }
|
13 | |
14 | uint32_t Daten = 0x7FFFFF; |
15 | uint8_t crc = 0; |
>Vielleicht hat jemand den Code parat
Das war so mein Gedanke
Schöne Grüße
Alex schrieb: > > Hier ist meine Lösung, die ganz sicher funktioniert. Ja, ganz sicher. > Kann jeder nachrechnen. Auch das. Falls Du ernsthaft meinst dass der Code etwas sinnvolles berechnet solltest Du besser irgendwas anders machen als in C programmieren. Tipp: CRCa[2] ist immer 1 und CRCa[1] ist immer 0.
Übertragungsfehler, sorry.
1 | uint32_t Daten = 0x000; |
2 | uint8_t crc = 0; |
3 | |
4 | |
5 | uint8_t crc_calc(uint32_t Input) { |
6 | volatile uint8_t CRC[3]={1,1,1}; |
7 | volatile uint8_t CRCa[3]; |
8 | |
9 | for(int i=0; i<=12 ; i=i+1){ |
10 | CRCa[2]= CRC[1]; |
11 | CRCa[1]= CRC[0]^CRC[2]; |
12 | CRCa[0] = CRC[2]^((Input >> i) & 0x01); |
13 | |
14 | CRC[0] = CRCa[0]; |
15 | CRC[1] = CRCa[1]; |
16 | CRC[2] = CRCa[2]; |
17 | |
18 | crc = ((CRCa[2] << 2) | (CRCa[1] << 1) | (CRCa[0] & 0x01)); |
19 | }
|
20 | return crc; |
21 | }
|
22 | |
23 | |
24 | |
25 | int main(void) |
26 | {
|
27 | |
28 | crc = crc_calc(Daten); |
29 | printf("0x%x\n", crc); |
30 | |
31 | for(;;) |
32 | {
|
33 | |
34 | }
|
35 | }
|
Falk B. schrieb: > Bei nur 10 Bit Telegrammlänge könnte man auch einfach eine Tabelle mit > 1024 Einträgen machen. Aber auch die muss erstmal berechnet werden 8-) Das wäre dann etwa das gleiche Niveau, wie machen Steuerberechnung in Deutschland.
Alex schrieb: > Hier ist meine Lösung, die ganz sicher funktioniert. Damit wäre das Problem doch gelöst. > Das ist nicht komplett meine, aber ich habe es soweit angepasst, dass es > passt. > In meinem Fall sind es 20 Bits Nutzdaten. > Kann jeder nachrechnen.uint8_t crc_calc(uint32_t Input) { > volatile uint8_t CRC[3]={1,1,1}; > volatile uint8_t CRCa[3]; Wozu soll volatile gut sein? Braucht hier keiner. Und warum nutzt du zwei Array die die CRC? Das kann man zwar machen, ist aber weder üblich noch von Vorteil. > for(int i=0; i<=22 ; i=i+1){ > CRCa[2]= CRC[1]; > CRCa[1]= CRC[0]^CRC[2]; > CRCa[0] = CRC[2]^((Input >> i) & 0x01); Naja, das funktioniert zwar, ist aber sehr akademisch. > crc = ((CRCa[2] << 2) | (CRCa[1] << 1) | (CRCa[0] & 0x01)); Und hier muss das Array wieder in einen normalen 3 Bit Wert umgewandelt werden. Warum muss das bei jedem Schleifendurchgang erfolgen? Das reicht auch auch EINMALIG nach der Schleife. Wenn man es gleich richtig macht, entfällt das alles. Siehe Bitmanipulation.
Hier meine Version mit normaler Bitmanipulation.
1 | #include <stdint.h> |
2 | |
3 | uint8_t crc3(uint16_t data) { |
4 | |
5 | uint8_t i, crc, poly=0x3; |
6 | |
7 | crc = 0x7; |
8 | data &= 0x3FF; |
9 | for (i=0; i<13; i++) { |
10 | if (crc & 0x04) { |
11 | crc <<= 1; |
12 | if (data & 1) crc |= 0x01; // copy LSB to LSB |
13 | crc ^= poly; |
14 | } else { |
15 | crc <<= 1; |
16 | if (data & 1) crc |= 0x01; // copy LSB to LSB |
17 | }
|
18 | data >>= 1; |
19 | }
|
20 | return crc & 0x7; |
21 | }
|
22 | |
23 | int main(void) { |
24 | |
25 | uint16_t crc; |
26 | |
27 | crc = crc3(0x000); // CRC 6 |
28 | crc = crc3(0x0CC); // CRC 3 |
29 | crc = crc3(0x151); // CRC 0 |
30 | crc = crc3(0x1E0); // CRC 3 |
31 | }
|
Falk B. schrieb: > uint16_t crc; > crc = crc3(0x000); // CRC 6 Wieso du ein u8 als return in einer u16 speicherst ist mir schleierhaft.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.