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
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
unsignedcharHexDigit(chardigit)
2
{
3
if(digit>='0'&&digit<='9')
4
returndigit-'0';
5
6
if(digit>='A'&&digit<='F')
7
returndigit+10-'A';
8
9
if(digit>='a'&&digit<='f')
10
returndigit+10-'a';
11
12
return'0';// Fehler
13
}
Mit dieser Funktion bewaffnet, wandelt man dann 2 stellige 'Zahlen'
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.
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
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 ;-)