Char-Array parsen

OP #2628421
Lesenswert?

Hallo zusammen,

ich habe schon lange gegoogelt, aber keine passende Lösung gefunden.
Ich habe nämlich folgendes Problem:

Ich empfange über den UART eines ATmega8 mehrere Chars, welche in einem 
Char-Array (= Buffer) zwischengespeichert werden. Dies funktioniert 
schon hervoragend in Verbindung mit HyperTerminal. Doch nun komme ich 
einfach nicht weiter: Ich muss nun den Char-Array im Ascii-Format parsen 
und dort Zahlen herauslesen.

Mein Protokoll:

         8 Bit             8 Bit   8 Bit

         Befehlsbuchstabe  Nummer  Wert

Beispiel 'p'               235     054

Die Strings von HyperTerminal sehen so aus:
p235054

Ich programmiere in C mit AVR-gcc.

Ich hoffe ihr könnt mir helfen.

Gruß Manuel
#2628426
Lesenswert?

Manuel Bentele schrieb:

> Die Strings von HyperTerminal sehen so aus:
> p235054


Also musst du diesen String erst mal in 3 Teile zerlegen.
1 char      Kommandobuchstabe
3 char      erste Zahl
3 char      zweite Zahl

damit hast du dann 2 Strings die du zb mittels atoi in richtige Zahlen 
umwandeln lassen kannst.

http://www.mikrocontroller.net/articles/String-Verarbeitung_in_C


PS. meistens ist es keine so gute Idee Zahlen direkt aufeinanderfolgen 
zulassen. Denn irgendwann macht wer beim zählen einen Fehler. Einfacher 
ist es oft zwischen die Einzelteile einen 'Trenner' einzubauen. Mach wir 
ja auch: zwischen 2 Wörter steht ein Leerraum.

p 235 54
oder

p 235,54
oder

p 235,54;
oder ....

ist um einiges fehlerunanfälliger, wenn ein Mensch die Steuerkommandos 
eingeben muss. Erzeugt ein Programm die Steuerkommandos, dann ist es 
allerdings egal, denn das erzeugt die Kommandos immer gleich und nur in 
Ausnahmefällen fehlerhaft (zb wenn die Ausgangszahlen zu groß sind)
#2628445
Lesenswert?

Dein String hat dieses format.
> p235054
Das erste Zeichen ist der Befehl
die Zeichen 2-4 sind eine Zahl
und die Zeichen 5-7 ebenfalls eine Zahl.
Du sammelst also immer 7 Zeichen.
Man könnte z.B. so vorgehen:
1
char chararray[] = "p235054";
2

3
char befehl    = char_array[0];
4
uint8_t nummer = (char_array[1] - 0x30)*100 + (char_array[2] - 0x30)*10 + (char_array[3] - 0x30);
5

6
uint8_t wert   = (char_array[4] - 0x30)*100 + (char_array[5] - 0x30)*10 + (char_array[6] - 0x30);

Eventuell könnte man die Übertragung anhand der Buchstaben, die bei dir 
ja Befehle darstellen synchonisieren, falls die Kommunikation mal aus 
dem Takt kommt. Eine Prüfsumme oder ein Paritätsbyte wäre vllt auch 
nicht schlecht, um die Übertragung abzusichern.

Gruß Oliver
OP #2628459
Lesenswert?

Vielen Dank für eure Antworten.

Ich werde Olivers Vorschlag gleich mal umsetzten.

@Karl Heinz Buchegger: Ich werde HyperTerminal nur zum Testen der 
Funktionalität benutzen. Deshalb werde ich den String ohne Trennzeichen 
zum UART schicken. Eine GUI sollte dann die Benutzerfehler abfagen (-> 
Exceptionhandling).
#2628471
Lesenswert?

> uint8_t nummer = (char_array[1] - 0x30)*100 + (char_array[2] - 0x30)*10 + 
(char_array[3] - 0x30);

Schreibs besser so:
1
uint8_t nummer = (char_array[1] - '0')*100 + (char_array[2] - '0')*10 + (char_array[3] - '0');

dann wird deutlicher, wo die 0x30 herkommen. Das ist einfach der ASCII 
Code des Zeichens '0'.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren