Forum: Mikrocontroller und Digitale Elektronik Hex zu String Zuweisung: Funktion in C?


von Moe E. (moe_espunkt)


Lesenswert?

Hallo Zusammen,

um eine CRC-Berechnung durchzuführen möchte ich den Quellcode von 
http://www.zorc.breitbandkatze.de/crctester.c verwenden. Der scheint 
auch sehr gut zu funktionieren.

Im Quellcode selber muss man lediglich den CRC-Rechner parametrieren und 
seinen gewünschten Datenwert, auf den die CRC-Berechnung durchgeführt 
werden soll, in das folgende Array schreiben:
1
const unsigned char string[] = {"012345ABCDEF"};

Nun mein Problem: die Daten, auf die ich die CRC-Berechnung durchführen 
möchte liegen in folgender Form vor:
1
int test_value[16] = {1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1}; // 0xFA01

Ich kann ja nicht einfach schreiben:
1
const unsigned char string[] = {"FA01"};

das führt nämlich zu einem falschen CRC-Wert. Ich wollte daher das Array 
test_value[16] in ein Hexwert umwandeln und anschließen den Hexwert in 
äquivalente Charzeichen wandeln.

Daher meine Frage: gibt es vielleicht schon fertige Funktionen in C die 
mir aus Hex das entsprechende Char machen? Oder hat jemand sogar eine 
bessere Lösung für das Problem?

Ich hatte bereits schon gegoogelt und immer bin ich entweder auf 
Funktionen für C# gestoßen oder die Quellcode vorschläge haben aus 
irgendwelchen Gründen bei mir nicht funktoniert (wahrscheinlich fehlende 
Erfahrung, da ich noch Anfänger bin)

Ich würde mich wirklich sehr über Hilfe freuen, da ich jetzt schon seit 
Wochen versuche eine einface CRC-Berechnung zu realisieren und mir schon 
die Zähne ausbeiße.

Vielen Dank im voraus udn viele Grüße

von Harry (Gast)


Lesenswert?

Haste mal versucht deinen Int-Wert direkt als
1
int test_value=0xFA01;
 zu speichern und den in das char array zu konvertieren?

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Einfach mit 0xf maskieren, dann um 4bit nach rechts verschieben, und 
wiederholen.

Eine Konstante zu addieren ist Asbach technologie, also besser in eine 
Tabelle zeigen mit dem gewuenschtem Char oder was auch immer.

Falls du 16 binaerwerte hast, musst du ggf. erst nach HEX umwandeln, die 
erste Stelle ist 1, dann 2, dann 4 usw.

Ja gibt es auch funktionen dazu, allerdings gibst du nicht an, welchen 
Compiler du verwendest. Also kein Hinweis auf Dokumentation moeglich.

von Karl H. (kbuchegg)


Lesenswert?

Moe Espunkt schrieb:
> Oder hat jemand sogar eine
> bessere Lösung für das Problem?

Oder


Warum liegen deine Daten in dieser Form vor?
Um 16 Bits zu speichern, ist das hier
1
int test_value[16] = {1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1}; // 0xFA01
so ziemlich die dümmste Version, die du finden kannst.

Setzte hier an und speichere deine 16 Bits auch als 16 Bit Zahl in einem 
16 Bit unsigned int (2 Bytes) und nicht als Einzelbits in einem Array.

Edit: Es sei denn natürlich, du hast einen extrem guten Grund, warum dir 
ein Array lieber ist. "Häufige Zugriffe und Veränderungen" würden zb. 
als extrem guter Grund qualifizieren. "Weil ich es nicht besser kann' 
ist hingegen kein akzeptabler extrem guter Grund.

von _??? (Gast)


Lesenswert?

char *  itoa ( int value, char * str, int base );

von Moe E. (moe_espunkt)


Lesenswert?

Vielen Dank für deine Antwort

Karl Heinz schrieb:
> Moe Espunkt schrieb:
>> Oder hat jemand sogar eine
>> bessere Lösung für das Problem?
>
> Oder
>
>
> Warum liegen deine Daten in dieser Form vor?
> Um 16 Bits zu speichern, ist das hier
>
1
> int test_value[16] = {1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1}; // 0xFA01
2
>
> so ziemlich die dümmste Version, die du finden kannst.
>
> Setzte hier an und speichere deine 16 Bits auch als 16 Bit Zahl in einem
> 16 Bit unsigned int (2 Bytes) und nicht als Einzelbits in einem Array.
>
> Edit: Es sei denn natürlich, du hast einen extrem guten Grund, warum dir
> ein Array lieber ist. "Häufige Zugriffe und Veränderungen" würden zb.
> als extrem guter Grund qualifizieren. "Weil ich es nicht besser kann'
> ist hingegen kein akzeptabler extrem guter Grund.

Ich weiß, dass es sehr verschwenderisch ist und nicht sonderlich klug. 
Ist mir im nachhinein auch aufgefallen aber man wächst bekanntlich mit 
seiner Erfahrung.
Die Bits in dem Array brauche ich um später ein Pin des µC auf High bzw. 
Low zu setzen; dafür Frage ich den Wert der einzelnen Felder ab und 
setzte den Pin entsprechend. Ich wusste leider nicht wie ich den Pin auf 
High bzw. auf Low setzen kann bzw wie man von einem Hex-Wert jedes Bit 
abfragenn kann, wenn ich statt
1
int test_value[16] = {1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1}; // 0xFA01

es doch so schreibe
1
int test_value = 0xFA01;

gibt es möglichkeiten jedes Bit des Hex-Wertes abzufragen?

Für Verbesserungsvorschläge bin ich immer sehr dankbar.

von Mat (Gast)


Lesenswert?

1
if(test_value&0x0001)
2
{
3
   // Bit gesetzt
4
} else
5
{
6
   // Bit nicht gesetzt
7
}

Das kannst du für jedes beliebige Bit machen.
Weiteres dazu im GCC Tutorial auf dieser Seite.

gruß Mat

von Udo S. (urschmitt)


Lesenswert?

Du brauchst ein C Buch :-)

von Moe E. (moe_espunkt)


Lesenswert?

Udo Schmitt schrieb:
> Du brauchst ein C Buch :-)

Ich glaub auch ! hahaha

von Moe E. (moe_espunkt)


Lesenswert?

Mat schrieb:
>
1
> if(test_value&0x0001)
2
> {
3
>    // Bit gesetzt
4
> } else
5
> {
6
>    // Bit nicht gesetzt
7
> }
>
> Das kannst du für jedes beliebige Bit machen.
> Weiteres dazu im GCC Tutorial auf dieser Seite.
>
> gruß Mat

 Stimmt! Eigentlich ziemlich einfach.

Ohje.. das wird ein heiden Spaß alles umzustellen !!

von foo (Gast)


Lesenswert?

Moe Espunkt schrieb:
> Ich glaub auch ! hahaha

Geht's darum den CRC selbst zu implementieren?
Ist das nur einen Hausübung?
Kennst Du http://www.ross.net/crc/download/crc_v3.txt


Wenn nicht, pycrc kann auch C Code generieren...

von Karl H. (kbuchegg)


Lesenswert?

Moe Espunkt schrieb:

> Ohje.. das wird ein heiden Spaß alles umzustellen !!

Tja. Was lernen wir daraus?
Mach es gleich richtig.
Denn letzten Endes bleibt dir eh nichts anderes übrig. Jede irgendwie 
geartete 'Nachlässigkeit' fällt einem früher oder später irgendwann auf 
den Kopf.

Gezielt Bits zu setzen, zu löschen bzw. abzufragen (bzw. wenn die zb 
über eine UART reinstreamen oder rausstreamen) ist hingegen 
Grundfertigkeit in der µC-Programmierung. Ohne das Beherrschen dieser 
Grundfertigkeit kommt man nicht weit. Zumal die dazu benutzten Techniken 
relativ einfach sind (wenn man sie erst mal intus hat)

Bitmanipulation

von Moe E. (moe_espunkt)


Angehängte Dateien:

Lesenswert?

Ich werde es mir auf jeden Fall genauer angucken, Karl Heinz. Vielen 
Dank für deine Hilfe. Leider bin ich noch blutiger Anfänger und lerne 
erst durch solch "nicht ganz kluge" programmierweisen.

foo schrieb:
> Moe Espunkt schrieb:
>> Ich glaub auch ! hahaha
>
> Geht's darum den CRC selbst zu implementieren?
> Ist das nur einen Hausübung?
> Kennst Du http://www.ross.net/crc/download/crc_v3.txt
>
>
> Wenn nicht, pycrc kann auch C Code generieren...

Ich verwende den CRC-Code von 
http://www.zorc.breitbandkatze.de/crctester.c
den hab ich auch schon abgeändert (siehe Anhang). In das Array const 
unsigned char string[] habe ich meinen Datenwert rein gepackt. 
Normalerweise erwarte ich , wie im Bild (siehe Anhang ) den CRC-Wert von 
"0CA5" aber irgendwie kommt andauernd "0x89F1" heraus. Hingegen liefert 
mir PyCRC nur ein Wert von "0x89F1" wenn ich als Datenwert "FF011511" 
eingebe:
1
C:\Python34>python pycrc.py --mode x-25 --check-hexstring=FF011511
2
0x89f1

Es scheint als würde mein jetziger Code (im Anhang) die Nullen 
wegschneiden. Liegt das evtl an der Strlen()-Funktion?

von Karl H. (kbuchegg)


Lesenswert?

Moe Espunkt schrieb:


> wegschneiden. Liegt das evtl an der Strlen()-Funktion?

C-Buch(!)

Du hast keinen String!
Nicht alles was man in einem char Array (oder unsigned char) speichert, 
ist auch ein String.
IN deinem Fall hast du ein Array mit Bytes. Nicht mehr und nicht 
weniger. Da greift kein strlen. Ein C-String ist definitionsgemäss eine 
Abfolge von Bytes, an deren Ende ein Byte mit dem Wert 0x00 steht. D.h. 
für alle String Funktionen ist der String mit dem ersten 0x00 zu Ende. 
Egal wie lange das Array tatsächlich ist. Dein Array kann 200 chrs lang 
sein. Wenn du da drinn "Hallo World" speicherst, dann steht an der 12. 
Stelle im Array ein Byte mit dem Wert 0x00 und dient als Kennung, dass 
dort der im Array gespeicherte String zu Ende ist. strlen liefert dir 
korrekterweise als Ergebnis 11 und nicht 200.

Wenn du die definierte Länge eines Arrays brauchst, dann kannst du das 
so machen:
1
unsigned char string[] = { 0x20, 0x00, 0x80, 0xFF };
2
#define ARRAY_SIZE(x) ( sizeof(x) / sizeof(*x))
3
4
...
5
6
     crc_wert = crcbitbybit( string, ARRAY_SIZE(string) );

und nenn die Variable nicht 'string'. Das ist maximal einfach nur 
irreführend. Denn da ist kein String drinnen. Das sind einfach nur 
Bytes, oder ganz allgemein 'Daten'.
1
unsigned char data[] = { 0x20, 0x00, 0x80, 0xFF };
2
#define ARRAY_SIZE(x) ( sizeof(x) / sizeof(*x))
3
4
...
5
6
     crc_wert = crcbitbybit( data, ARRAY_SIZE(data) );

(und caste nicht, wenn du nicht musst. Damit versteckst du nur mögliche 
Fehler, weil du dem Compiler auf freundliche Art und Weise mitteilst: 
Selbst wenn da die Datentypen nicht stimmen .... Halt einfach die 
Schnauze

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.