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
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)
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
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).
> 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'.
Das stimmt: So wird es übersichtlicher. Ich habe es gerade ausprobiert: Es funktioniert. Wenn das ganze Projekt fertig ist, werde ich es im Forum in Form von Bildern zeigen.
Karl Heinz Buchegger schrieb: > dann wird deutlicher, wo die 0x30 herkommen. Das ist einfach der ASCII > Code des Zeichens '0'. Nun ja. Das ist in diesem Fall Geschmackssache. Ich schreib es schon ewig als 0x30 und finde daher '0' recht ungewöhnlich. Gruß Oliver
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.