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
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
Wo werden denn Hex-Werte als "Klartext" über die UART übertragen? Hast Du die PC-seitige Software selber geschrieben?
strtok() suchst du. Separiert Zeichengetrennte-Listen (z.B. wie in CSV) in einzelne Token also Elemente der Liste.
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:-)
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.
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!)
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.
1 | unsigned char HexDigit( char digit ) |
2 | {
|
3 | if( digit >= '0' && digit <= '9' ) |
4 | return digit - '0'; |
5 | |
6 | if( digit >= 'A' && digit <= 'F' ) |
7 | return digit + 10 - 'A'; |
8 | |
9 | if( digit >= 'a' && digit <= 'f' ) |
10 | return digit + 10 - 'a'; |
11 | |
12 | return '0'; // Fehler |
13 | }
|
Mit dieser Funktion bewaffnet, wandelt man dann 2 stellige 'Zahlen'
1 | unsigned char HexNumber( char digit1, char digit2 ) |
2 | {
|
3 | return HexDigit( digit1 ) * 16 + HexDigit( digit2 ); |
4 | }
|
und benutzt die dann zb
1 | 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.
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.
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.
Peter Stegemann schrieb: > Karl heinz Buchegger schrieb: > >>
1 | >> return '0'; // Fehler |
2 | >>
|
> > moep ;-) Danke für den Bugreport :-) return 0; Wobei es im Fehlerfall sowieso fraglich ist, wie dann reagiert werden soll.
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??
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.
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?
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)
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
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
Womit die Frage, warum du die Daten nicht einfach binär überträgst, immer noch nicht geklärt ist.
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.
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
Karl heinz Buchegger schrieb: > Wobei es im Fehlerfall sowieso fraglich ist, wie dann reagiert werden > soll. Das ist die zentrale Frage beim Programmieren ueberhaupt ;-)
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.