Hallo zusammen, ich habe folgendes, für Euch wahrscheinlich triviales Problem. Und zwar habe ich einen Hex Wert den ich über eine serielle Schnittstelle an einer Konsolo ausgebe. Der Wert wird mir da natürlich als ASCII Zeichen interpretiert und auch als solches ausgegeben. Wie ist es möglich dass ich mir den Hex-Wert ausgeben lassen kann? Gruß
Es fängt schon mal damit an, daß Du gar keinen Hex-Wert hast, sondern einfach nur eine Zahl. Ob Hex, ob Dezimal oder Oktal, das ist alles nur eine Darstellungssache, die Zahl selbst interessiert sich nicht dafür. Und diese Zahl willst Du in Klartext umwandeln, und zwar so, daß sie in hexadezimaler Darstellung vorliegt. Da Du praktischerweise kein Wort über die von Dir verwendete Programmiersprache verloren hast, gehe ich jetzt einfach mal von C aus. Und da gibt es das mächtige printf, das mit dem Formatspezifizierer %x bzw. %X daherkommt. Bei gewünschter Ausgabe von führenden Nullen ist noch eine Null und die Feldbreite anzugeben, also z.B. %04x für vierstellige Zahlen.
Ja, stimmt, habe mich etwas undeutlich ausgedrückt:-) Ich benutze C++. Printf steht mir nicht zur Verfügung. Auch die stdlib.h kann ich nicht verwenden (also kein itoa), sodass ich eine andere Möglichkeit benötige....
>sodass ich eine andere Möglichkeit benötige....
Selber basteln?
Man nehme einen String, ein paar Schleifen und Abfragen, und schon ist
ITOA selber gebastelt.
Ungefähr so, allerdings ist das jetzt aus dem Kopf und vielleicht ist da ein Bug drin. Aber vom Prinzip her sollte es klappen:
1 | unsigned char nibble_zu_hex(unsigned char nib) { |
2 | if (nib < 0x0A) nib = nib + '0'; |
3 | else nib = (nib - 0x0A) + 'A' |
4 | return nib; |
5 | }
|
6 | |
7 | nibble_zu_hex(zahl >> 4); |
8 | //liefert Dir den vorderen Buchstaben
|
9 | |
10 | nibble_zu_hex(zahl & 0x0F); |
11 | //liefert Dir den hinteren Buchstaben
|
12 | |
13 | //Annahme: UART_send ist Deine Funktion, um ein char zu senden
|
14 | UART_send("0"); |
15 | UART_send("x"); |
16 | UART_send(nibble_zu_hex(zahl >> 4)); |
17 | UART_send((zahl & 0x0F)); |
18 | }
|
Ich hoffe, Du verstehst die Grundidee dahinter, dann kannst Du das auch auf Integer, long long Longs usw. anwenden :) Im Prinzip musst Du nur den Zahlenwert der Ziffer kennen (4 Bit entsprechen einer Hex-Ziffer), und dann das entsprechende ASCII-Zeichen stattdessen nutzen. Ich addiere einfach die entsprechenden Werte (einmal für 0-9, einmal für A-F).
Für AVR's: Wie wärs mit Assembler ? ; ************************************************************************ ; bin2ascii R16 Hexaziffer binär nach ASCII umwandeln bin2ascii: andi r16,$0f ; Maske 0000 1111 subi r16,-0x30 ; ADDI r16,+$0x30 codieren cpi r16,'9'+1 ; Ziffern 0..9 ? brlo bin2ascii1 ; ja: weiter subi r16,-7 ; nein: ADDI r16,+7 Buchstaben A .. F bin2ascii1: ret ; Rücksprung
wenn du mit cout arbeitest, dann hilft cout << hex; //schaltet auf hexadezimale Zahlendarstellung um ;-)
> Ich benutze C++. > Printf steht mir nicht zur Verfügung. Warum? > Auch die stdlib.h kann ich nicht verwenden (also kein itoa), Warum?
Vielen Dank Euch allen für die sehr hilfreichen Antworten. Habe mir jetzt auf eine nicht besonders schöne aber durchaus brauchbare "Abfragenbatterie" :-) eine itoa programmiert. VG
Captain Subtext schrieb:
>
1 | > unsigned char nibble_zu_hex(unsigned char nib) { |
2 | > if (nib < 0x0A) nib = nib + '0'; |
3 | > else nib = (nib - 0x0A) + 'A' |
4 | /* ^^^^^ sollte +'0' heißen, oder? */
|
5 | > return nib; |
6 | > } |
7 | >
|
wobei das auch mit weniger Code geht:
1 | return "01234567890ABCDEF"[nib]; |
und sich dafür wiederum gar kein echter Funktionsaufruf lohnt...
> wobei das auch mit weniger Code geht: > return "01234567890ABCDEF"[nib]; ^ Das gehört da aber nicht hin. Daraus würde ich zur Sicherheit das machen:
1 | return "0123456789ABCDEF"[nib & 0xf]; |
Letztendlich ist auch das da:
> else nib = (nib - 0x0A) + 'A'
eigentlich nicht so ganz portabel, da nicht garantiert ist, daß die
Zeichen 'A' bis 'F' hintereinander stehen. Da aber die meisten
C-Compiler ASCII als Basis für ihre Zeichensätze benutzen, geht's
normalerweise.
Rolf Magnus schrieb: >> wobei das auch mit weniger Code geht: >> return "01234567890ABCDEF"[nib]; > ^ > Das gehört da aber nicht hin. klar, mein Fehler. > > Daraus würde ich zur Sicherheit das machen: > >
1 | > return "0123456789ABCDEF"[nib & 0xf]; |
2 | >
|
So wie er es verwendet, maskiert er vorher so, daß nur 4 Bit vorhanden sein können. Insofern hätte ich hier keine Bedenken. Als allgemeingültige Funktion gebe ich dir Recht. Ob man in diesem Fall die hier unnötigen Tests machen will, muß jeder selbst sehen. > > Letztendlich ist auch das da: > >> else nib = (nib - 0x0A) + 'A' > > eigentlich nicht so ganz portabel, da nicht garantiert ist, daß die > Zeichen 'A' bis 'F' hintereinander stehen. Da aber die meisten > C-Compiler ASCII als Basis für ihre Zeichensätze benutzen, geht's > normalerweise. Wieso "auch"? Meine Version ist portabel.
> Wieso "auch"? Meine Version ist portabel.
Mit "auch" meinte ich hier, daß das "auch" ein Grund ist, deine Version
zu verwenden.
> Da aber die meisten C-Compiler ASCII als Basis für ihre > Zeichensätze benutzen, geht's normalerweise. Hat schon mal jemand von einem auch nur gehört, der das nicht tut?
Ich gehe mal davon aus, daß man auf IBM-Mainframes nicht ASCII findet, sondern EBCDIC. Da sind dann nicht alle Buchstaben A bis Z aufeinanderfolgend, aber immerhin A bis F und auch die Ziffern. Der obige Code würde also auch dort funktionieren.
Mal ernsthaft: Glaubst Du ernsthaft, daß es diese 60er-Jahre-Technik immer noch gibt? (Ansonsten hast Du natürlich recht, der Ansatz ist der "portabelste").
> Mal ernsthaft: Glaubst Du ernsthaft, daß es diese 60er-Jahre-Technik > immer noch gibt? ASCII ist auch "60er-Jahre-Technik".
@Rufus: meines Wissens sind bei Banken immer noch solche Kisten im Betrieb. Zumindest war das vor wenigen Jahren so und ich habe nichts gegenteiliges gehört.
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.