mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C String in 2 Strings


Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe genau dasselbe Problem wie du, ich bekomme Daten über den UART
die folgt aussehen:
0x70;0x11

möchte diese in 2 Strings teilen und zuweisen, also dann:
code1=0x70;
code2=0x11;

und diese dann grad weiterverwenden, z.B.

i2c_start(code1)  //i2c_start(0x70);
usw.

Ein Beispiel mit meinen Werten wäre natürlich sehr hilfreich:-)
auch zum nachvollziehen.

danke im vorraus

Matze

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steht das ; immer an der selben Stelleß

Wenn ja dann..

string1[0]=input[0];
string1[1]=input[1];
[...]

string2[0]=input[4];
string2[1]=input[5];
[...]

dann noch atoi und schon hast du deine werte

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo werden denn Hex-Werte als "Klartext" über die UART übertragen? Hast 
Du die PC-seitige Software selber geschrieben?

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
strtok() suchst du.

Separiert Zeichengetrennte-Listen (z.B. wie in CSV) in einzelne Token 
also Elemente der Liste.

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im moment übertrage ich meinen "Code" über ein Hyperterminal

dort gebe ich ein: "0x70;0x11"

Das Programm zum senden des Codes wird noch erstellt!! Wollte aber 
zuerts dass C-Prog laufen lassen, dass ich weiß es funzt.

zu ... ... :(name?)

das heisst ich muss es Byteweise zuweisen

code[0]=adress[0];  //hier steht "0"  ??
code[1]=adress[1];  //hier steht "x"  ??
[...]

das verstehe ich, aber wie mache ich jetz aus adress[0] & adress[1]
eine var: char Adresse;  //wo drin steht "0x70" ??

Danke für eure Bemühungen, ich steh noch am Anfang mit dem Bearbeiten 
von Strings.....möcht es aber lernen:-)

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

Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:

> das heisst ich muss es Byteweise zuweisen

Kannst du machen.
Wenn sichergestellt ist, dass die dich interessierenden Daten immer an 
der gleichen Stelle stehen.
Da letztendlich ja das Senden von einem Programm übernommen wird, kann 
man wohl davon ausgehen, dass dem immer so ist.

Ein String wird in C ja ganz einfach in einem Array gespeichert. Also 
kannst du ganz normal über Arrayindizierung auf die Daten zugreifen.

> code[0]=adress[0];  //hier steht "0"  ??
> code[1]=adress[1];  //hier steht "x"  ??
> [...]
>
> das verstehe ich, aber wie mache ich jetz aus adress[0] & adress[1]
> eine var: char Adresse;  //wo drin steht "0x70" ??

Indem du dir aus dem 'String' den zugehörigen numerischen Wert 
berechnest.
atoi eignet sich in deinem Fall nicht, da du dein String Hex Zahlen 
repräsentiert. atoi geht nur für Dezimalzahlen.

Aber es ist nicht weiter schwer, sich eine Umwandlungsfunktion zu bauen, 
die einen 2 stelligen Hex-Wert-String in einen tatsächlichen Hex-Wert 
umwandelt.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das verstehe ich, aber wie mache ich jetz aus adress[0] & adress[1]
eine var: char Adresse;  //wo drin steht "0x70" ??

Was soll denn eine char Adresse sein? Es gibt ein char dort steht 
einzeichen drin. Das zeichen kann als Hex ( 0x70 ) oder als char 
dargestellt werden ('A') aber es ist immer ein char. eine Adresse ist 
wenn du char* verwendest - das willst du aber hier vermutlich nicht.

Wenn ich es richtig verstanden habe willst du aus einem String 0x71;0x11 
2 Chars mit einer Hex to int umwandlung machen.

char c1 = (string[2]-'0') << 8 + (string[3]-'0');
char c2 = (string[7]-'0') << 8 + (string[8]-'0');

(ist jetzt aber nicht getestet, soll nur das Prinzip zeigen!)

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

Bewertung
0 lesenswert
nicht lesenswert
Aber es ist nicht weiter schwer, sich eine Umwandlungsfunktion zu bauen,
die einen 2 stelligen Hex-Wert-String in einen tatsächlichen Hex-Wert
umwandelt.

Alles fängt damit an, dass man sich eine Funktion baut, die ein
einzelnes Hex-Digit in seinen binären Counter-Part umwandelt.
unsigned char HexDigit( char digit )
{
  if( digit >= '0' && digit <= '9' )
    return digit - '0';

  if( digit >= 'A' && digit <= 'F' )
    return digit + 10 - 'A';

  if( digit >= 'a' && digit <= 'f' )
    return digit + 10 - 'a';

  return '0';   // Fehler
}


Mit dieser Funktion bewaffnet, wandelt man dann 2 stellige 'Zahlen'
unsigned char HexNumber( char digit1, char digit2 )
{
  return HexDigit( digit1 ) * 16 + HexDigit( digit2 );
}

und benutzt die dann zb
  unsigned char addrNum =  HexNumber( adress[2], adess[3] );

Ab jetzt steht dem Aufwand Tür und Tor offen:
Das ganze umwandeln in eine Funktion, die einen String annimmt.
Dann soll die Funktion im String den Präfix "0x" erkennen und 
entscheiden, ob es sich um eine Hex-Zahl oder eine Dezimal-Zahl handelt 
und die jeweils richtige Umwandlung dafür hernehmen, etc. etc.

Wenn du aber nur Funktionalität brauchst, die eine 2-stellige Hex-Zahl 
von der Stringform in eine tatsächliche Zahl wandelt UND die Ziffern 
konstant im String immer an der gleichen Stelle stehen, dann bist du mit 
obigem schon gut dabei.

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok viell sollte ich mal einen kurzen Quellcode von mir reinsetzen:-)

bin grad etwas durcheinander:-)
aber schon mak tausend Dank dass die Hilfe hier so schnell geht und es 
Leute gibt die einem versuchen zu Helfen:-)

Quellcode::

   i2c_start(0x70);       // setze
   i2c_write(0xFF);        // schreibe
   i2c_stop();

   i2c_start(0x71);        // setze
   ret = i2c_readNak();
   i2c_stop();             // stoppe

hier möchte ich die Hexadressen die schreibe, Variabel machen, so dass 
jede adresse und Daten schreiben kann die ich vom PC zum µC sende.
d.h.
Ich möchte bei i2c_start das 0x70 variabel und i2c_write variabel 
machen.

wenn ich also sende(der code sieht immer gleich aus!!)
0xFA;0x4F

soll 0xFA in i2c_start geschrieben werden und
     0x4F in i2c_write geschrieben werden.

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

Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:

> wenn ich also sende(der code sieht immer gleich aus!!)
> 0xFA;0x4F
> soll 0xFA in i2c_start geschrieben werden und
>      0x4F in i2c_write geschrieben werden.

Du empfängst diesen String in einer String Variable

char Command[20];   <- da baut die die Empfangsroutine den String rein
                       wobei sichergestellt ist, dass der String immer
                       dem Muster 0xaa;0xbb genügt

                       Das ist eine wichtige Einschränkung!
                       Auch sollte der String auf Gültigkeit geprüft
                       werden!

                       Da der String aber immer gleich aussieht, weißt
                       du auch, wo die Hex-Ziffern im String sind:


   i2c_start( HexNumber( Command[2], Command[3] ) );       // setze
   i2c_write( HexNumber( Command[7], Command[8] ) );       // schreibe
   i2c_stop();


Wie gesagt: Wenn das von einem menschlichen Benutzer eingegeben werden 
muss, würde ich nicht so naiv annehmen, dass der String den Aufbauregeln 
entspricht. Da dein String aber von einem Programm erzeugt wird, kann 
man im Sender sicherstellen, dass dem so ist.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

>
>   return '0';   // Fehler
> 

moep ;-)

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

Bewertung
0 lesenswert
nicht lesenswert
Peter Stegemann schrieb:
> Karl heinz Buchegger schrieb:
>
>>
>>   return '0';   // Fehler
>> 
>
> moep ;-)

Danke für den Bugreport :-)

    return 0;

Wobei es im Fehlerfall sowieso fraglich ist, wie dann reagiert werden 
soll.

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, so hatte ich mir es vorgestellt:-)

danke schön.

aber muss ich "HexNumber" nicht irgendwie deklarieren oder is das ne 
Funktion?? Brauch ich dann ev. ne Headerdatei dafür??

warum return 0; ??? und wo? am Ende meines Progs??

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

Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:
> ok, so hatte ich mir es vorgestellt:-)
>
> danke schön.
>
> aber muss ich "HexNumber" nicht irgendwie deklarieren oder is das ne
> Funktion?? Brauch ich dann ev. ne Headerdatei dafür??

Ähm. Das ist jetzt aber nicht dein Ernst.
Wenn dir diese Fragestellung Kopfzerbrechen macht, dann bist du noch 
nicht soweit um Produktionscode zu schreiben.

Oder hast du diese hier
Beitrag "Re: C String in 2 Strings"
nicht gesehen?

>
> warum return 0; ??? und wo? am Ende meines Progs??

Nein.
Am Ende der Funktion. Vergleich doch mal, was ich in der 'Urversion' im 
Fehlerfall für einen return in der Funktion HexDigit hatte.

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke!

Ne sorry die Frage war etwas voreilig, hab dann deine Antwort gesehen 
mit der Funktion. Und sorry, klar is es ne Funktion!!! War etwas 
zerstreut geradeeben.

Dann geb ich es mal kurz wieder ob ich die Funktion richtig verstanden 
hab.


unsigned char HexDigit( char digit )
{
  if( digit >= '0' && digit <= '9' )  wenn digit >=0 und <=9 dann gib 
mir
    return digit - '0';               digit -0 zurück!

  if( digit >= 'A' && digit <= 'F' )  wenn digit>=A und <=F ist gib mir
    return digit + 10 - 'A';          digit +10 - A zurück

  if( digit >= 'a' && digit <= 'f' )  dasselbe mit Kleinbuchstaben!
    return digit + 10 - 'a';

  return '0';   // Fehler
}

Nun noch:::

unsigned char HexNumber( char digit1, char digit2 ) /funktion mit 
parameter
{
  return HexDigit( digit1 ) * 16 + HexDigit( digit2 );
}
 eine frage noch!! Was wird hier gemacht? und warum?

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

Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:

>  eine frage noch!! Was wird hier gemacht? und warum?

HexDigit wandelt einen Character aus dem üblichen 'Hex-Vorrat' in sein 
numerisches Äquivalent. Ich empfehle das Studium einer ASCII Tabelle, in 
der für jedes Zeichen sein Code angegeben ist.
Und dann muss man nur noch wissen, dass man in C mit char genausogut 
rechnen kann. Wenn du '0' im C-Source Code hinschreibst, dann setzt der 
Compiler gleich mal den ASCII Code dafür ein.

Wenn ein char '5' enthält, dann steht da nicht wirklich '5' drinnen, 
sondern der entsprechende ASCII Code: 0x35
Und wenn man von 0x35 dann noch 0x30 (= der ASCII Code für '0') abzieht, 
bliebt 5 übrig.
Und so ergibt dann '5' - '0' das Ergebnis 5


HexNumber fügt die numerischen Äquivelente der einzelnen Digits zu einer 
Zahl zusammen.

Bleiben wir einfach mal im Dezimalsystem:
Wenn du 2 Zehner und 5 Einer hast, dann entspricht das der Zahl:
    2 * 10 + 5 = 25

Im Hex-System (oder in jedem andren Zahlensystem) ist das nicht anders. 
Nur ist hier die Basis des Zahlensystems nicht 10 sondern 16 (daher auch 
Hexadezimalsystem: System zur Basis 16)

Autor: vlad (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mal ne ganz blöde frage:
warum den Code als HexText und nicht einfach als Binärdaten übertragen? 
da spart man sich den quatsch und schneller geht die Übertragung auch.

Wenn unbedingt hexText sein muss, dann lass doch wenigstens das '0x' und 
das ';' weg, dann parst sich das ganze einfacher:
ein char -> ein nibble

berechnung des Nibblewerts:
value = inputchar - '0'; // asciiwerte 0-9 in binär werte
if(value>9)
  value = inputchar - 'A' + 10;  // restliche werte

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ok,

super Erklärung!!! Jetzt hab ich verstanden!!
Es ist also eine Umrechnung sozusagen, dass man das erhält was man 
eingibt und nicht dass was der µC draus macht!! Also z.B. von 5 zu 0x35 
zu 5!!

habs grad mal ausprobiert und funktioniert super!!

danke an alle die geholfen haben und especially thanks to Karl heinz 
Buchegger!!!  Hast mir echt weitergeholfen!!
Jetzt muss ich es nur noch verinnerlichen, damit ich es nicht immer 
nachlesen muss;-)

MfG
Matze

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Womit die Frage, warum du die Daten nicht einfach binär überträgst, 
immer noch nicht geklärt ist.

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

Bewertung
0 lesenswert
nicht lesenswert
sven schrieb:
> Womit die Frage, warum du die Daten nicht einfach binär überträgst,
> immer noch nicht geklärt ist.

Aus einem seiner ersten Postings

> Im moment übertrage ich meinen "Code" über ein Hyperterminal
>
> dort gebe ich ein: "0x70;0x11"
>
> Das Programm zum senden des Codes wird noch erstellt!! Wollte aber
> zuerts dass C-Prog laufen lassen, dass ich weiß es funzt.

-> zum Testen ist ASCII gut genug.


@Matze
Vorsicht: Natürlich haben die Leute recht. Im Endausbau könnte man die 
Übertragung direkt binär durchführen, wenn ASCII ein Zeitproblem 
darstellt. Aber dann gut überlegen, wie du die Synchronisierung auf 
Adressbyte und Datenbyte hinkriegst.

Autor: Matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich finde die lösung mit dem ASCII ganz gut, Zeit ist kein Problem.
Kann es mal kurz erläutern:
Ich schicke einen Code 0x70;0x11
dieser wird per i2c gesendet
dadurch wird ein i2c Baustein angesprochen der mit den entsprechenden 
Ausgang(0x11) schaltet, dadurch wird ein relais geschaltet!
Das Relais schaltet wiederum einen Motor,LED,oder sonstiges.

Dann wird ein Test mit Multimeter oder visuell geschaut ob der Motor,LED 
geht und die Verbindung in Ordnung ist!
dann wird der "Test" beendet, kurz gewartet und die nächste 
LED,Motor,... geschaltet bis ich alle Komponenten die ich dran haben 
möchte getestet sind!

Ob ich nun 2s länger warten muss oder nicht, ist für diesen Zweck 
erstmal egal!! da ich die wartezeit in meinem "sendeprogramm" am PC 
einstelle.
Prinzip:

sende
warte
teste
warte
sende
warte
.
.
.



Klar ich könnte es auch binär machen, aber ich wollte mal etwas Neues 
probieren:-) Das hat ja auch ganz gut geklappt und was gelernt hab ich 
dabei auch.
Ich werde den Code, sobald er endgültige Form hat mal posten, sodass 
auch andere an dem Beispiel teilhaben können....

Mfg

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Wobei es im Fehlerfall sowieso fraglich ist, wie dann reagiert werden
> soll.

Das ist die zentrale Frage beim Programmieren ueberhaupt ;-)

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.