Forum: Mikrocontroller und Digitale Elektronik Integer zu 20Bit Char


von Draco (Gast)


Lesenswert?

Ich würde gerne eine uint16 mit den einzelnen Zeichen in ein fünfer 
Chararray rumschreiben. Verzweifel aber gerade daran...

Beispiel: Vorgegeben habe ich z.b.:
1
uint16 = 12345
2
3
//und möchte daraus:
4
5
char = {1,2,3,4,5}

Mit Bitshifften komme ich da ja nicht wirklich weiter, außer halt Bit 
1-4 (letzte Stelle)

Kann mir jemand einen Ansatzpunkt geben wo ich da anfangen kann?!

von M. K. (sylaina)


Lesenswert?

Draco schrieb:
> Ich würde gerne eine uint16 mit den einzelnen Zeichen in ein fünfer
> Chararray rumschreiben. Verzweifel aber gerade daran...
>
> Beispiel: Vorgegeben habe ich z.b.:
>
>
1
> uint16 = 12345
2
> 
3
> //und möchte daraus:
4
> 
5
> char = {1,2,3,4,5}
6
> 
7
>
>
> Mit Bitshifften komme ich da ja nicht wirklich weiter, außer halt Bit
> 1-4 (letzte Stelle)
>
> Kann mir jemand einen Ansatzpunkt geben wo ich da anfangen kann?!

Spontan:

Mit itoa() in einen String umwandeln und dann die Zeichen einzeln 
aufsplitten.

PS: Bist du sicher dass du
1
char[] = {1,2,3,4,5}

machen möchtest und nicht
1
char[] = {'1','2','3','4','5'}
?

: Bearbeitet durch User
von Draco (Gast)


Lesenswert?

Achja, die hälfte vergessen :D

Wegen der 20 Bit, die einzelnen Char will ich mir dann jeweils in eine 
Hexmaske schieben, das klappt ja auch:

z.b.:
1
Chararray = {1,2,3,4,5}
2
3
//zu:
4
5
...
6
Char1 = {0bXXXX0001}
7
Char2 = {0b00100011}
8
Char3 = {0b01000101}

Aber wie gesagt - das funktioniert, das schiebe ich mir aus den 
einzelnen Char in dem Array zusammen.

von Johnny B. (johnnyb)


Lesenswert?

Wenn Deine Plattform genügend freien Speicher hat, gehts auch mit einem 
SPRINTF. Damit kannst Du dann die Zahl noch schön formatieren.
http://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm

von Draco (Gast)


Lesenswert?

Michael K. schrieb:
> Spontan:
>
> Mit itoa() in einen String umwandeln und dann die Zeichen einzeln
> aufsplitten.
>
> PS: Bist du sicher dass du
> char[] = {1,2,3,4,5}
> machen möchtest und nichtchar[] = {'1','2','3','4','5'}?


Ja ich brauche die Hex von den Integer für die einzelnen Zahlen, die Hex 
für '5' z.b. ist ja 0x53 = 0b00110101.

von M. K. (sylaina)


Lesenswert?

Draco schrieb:
> Ja ich brauche die Hex von den Integer für die einzelnen Zahlen, die Hex
> für '5' z.b. ist ja 0x53 = 0b00110101.

Na dann versuch mal
1
char myChar = '5';
2
uint8_t ascii_code = (uint8_t)myChar;
und freu dich. Das kann der Compiler schon alleine, da musst du nicht 
selber schubsen ;)

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Draco,

Du willst ja keine Ziffer/Zahl als Zeichen kodiert sondern nur die 5 
Ziffern speichern.

Dann ist der Modulo Operator dein Freund.
1
a= 12345;
2
d = a % 10 // d = 5
3
a = a / 10;
4
// nächste Stelle
5
d = a % 10 // d = 4
6
a = a / 10;
7
// usw.

von Draco (Gast)


Lesenswert?

Michael K. schrieb:
> Na dann versuch malchar myChar = '5';
> uint8_t ascii_code = (uint8_t)myChar;
> und freu dich. Das kann der Compiler schon alleine, da musst du nicht
> selber schubsen ;)

Danke für den Versuch :D

Aber nein, also mein Compiler wandelt da nichts um von Char in uint8 :) 
Da bekomme ich dennoch den Hex Code für die Char '5' (also 35 bzw 53 bei 
littleendian)

von Draco (Gast)


Lesenswert?

Karl M. schrieb:
> Draco,
>
> Du willst ja keine Ziffer/Zahl als Zeichen kodiert sondern nur die 5
> Ziffern speichern.
>
> Dann ist der Modulo Operator dein Freund.a= 12345;
> d = a % 10 // d = 5
> a = a / 10;
> // nächste Stelle
> d = a % 10 // d = 4
> a = a / 10;
> // usw.

Ohhh super! Danke, genau das hab ich gesucht :)

von M. K. (sylaina)


Lesenswert?

Draco schrieb:
> Da bekomme ich dennoch den Hex Code für die Char '5' (also 35 bzw 53 bei
> littleendian)

Oben habe ich dich so verstanden, dass du doch genau das willst, also 
den ASCII-Wert der Ziffer.

Draco schrieb:
> Ohhh super! Danke, genau das hab ich gesucht :)

Dann solltest du aber auch ein Integer-Array benutzen und kein 
Char-Array. Habe dich nämlich deshalb anscheinend falsch verstanden ;)

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Draco schrieb:
> also mein Compiler wandelt da nichts um von Char in uint8
Ist ja zum Glück eh' das Selbe...

> Char '5' (also 35 bzw 53 bei littleendian)
Little und Big-Endian geht aber nicht bis auf die Nibble-Ebene runter, 
sondern es mach beim Byte Schluss.
Und 35 bzw 53 sind erst mal ALLE BEIDE dezimale Zahlen.
Wenn du 35hex (='5') oder 53dez meinst, dann musst du das unbedingt 
deutlich kenntlich machen.
Denn was ist z.B. 11?
Ist das binär 11 (=3) oder dezimal 11 oder hex 11 (=17)?

Draco schrieb:
> Ohhh super! Danke, genau das hab ich gesucht :)
Da bin ich mir noch nicht ganz so sicher...
Wofür brauchst du denn diese dezimale Darstellung der einzelnen 
Zehnerpotenzen? Für irgend eine Anzeige? Dann wäre die Darstellung im 
ASCII-Code üblicher.

: Bearbeitet durch Moderator
von Draco (Gast)


Angehängte Dateien:

Lesenswert?

Lothar M. schrieb:
> Draco schrieb:
>> also mein Compiler wandelt da nichts um von Char in uint8
> Ist ja zum Glück eh' das Selbe...
>
>> Char '5' (also 35 bzw 53 bei littleendian)
> Little und Big-Endian geht aber nicht bis auf die Nibble-Ebene runter,
> sondern es mach beim Byte Schluss.
> Und 35 bzw 53 sind erst mal ALLE BEIDE dezimale Zahlen.
> Wenn du 35hex (='5') oder 53dez meinst, dann musst du das unbedingt
> deutlich kenntlich machen.
> Denn was ist z.B. 11?
> Ist das binär 11 (=3) oder dezimal 11 oder hex 11 (=17)?
>
> Draco schrieb:
>> Ohhh super! Danke, genau das hab ich gesucht :)
> Da bin ich mir noch nicht ganz so sicher...
> Wofür brauchst du denn diese dezimale Darstellung der einzelnen
> Zehnerpotenzen? Für irgend eine Anzeige? Dann wäre die Darstellung im
> ASCII-Code üblicher.

Ja... also um mal weit auszuholen. Der ASCII Code für '5' ist der 
Integerwert 53 also als Hexwert die 0x35 und Binär 0b00110101 - so 
meinte ich das :)

Ja genau, es ging um das Darstellen auf einer 5er 7-Segment Anzeige mit 
einem MC14489 als Treiber. Der will halt die einzelnen Stellen als 4-Bit 
Hex haben.

Hab mir dann das so gerade fix zusammengeschrieben und funktioniert nun 
super:
1
  
2
Vvalue = 12345;
3
4
5
        uint16_t Temp = 9;
6
  unsigned char ByteThree = 0b00000000;
7
  unsigned char ByteTwo   = 0b00000000;
8
  unsigned char ByteOne   = 0b00000000; 
9
  
10
  for(uint8_t i=0; i<=4;i++)
11
  {
12
    if(Vvalue > 10)
13
    { 
14
      Temp = Vvalue % 10;
15
        Vvalue = Vvalue / 10;
16
      switch (i)
17
      {
18
      case 0: ByteThree = Temp;
19
        break;
20
      case 1: ByteThree |= Temp << 4;
21
        break;
22
      case 2: ByteTwo = Temp;
23
        break;
24
      case 3: ByteTwo |= Temp << 4;
25
        break;
26
      case 4: ByteOne = Temp;
27
      }
28
    } else if (Vvalue < 10)
29
    {
30
      switch (i)
31
      {
32
      case 0: ByteThree = Vvalue;
33
        break;
34
      case 1: ByteThree |= Vvalue << 4;
35
        break;
36
      case 2: ByteTwo = Vvalue;
37
        break;
38
      case 3: ByteTwo |= Vvalue << 4;
39
        break;
40
      case 4: ByteOne = Vvalue;
41
    }
42
    Vvalue = 0;  
43
    }
44
  }

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Draco schrieb:
> Der will halt die einzelnen Stellen als 4-Bit Hex haben.
Dann kannst du es auch "einfach" mit itoa() machen und vor der Ausgabe 
bei den einzelnen Zeichen jeweils eine '0' abziehen...

> Hab mir dann das so gerade fix zusammengeschrieben und funktioniert nun
> super: ...
Was du da gemacht hast, ist eine "Integer-nach-Packed-BCD" Uwandlung.
Beim "Packed-BCD" sind jeweils in 1 Byte zwei BCD-Zahlen 
hineingepackt...

von Draco (Gast)


Lesenswert?

Ja itoa wäre auch ne Möglichkeit gewesen, aber ich arbeite mit nem 
Tiny2313, da stören mich schon die Case Anweisungen ganz dolle arg :) - 
2kbyte sind schnell voll und itoa schluckt halt auch wahnsinnig viel.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Draco schrieb:
> da stören mich schon die Case Anweisungen ganz dolle arg :)
Warum machst du die dann gleich doppelt?

Probiers mal in die Richtung:
1
  ByteThree = ByteTwo = ByteOne = i = 0;
2
  while (Vvalue)
3
  {
4
      Temp = Vvalue%10;
5
      switch (i)
6
      {
7
      case 0: ByteThree = Temp;          break;
8
      case 1: ByteThree |= Temp << 4;    break;
9
      case 2: ByteTwo   = Temp;          break;
10
      case 3: ByteTwo   |= Temp << 4;    break;
11
      case 4: ByteOne   = Temp;
12
      }
13
      Vvalue /= 10;
14
      i++;
15
  }

Siehe dort: http://codepad.org/EgQaXPuy

Und probier das doch auch mal:
1
  ByteThree = (Vvalue%10);
2
  Vvalue /= 10;
3
  ByteThree |= (Vvalue%10) << 4;
4
  Vvalue /= 10;
5
  ByteTwo   = (Vvalue%10);      
6
  Vvalue /= 10;
7
  ByteTwo  |= (Vvalue%10)<< 4;
8
  Vvalue /= 10;
9
  ByteOne   = Vvalue; // das %10 ist hier nicht mehr nötig...
Das sieht zwar nach vielen Modulo und Divisionen aus, aber dafür ist die 
Schleife weg...

: Bearbeitet durch Moderator
von Draco (Gast)


Lesenswert?

Ja super, danke - funktioniert auch :D

Ich dachte Modulo wirft ein Fehler raus wenn er es nicht mehr durch zehn 
teilen kann - aber er teilt ja im Grunde nicht, er zieht ja bloß die 
Stelle rüber. Wieder was gelernt ^^

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Draco schrieb:
> Ich dachte Modulo wirft ein Fehler raus wenn er es nicht mehr durch zehn
> teilen kann
Man kann 0 beliebig oft durch irgendwas teilen. Es kommt immer 0 dabei 
raus. Und bei einer Division von 0 durch irgendwas ist der Rest immer 
0...

: Bearbeitet durch Moderator
von M. K. (sylaina)


Lesenswert?

Draco schrieb:
> Ich dachte Modulo wirft ein Fehler raus wenn er es nicht mehr durch zehn
> teilen kann - aber er teilt ja im Grunde nicht, er zieht ja bloß die
> Stelle rüber. Wieder was gelernt ^^

Öhm, nein. Modulo gibt einem den ganzzahligen Rest zurück der übrig 
bleibt von einer Ganzzahl-Division. Es hindert niemand einen daran auch 
5%2 zu schreiben, da wird keine Stelle rüber gezogen.

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.