Hallo zusammen, ich schreibe gerade an einer UART Kommunikation, bei der Eigentliche Hex-Bytes also z.B 0xC2 als 2 einzelne Char (je ein byte) C und 2 übermittelt werden. Einseitig habe ich die Umwandlung mit Bitmanipulation und einem Hilfsarray hinbekommen, jedoch klappt der folgende Weg nicht. Es liegt C als Char vor, also 0x43 und somit 0100 0011 ebenso wie 2 also 0x32 und somit 0011 0010 Nun möchte ich diese beiden Chars wieder zu einem Hexwert zusammenfügen. Leidet kommt bei meinem Veruschen alles raus, aber nicht dass was ich möchte, nämlich 0xC2, also 1100 0010 Kann mir vielleicht jemand auf die Sprünge helfen. Bin mir fast sicher, dass ich nur einen Denkfehler hab. Besten Dank. Gruß Tobias
Aus einem Char, welches eine Zahl ist, einen Int zu machen ist ja kein Ding, weißt du, oder? Tipp: ATOI. Und aus dem Char C eine Zahl zu machen ist ja auch kein Ding, könnte man über eine Switch-Case-Funktion lesen, es sind ja nur 6 Werte, die bei rum kommen können.
Tobias S. schrieb: > Bin mir fast sicher, dass ich nur einen Denkfehler hab. Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die Sprache, in der du programmierst... Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe. So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr viel darüber.
c-hater schrieb: > Tobias S. schrieb: > >> Bin mir fast sicher, dass ich nur einen Denkfehler hab. > > Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die > Sprache, in der du programmierst... > > Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe. > So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr > viel darüber. Diesen Schwätzer einfach nicht beachten. Der kann nichts, der macht sich nur wichtig.
Michael K. schrieb: > Aus einem Char, welches eine Zahl ist, einen Int zu machen ist ja > kein > Ding, weißt du, oder? Tipp: ATOI. > Und aus dem Char C eine Zahl zu machen ist ja auch kein Ding, könnte man > über eine Switch-Case-Funktion lesen, es sind ja nur 6 Werte, die bei > rum kommen können. Hallo Michael, ja das ist korrekt. Nur fuchst es mich etwas, dass ich es nicht mit Bitmanipulation hinbekommen. Im Endeffekt ist es ja nur ein zusammenführen von 2 nibble. Nur genau beim verschieben und Ver"UND"en ist wahrscheinlich mein Fehler. Gruß Tobias
Juven schrieb: > c-hater schrieb: >> Tobias S. schrieb: >> >>> Bin mir fast sicher, dass ich nur einen Denkfehler hab. >> >> Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die >> Sprache, in der du programmierst... >> >> Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe. >> So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr >> viel darüber. > > Diesen Schwätzer einfach nicht beachten. Der kann nichts, der macht sich > nur wichtig. Das hab ich bemerkt, ich ignoriere das jetzt einfach dezent
Hallo, was ist das Problem? Die 2 Char als 8-Bit Wert betrachten. Ist der Wert größer als 9 (0x39) dann - 0x37, wenn nicht -0x30. Den höherwertigen teil * 16 oder 4 Bit nach links schieben. Den niederwertigen Teil genauso behandeln und mit den oberen ver-odern. Macht man beim konvertiren von Bin nach Hex genauso, nur andersrum. Gruß aus Berlin Michael
Tobias S. schrieb: > Kann mir vielleicht jemand auf die Sprünge helfen. Fang damit an, dir eine Funktion zu schreiben, die aus EINEM Character den entsprechenden Zahlenwert generiert. Das ist an für sich leicht. Denn wenn dieses Zeichen im Bereich '0' bis '9' liegt, dann brauchst du vom ASCII Code des Zeichens nur den ASCII COde von '0' abziehen und du hast den numerischen Wert. Liegt das Zeichen aber im Bereich 'A' bis 'F', dann ziehst du von ihm den ASCII COde von 'A' ab und addierst wieder 10. Dann das Hexadezimale Digit A hat ja den dezimalen Wert 10.
1 | uint8_t toHexDigit( char c ) |
2 | {
|
3 | if( c >= '0' && c <= '9' ) |
4 | return c - '0'; |
5 | |
6 | if( c >= 'A' && c <= 'F' ) |
7 | return c - 'A' + 10; |
8 | |
9 | return 0; |
AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den geneigten Leser gedacht. Um aus 2 eingehenden Zeichen die enstprechende Zahl zu machen ist dann einfach
1 | uint8_t zahl = toHexDigi( erstes_Zeichen ) * 16 + toHexDigit( zweites_Zeichen ); |
> Bin mir fast sicher, dass ich nur einen Denkfehler hab.
es wäre gut, wenn du COde zeigen würdest. Dann könnte man dir zeigen, wo
du den Denkfehler hast.
:
Bearbeitet durch User
Tobias S. schrieb: > Nur genau beim verschieben und Ver"UND"en ist wahrscheinlich mein > Fehler. Ich hoffe du hast nicht wirklich ein UND gemacht. Da bleibt nichts mehr übrig von deinen Nibbles. Du meinst wohl OR.
Tobias S. schrieb: > Nur genau beim verschieben und Ver"UND"en ist wahrscheinlich mein > Fehler. Überlass solchen Kleinscheiss dem Compiler. der kann das. Für dich ist es ganz einfach: Um aus den beiden dezimalen Ziffern 3 und 4 die Zahl 34 zu erzeugen, rechnest du
1 | 3 * 10 -> 30 |
2 | + 4 |
3 | ------ |
4 | 34 |
und nichts anderes machst du bei Hex-Ziffern. Nur dass du anstelle von 10 mit 16 multiplizierst. Denn genau deswegen ist es ja das Hexadezimalsystem.
Karl H. schrieb: > Tobias S. schrieb: > >> Kann mir vielleicht jemand auf die Sprünge helfen. > > Fang damit an, dir eine Funktion zu schreiben, die aus EINEM Character > den entsprechenden Zahlenwert generiert. > Das ist an für sich leicht. Denn wenn dieses Zeichen im Bereich '0' bis > '9' liegt, dann brauchst du vom ASCII Code des Zeichens nur den ASCII > COde von '0' abziehen und du hast den numerischen Wert. Liegt das > Zeichen aber im Bereich 'A' bis 'F', dann ziehst du von ihm den ASCII > COde von 'A' ab und addierst wieder 10. Dann das Hexadezimale Digit A > hat ja den dezimalen Wert 10. > uint8_t toHexDigit( char c ) > { > if( c >= '0' && c <= '9' ) > return c - '0'; > > if( c >= 'A' && c <= 'F' ) > return c - 'A' + 10; > > return 0; > > AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den > geneigten Leser gedacht. > > Um aus 2 eingehenden Zeichen die enstprechende Zahl zu machen ist dann > einfachuint8_t zahl = toHexDigi( erstes_Zeichen ) * 16 + toHexDigit( > zweites_Zeichen ); > >> Bin mir fast sicher, dass ich nur einen Denkfehler hab. > > es wäre gut, wenn du COde zeigen würdest. Dann könnte man dir zeigen, wo > du den Denkfehler hast. Vielen Dank, du wirst lachen, oder mir es nicht glauben, aber genau den Ansatz habe ich jetzt gerade aufgeschrieben. Das macht mich jetzt aus eigenem Interesse nicht ganz glücklich aber es klappt auf jeden Fall.. Also vielen Dank, für eure Hilfe :) Gruß Tobias
#include <stdio.h> unsigned char asc2char(unsigned char ziffhi, unsigned char zifflo) { unsigned char ziff2nibble(unsigned char ziff) { if (ziff < ':') { return ziff - 48; } if (ziff < 'G') { return ziff - 55; } return (ziff - 87); } return (ziff2nibble(ziffhi) << 4) + ziff2nibble(zifflo); } int main(void) { unsigned char by; by= asc2char('f','3'); printf("\n\r%.2X\n\r",by); return 0; }
Ralph S. schrieb: > #include <stdio.h> > > unsigned char asc2char(unsigned char ziffhi, unsigned char zifflo) > { > unsigned char ziff2nibble(unsigned char ziff) > { > if (ziff < ':') { return ziff - 48; } Autsch. Gewöhn dir diesen Unsinn ab, die ASCII Codes direkt hinzuschreiben. Wenn du '0' meinst, dann schreib auch '0'
1 | .... return ziff - '0'; |
... dann ... muesste ich auch schreiben: return ziff - 'A' + 10; Hmm, ich komme noch von "richtig alten Zeiten" als ein Compiler noch nicht so "schlau" war und ein -'A' + 10 intern NICHT optimierte und daraus noch eine Rechenoperation mehr machte... (smile ... die "Entry-Punkte" für '0', 'a', 'A' des Ascii-Codes sind mir damals ins Blut gelegt worden) Der Uralte Compiler war damals ein Compiler fuer einen 8048 MCU auf einem HP-150 Rechner mit C/PM 86 Sorry (werde mich bei weiteren Codeschnippseln "bessern") Ralph PS: ich weiß nicht mehr welcher C- Compiler das war .... irgendwie muß das um das Jahr 1981 gewesen sein (da war ich mit der Lehre gerade fertig)
Ralph S. schrieb: > ... dann ... muesste ich auch schreiben: > > return ziff - 'A' + 10; Ja. Klar. so ist es doch viel einfacher zu verstehen, was hier die Absicht ist. > Hmm, ich komme noch von "richtig alten Zeiten" als ein Compiler noch > nicht so "schlau" war und ein -'A' + 10 intern NICHT optimierte und > daraus noch eine Rechenoperation mehr machte... Ah geh. Schon die ersten Compiler vor Beginn der Zeitrechnung konnten Constant Folding. Das ist die simpelste aller Übungen für einen Compiler. Einen Expression Tree muss er sich sowieso aufbauen, um notwendige Casts einzubauen. Diesen Baum dann noch einmal rekursiv abklappern, bei jeden Operations-Knoten links im Baum nachsehen, ob da eine Konstante steht, rechts nachsehen ob eine Konstante steht und wenn ja den Operationsknoten samt linken und rechtem Subknoten durch das ausgerechnete Ergebnis zu ersetzen, ist trivial. Wenn ein Compiler das nicht kann, dann nur aus stinkender Faulheit des Compilerbauers. Technisch sind zumindest die einfacheren Formen von Constant Folding bei dem die Konstanten direkt hintereinander kommen ein Kinderspiel.
:
Bearbeitet durch User
oder so: return (ziff <= '9' ? ziff&0x0F : (ziff&0x0F)+9);
>AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den >geneigten Leser gedacht. evtl. solltem an noch abfangen das ein böser Bube auch mal: Q§ W° R+ T" Z* Uç I% O& P/ ü( l) K= j? S` ~^ '... oder ein paar Steuerzeichen senden könnte. hat mit der gestellten Frage nichts mehr zu tun aber die ist ja auch beantwortet hauspapa
Der Vollständigkeit halber: Kleine Erweiterung, damit Karls Funktion auch mit Kleinbuchstaben als Hexziffern umgehen kann:
1 | uint8_t toHexDigit( char c ) |
2 | {
|
3 | if( c >= '0' && c <= '9' ) |
4 | return c - '0'; |
5 | |
6 | if( c >= 'A' && c <= 'F' ) |
7 | return c - 'A' + 10; |
8 | |
9 | if( c >= 'a' && c <= 'f' ) |
10 | return c - 'a' + 10; |
11 | |
12 | return 0; |
13 | }
|
Gruß, Stefan
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.