Hallo, ich programmiere einen ATmega in der AVR GCC Umgebung.
Ich empfange über UART Zeichen und Strings, die ich auswerten möchte:
z.B. 'Run', Stop', 'An', 'Aus'
Dies Sind in meiner Variablen gespeichert und wollen nun ausgewertet
werden. Meine Idee war mit switch - aber leider bekomme ich das nicht
hin. Hier ein Ausschnitt von meinem Code:
1
charData[10];
2
[...]
3
4
switch(Data)
5
{
6
case'1':
7
USART_Tx_s("Es wurde die Taste 1 gedrueckt");
8
_Enter;
9
break;
10
case'a':
11
USART_Tx_s("Das war ein 'a'");
12
_Enter;
13
break;
14
case'hallo':
15
USART_Tx_s("Herzlich Willkommen");
16
_Enter;
17
break;
18
default:
19
USART_Tx_s("Leider nicht im Programm.\n\r Versuchen Sie es noch einmal...");
20
_Enter;
21
break;
22
}
Die Daten werden über UART empfangen. Ich sende sie als Echo zurück. Das
funktioniert alles. Aber wie kann ich sie nun auswerten?
Äh, ja. Ich vergaß.
Was man manchen könnte, wenn man es mit switch machen will: Auf das
erste Zeichen prüfen. Im case-Block dann die weiteren Zeichen checken,
z.B. mit strcmp()?
Nimm Dir eine verkettete Liste, in der Du an jeder Listenposition einen
Zeiger auf einen String sowie einen Zeiger auf eine Abarbeitungsroutine
speicherst. Diese Strings sind Deine Befehlsworte.
Wenn Du einen Befehl bekommen hast, musst Du diese Liste durchsuchen und
bei einem Treffer die Abarbeitungsroutine anspringen.
Oder sowas (in etwa):
M.B. schrieb:
> M..., so was blödes. Gibts eine andere Möglichkeit?
es gibt 2 Möglichkeiten:
Entweder du beschränkst dich in deiner Übertragung und damit in den
Kommandos, die du übertragen kannst, auf 1-buchstabige (dann kannst du
switch nehmen) oder du überträgst ganze Strings, dann ist eine if -
elseif Kette mit lauter strcmp oder strncmp angebracht.
1
...
2
3
if(!strncmp(Data,"Run",3))
4
// Bearbeite Run-Kommando
5
6
elseif(!strncmp(Data,"Stop",4))
7
// Bearbeite Stop-Kommando
8
9
elseif(!strncmp(Data,"An",2))
10
// Bearbeite An-Kommando
11
12
elseif(!strncmp(Data,"Aus",3))
13
// Bearbeite Aus Kommando
14
15
else
16
// Bearbeite ungültiges Kommando
(und immer schön auf den Unterschied 'einzelner char' und 'String'
achten. Strings werden mit " geschrieben!)
Hm, was sind die Trennzeichen zwischen den zu empfangenden Wörtern? Man
könnte den Empfangsstring mit strtok() aufdröseln und dann in einer
Schleife mit strcmp() weitermachen.
Christian H. schrieb:
> Nimm Dir eine verkettete Liste, in der Du an jeder Listenposition einen> Zeiger auf einen String sowie einen Zeiger auf eine Abarbeitungsroutine> speicherst. Diese Strings sind Deine Befehlsworte.> Wenn Du einen Befehl bekommen hast, musst Du diese Liste durchsuchen und> bei einem Treffer die Abarbeitungsroutine anspringen.
Ein Array tut es auch ;)
Simon K. schrieb:
> Christian H. schrieb:>> Nimm Dir eine verkettete Liste, in der Du an jeder Listenposition einen>> Zeiger auf einen String sowie einen Zeiger auf eine Abarbeitungsroutine>> speicherst. Diese Strings sind Deine Befehlsworte.>> Wenn Du einen Befehl bekommen hast, musst Du diese Liste durchsuchen und>> bei einem Treffer die Abarbeitungsroutine anspringen.>> Ein Array tut es auch ;)
Ja, meinte ich eigentlich auch. Wieso ich "verkettete Liste" geschrieben
habe, weiß ich auch nicht. Irgenwie war ich mit den Gedanken woanders
8-|
Also vergesst "verkettete Liste" und denkt euch an der Stelle "Array".
Ok, vielen Dank für eure vielen Tipps und Kommentare.
Ich werde dann mein Programm so aufbauen, das ich mit "Einzelbuchstaben"
auskomme.
Ist zwar schade, aber einfacher. Trotzdem vielen Dank für die
hilfreichen Tipps, die nicht nur mir helfen werden.
Da bin ich mir sicher.
M.B. schrieb:
> Ich werde dann mein Programm so aufbauen, das ich mit "Einzelbuchstaben"> auskomme.> Ist zwar schade, aber einfacher.
:-)
Im Long-Run ist es auch nicht einfacher.
Warte ab, bis du das erste mal einem Kommando einen Parameter mitgibst.
Dann kommst du um Stringbearbeitung nicht mehr sinnvoll rum.
Das bischen switch versus strcmp Unterschied macht das Kraut auch nicht
fett. Zumal es, wie Christian H. schon angedeutet hat, eine sehr schöne
und praktikable Lösung gibt, eine zur Compilezeit gut konfigurierbare
Kommandostruktur über ein Array von Strukturen und Funktionspointer zu
schaffen. Und dann spielt der Unterschied Einzelbuchstabe versus
Kommandostring praktisch so gut wie keine Rolle mehr (ausser höchstens
durch den Speicherverbauch)
Fazit:
Es bringt nichts, sich vor Stringverarbeitung zu drücken. Irgendwann
holt sie dich trotzdem ein :-)
Is natürlich nicht komplett, aber das Prinzip sollte klar sein.
Damit könnte man sogar eine autocompletion bauen, Dh der Benutzer tippt
ein Zeichen und der µC bietet mögliche Kommandos an.