mikrocontroller.net

Forum: Compiler & IDEs Zeichen (hex) binär ausgeben


Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Forum Gemeinde.

Als erstes wünsche ich allen ein frohes und vorallem gesundes neues 
Jahr.
Zweitens : ich komme gleich auf den Punkt.

Ich habe ein char (Zeichen zwischen 0...F)
Nun möchte ich das Zeichen in binärcode ausgeben.

Folgendes habe ich bisher geschafft:

char Buffer[4];
int i;
char Wert;

Wert=botschaft[7];  // botschaft[7] enthält die Zeichen von 0 bis F...

for (i = 0; i < 4; i++)
{
   Buffer[i] = (Wert & (1 << (3 - i)) ? '1' : '0');
}
Buffer[4] = '\0';
set_cursor(0,3);lcd_string(Buffer);

Es klappt nur bei Zeichen von 0 bis 9...
Wie kann ich den Code ergänzen um auch A bis F auszugeben.

Liebe Grüße

Autor: TokyoDrift (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for (i = 0; i < 4; i++)
{
   Buffer[i] = (Wert & (1 << (3 - i)) ? '1' : '0');
}
Sieht eigentlich gut aus.

Buffer[4] = '\0';
Schreibt auf jeden Fall in einen Speicher in den es nicht schreiben 
soll.


>Es klappt nur bei Zeichen von 0 bis 9...
>Wie kann ich den Code ergänzen um auch A bis F auszugeben.
Was passiert denn bei A bis F?

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Bei A-F wird zwar ein binärcode erzeugt, jedoch nicht der Richtige.

Gruß

Autor: Nico S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann schreib doch mal bitte ein Beispiel, welcher Binärcode bei A-F 
erzeugt wird.

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also.
Die Zeichen werden wie folgt erzeugt :

0   0000
1   0001
2   0010
3   0011
4   0100
5   0101
6   0110
7   0111
8   1000
9   1001

bis dahin alles ok...

A   0001
B   0010
C   0011
D   0100
E   0101
F   0110

ok. Er fängt wieder von vorne an.
Wenn ich das Ergebnis (von der 9) zum Ergebnis (z.B. von A) addiere 
bekomme ich das richtige Ergebnis??

BSP:
1001  ->9
+
0011  ->C
=
1100  ->12

Wie mache ich das?

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar.

Habe alles auf 8bit erweitert und es funktioniert nun richtig. ok

Danke für die Hilfe.

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal. Kann leider das Problem immernoch nicht lösen !
Kann mir jemand helfen ?

Nochmal zum Problem :

ich möchte ein Zeichen als Binärcode (4 Bit) darstellen :

Erstes  Bsp: 5 -> 0101
Zweites Bsp: B -> 1011

Leider bekomme ich mit meinem Code nur ein 7 Bit Binärcode heraus.

Ich möchte aber ein 4 Bit Binärcode. Wie mache ich das? Weiß das Jemand?

Liebe Grüße

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versehentlich signed statt unsigned genommen?

PS: Ohne deinen Quelltext kann man lange raten.
Verstecke ihn gut, damit ihn nie jemand sieht!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass es bei 0 - 9 funktioniert, ist auch eher Zufall.

Du musst erst mal das Zeichen ('0' - 'F') in eine Zahl (0 - 15) 
umwandeln, bevor du anfangen kannst, diese Zahl dann binär auszugeben. 
Und nein, mit einer einfachen Zuweisung ist diese Wandlung nicht zu 
erreichen.

Autor: DirkB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kommst du denn überhaupt an deine 0 bis F?

Autor: smoerre (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Erstes  Bsp: 5 -> 0101
> Zweites Bsp: B -> 1011

> Leider bekomme ich mit meinem Code nur ein 7 Bit Binärcode heraus.
> Ich möchte aber ein 4 Bit Binärcode.

Du meinst wahrscheinlich BCD-Zahlen im 8421-Code ?
A bis F sind dann sogenannte Pseudotetraden.
Soviel zu den Grundlagen.

> Ohne deinen Quelltext kann man lange raten.
> Verstecke ihn gut, damit ihn nie jemand sieht!
nicht ganz im Sinne des GNU Projekts ;-) insofern gibts auch nur vage 
Hinweise.

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo . Da bin ich wieder.

P.S. Das was ich vor habe funktioniert immernoch nicht :o(

Zur Erinnerung:
1. Ich bekomme einen String (botschaft) über UART [botschaft[10]]
2. Das 9-te Zeichen botschaft[8] z.B. A möchte ich zu 4-Bit Binärcode
convertieren.
3. Die Funktion hex_to_bin soll mir den Code (z.B. 1010) als String 
liefern...

WAS MACHE ICH FALSCH????

P.S.
Das habe ich bereits gelesen...
http://www.mikrocontroller.net/articles/FAQ#Wie_fu...


Hier mein Code...
char botschaft[10];   // 9 Zeichen Botschaft

int main(void)
{
         // UART , LCD etc.. initialisieren

  while(1)
  {
         // Botschaft über UART empfangen (z.B. 00000000A)
         uart_gets( botschaft, sizeof( botschaft ) );    

         // 9-tes Zeichen des Strings als 4-Bit Binär convertieren
         set_cursor(0,2);lcd_string(hex_to_bin(botschaft[8]));
    }
  }
}

char* hex_to_bin(char hex)
{
      char temp[5];

    int bin;
    switch (hex)
    {
      case '0' : bin=0000; break;
      case '1' : bin=0001; break;
      case '2' : bin=0010; break;
      case '3' : bin=0011; break;
      case '4' : bin=0100; break;
      case '5' : bin=0101; break;
      case '6' : bin=0110; break;
      case '7' : bin=0111; break;
      case '8' : bin=1000; break;
      case '9' : bin=1001; break;

      case 'A' : bin=1010; break;
      case 'B' : bin=1011; break;
      case 'C' : bin=1100; break;
      case 'D' : bin=1101; break;
      case 'E' : bin=1110; break;
      case 'F' : bin=1111; break;
      default :  break;
    }

      itoa(bin, temp, 10);
      temp[4]='\0';

  return temp;
}



ERROR:
../LCD_v1.c:51: error: conflicting types for 'hex_to_bin'

Vielen Dank

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. Dammerow schrieb:
> char* hex_to_bin(char hex)
> {
>   char temp[5];
>   return temp;
> }

das ist nicht zulässig, du darst NIEMALS ein zeiger auf eine lokale 
Variable zurückgeben

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. Dammerow schrieb:


und das

>     switch (hex)
>     {
>       case '0' : bin=0000; break;
>       case '1' : bin=0001; break;
>       case '2' : bin=0010; break;
>       case '3' : bin=0011; break;
>       case '4' : bin=0100; break;
>       case '5' : bin=0101; break;
>       case '6' : bin=0110; break;
>       case '7' : bin=0111; break;
>       case '8' : bin=1000; break;
>       case '9' : bin=1001; break;
>
>       case 'A' : bin=1010; break;
>       case 'B' : bin=1011; break;
>       case 'C' : bin=1100; break;
>       case 'D' : bin=1101; break;
>       case 'E' : bin=1110; break;
>       case 'F' : bin=1111; break;
>       default :  break;

ist zwar nett gedacht, aber ziemlicher Unsinn.

Kleiner Tipp:
0010
ist nicht das Bitmuster, bei dem das 2.te Bit eine 1 ist.

Das ist eine Oktalzahl. Genau genommen ist das dezimal 8
Aus demselben Grund ist auch 0011 nicht das Bitmuster, bei dem die 
untersten 2 Bit gesetzt sind, sondern wieder eine Oktalzahl, die dezimal 
gesehen den Wert 9 (oder binär 0b1001) aufweist.

Nur 1000 (bzw. alle nachfolgenden) die sind tatsächlich das was dort 
steht. Nämlich Ein-Tausend, Ein-Tausend-Eins, Ein-Tausend-Zehn, 
Ein-Tausend-Elf etc. etc.


Was ist falsch an der Kombination, wie schon weiter oben vorgeschlagen:

Den ASCII Code des Buchstabens hernehmen und daraus die richtige Zahl 
machen ....
uint8_t toBin( char c )
{
  if( c >= '0' && c <= '9' )
    return c - '9';

  return c - 'A' + 10;
}

... und danch itoa zu benutzen um sich dann aus einer Zahl eine 
textuelle Binärrepräsentierung besorgen zu lassen?
  while(1)
  {
         // Botschaft über UART empfangen (z.B. 00000000A)
         uart_gets( botschaft, sizeof( botschaft ) );    

         uint8_t value = toBin( botschaft[8]);

         set_cursor(0,2);
         lcd_string( itoa( value, buffer, 2 ) );
    }

(jetzt mal von fehlenden führenden 0-en abgesehen, was man noch lösen 
müsste)

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die ausführliche Antwort Karl Heinz.

Habe Deine (durchaus elegantere) Lösung eingearbeitet.
Um es zu verstehen, werde ich sicherlich etwas länger brauchen.
Es sieht schon super aus. Was ich leider noch nicht
hinbekomme ist folgendes :
uint8_t toBin( char c )
{
  if( c >= '0' && c <= '9' )
    return c - '9';
  return c - 'A' + 10;
}

Bei den Zeichen von 0 bis 9 bekomme ich immer nur 1111 heraus.
Bei A-F klappts super.

Danke

Autor: DirkB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es muss c - '0'; (nicht c - '9') heißen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. Dammerow schrieb:

> Bei den Zeichen von 0 bis 9 bekomme ich immer nur 1111 heraus.
> Bei A-F klappts super.


Muss ich mich entschuldigen.
Es bewahrheitet sich eben immer wieder: Egal wie banal ein Codestück 
erscheint. Egal wie oft man diese Funktion in der Vergangenheit schon 
geschrieben hat. Teste ihn vor dem Posten, den es gibt keinen Fehler der 
nicht banal genug wäre ihn noch einmal zu machen :-)

Autor: P. Dammerow (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl Heinz, hallo DirkB.
BITTE NICHT LACHEN !

Ich bekomme es leider nicht hin die führende Nullen in die Integer Zahl 
hinzuzufügen. Obwohl Deine (Karl Heinz) Lösung mir persönlich sehr gut 
gefallen hat.

Habe mir daher eine unsinnige Funktion geschrieben, die jedoch zu 
funktionieren scheint.
Ob diese resourcen-schonend ist, das wage sogar ich - als Anfänger - zu 
bezweifeln...
char bin[4];    // Variable für 4 Bit Binär als String

// Konvertiert HEX (Zeichen 0-F) in 4-Bit Binärcode
char* hex_to_bin(char hex)
{
      switch (hex)
    {
      case '0' : strcpy( bin, "0000"); break;
      case '1' : strcpy( bin, "0001"); break;
      case '2' : strcpy( bin, "0010"); break;
      case '3' : strcpy( bin, "0011"); break;
      case '4' : strcpy( bin, "0100"); break;
      case '5' : strcpy( bin, "0101"); break;
      case '6' : strcpy( bin, "0110"); break;
      case '7' : strcpy( bin, "0111"); break;
      case '8' : strcpy( bin, "1000"); break;
      case '9' : strcpy( bin, "1001"); break;
      case 'A' : strcpy( bin, "1010"); break;
      case 'B' : strcpy( bin, "1011"); break;
      case 'C' : strcpy( bin, "1100"); break;
      case 'D' : strcpy( bin, "1101"); break;
      case 'E' : strcpy( bin, "1110"); break;
      case 'F' : strcpy( bin, "1111"); break;
      default :  break;
    }
  return bin;
}

Aufruf...

// botschaft[8] beinhaltet Zeichen 0...F
lcd_string(hex_to_bin(botschaft[8]));


Liebe Grüße

Autor: René H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
char bin[4]; 

muss sicher mal:
char bin[5]; 

sein, da ein string mit \0 abgeschlossen wird bei strcpy.

Autor: DirkB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
char* hex_to_bin(char *bin, char hex)
 find ich da sinnvoller.

Das itoa hast du aber auch benutzt?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.