www.mikrocontroller.net

Forum: Compiler & IDEs Datenkonvertierung


Autor: Justus Jonas (jonas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,
wahrscheinlich ist mein Problem garnicht sehrgroß, aber ich sehe
einfach den Wald vor lauter Bäumen nicht mehr.

Ich bekomme von einem zuarbeitendem Programm einen String char
stream[100]; übergeben. In diesem String stehen nur hexadezimale Werte,
also in der Form wie "39AB38...." . Jetzt möchte ich diese aber
Byteweise weiterverarbeiten und zwar Bitweise, d.h. ich möchte die
ersten beiden Zeichen als 0x39 interpretieren und dann als Bits
"00111001" mit verschiedenen Routinen auswerten.

Krieg ich aber nicht hin, weil ich wohl nicht fit genug in C bin.
Wie krieg ich so eine konvertierung den wohl hin?

Justus

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ist nichts zu konvertieren.

Autor: Mario Schrenk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch's mal mit

x = ((stream[i] - '0') << 4) | (stream[i+1] - '0');
i += 2;
...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Umm, ja, sorry, ich ziehe meine Bemerkung zurück. ;-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
0 abziehen geht nicht bei Hex, aber sscanf geht:

sscanf( s, "%02x", &i);

Peter

Autor: Mario Schrenk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 0 abziehen geht nicht bei Hex

Oh ja, stimmt. Und wenn dann noch Groß- und Kleinbuchstaben
berücksichtigt werden müssen, dann wird der Aufwand durch die nötigen
Fallunterscheidungen doch recht groß...

War also nichts mit einer einfachen, schnellen Codezeile.

Autor: xXx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-> Setzen, Sechs!!!

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Ansatz (ohne Gewähr)
#include <ctype.h>

void xxx(char* stream) {
 uint8_t result = 0;
 char* cp       = stream;
 uint16_t len   = strlen(stream);

 while(isxdigit(*cp)) {
  result <<= 4;
  if(*cp <= '9')
    result |= (*cp - '0');
  else 
    result |= ((*cp & ~' ') - 'A' + 10);
  cp++;
  len--;
  if(len & 1) == 0)
      machWasDamit(result);
 }
}

Autor: Justus Jonas (jonas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für eure Antworten!

Ich hab es jetzt erstmal mit sscanf probiert, das funktioniert auf dem
Pc auch toll, aber wenn ich es auf dem Mikrocontroller einbinde, dann
funktioniert es garnicht mehr.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich hab es jetzt erstmal mit sscanf probiert, das funktioniert auf
> dem Pc auch toll, aber wenn ich es auf dem Mikrocontroller einbinde,
> dann funktioniert es garnicht mehr.

Sollte aber.  Was funktioniert denn genau nicht (und wie funktioniert
es nicht)?  Hast du Beispielcode?

Autor: Justus Jonas (jonas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich hab das ganze mal so gelöst.



for(int c=0;c<=1;c++)
{
sscanf((id+(2*c)),"%02x", &shift);
for(int b=0;b<=7;b++)
{
  if (shift & 0x80)
     {
        if (c==0)
        gesamt1 = (gesamt1+bitwert[7-b]);
        if (c==1)
        gesamt2 = (gesamt2+bitwert[7-b]);
   }
    else ;
shift<<= 1;
}
}
gesamt = ((gesamt2 * 256)+gesamt1);
sprintf(gesamtchar,"%i",gesamt);
for(int b=0;b<=4;b++)
{
uart0_putchar(gesamtchar[b]);
}

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

Bewertung
0 lesenswert
nicht lesenswert
Was soll'n das sein?

Hast Du Dir schon mal den Wert von shift ausgeben lassen?
Du kannst Dir den ganzen Mambo-Zambo mit der ersten
b-Schleife komplett sparen.

Dezimal-Hex-Binaer sind nur andere Schreibweisen fuer
immer dasselbe: eine Zahl.
Und sscanf liefert dir diese Zahl.

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

Bewertung
0 lesenswert
nicht lesenswert
Im Übrigen gibt es da etwas, was Du Dir abgewöhnen solltest:

> for(int b=0;b<=4;b++)

Benutze kein <= in for Schleifen, es sei denn es gibt
einen extrem guten Grund dafuer.

  for( int b = 0; b < 5; b++ )

ist eine Schleife die 5 mal ausgeführt wird. D.h. die
Anzahl der Wiederholungen steht unmittelbar im Statement
ohne dass man gross rechnen oder analysieren muss.

  #define ANZAHL 28

  int irgendwas[ ANZAHL ];
        /* definiert ein Array mit 28 Eintraegen */

um dieses Array abzuarbeiten, schreibt man dann

  for( int i = 0; i < ANZAHL; i++ )
    ....

usw.
Das ist die übliche Art und Weise. Ein Programmierer checkt
mit seinem 'optischen Pattern-Matcher' (sprich Auge-Gehirn)
4 Dinge:
  * ist die Variable in allen 3 Ausdruecken immer diesselbe
      jawohl ist es: ist immer 'i'
  * steht da ein '<'
      yep. steht da
  * beginnt die Zaehlung mit 0
      yep.
  * kommt im letzten Ausdruck ein ++ vor und sonst nichts?
      yep.

-> Schlussfolgerung: Das ist eine Zaehlschleife, die i hochzaehlt.
Die Schleife wird ANZAHL mal (oder was halt im 2. Ausdruck rechts
vom '<' steht) wiederholt wird. Mehr analysiert er nicht sondern
beschaeftigt sich sofort damit, was in der Schleife passiert.
Erst wenn eine der 4 Dinge so nicht da stehen, dann beginnt
er darüber nachzudenken, warum denn die Schleife nicht in
ihrer Standardform geschrieben ist, was uns der Autor sagen
will und ob das überhaupt stimmen kann was da steht.

-> Standardform benutzen um anzuzeigen dass da nichts spezielles
passiert sondern es sich um eine stinknormale Standard-Zählschleife
handelt.

Autor: Justus Jonas (jonas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Tips, klingt ganz praktisch. Werde mehr auf die
Standardformen beim Programmieren achten.

Ansonsten funktioniert der Code aber.
Er macht aus 4 Hex-Werten die entsprechende Dezimalzahl.
Die wird dann in einen String geschrieben und über uart ausgegeben.

Werd mir das heute nochmal anschauen und ohne Schleife probieren.

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

Bewertung
0 lesenswert
nicht lesenswert
> Ansonsten funktioniert der Code aber.

Klar funktioniert er. Was Du machst ist: Du zerlegst
die Zahl in Bits und setzt dann aus den Bits wieder die
Zahl zusammen. D.h. das Ergebnis ist identisch mit dem
Ursprung. Damit ist aber der ganze Rechenweg dazwischen
umsonst und verbraucht nur Resourcen.

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

Bewertung
0 lesenswert
nicht lesenswert
> Er macht aus 4 Hex-Werten die entsprechende Dezimalzahl

Das wuerde

  long gesamt;
  sscanf( id, "%04lx", &gesamt );

auch machen :-)

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.