Hallo sehr geehrte Community. Ich stehe momentan vor einem Problem für das ich keine optimale Lösung habe, die Suchanfrage hat auch nichts Sinnvolles rausgespuckt :-) Und zwar habe ich einen Mega 16 so programmiert, dass er ASCII- Zeichen über RS232 empfängt und diese in einen 256 Byte Buffer ablegt. Übrigens alles in ASM. ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxx Gewünschte Funktion: Drei auf einander folgende Zeichen sollten als Befehl interpretiert werden. Das ist auch schon das hauptsächliche Problem. Als Beispiel bestehen diese Befehle nur aus Zahlen und somit währen 999 Befehle möglich. Für meine Anwendung reichen auch 100 Befehle. Zu jeden dieser Befehle möchte ich eine Anwendung aufrufen und etwas ausführen. Nur wie soll das gehen? Bitte um Hilfe !!
Wenn das nicht zwingend ASCII sein muss, dann bastel Dir eine "Wrapper Struktur" drum herum. Beispiel: Befehl: L (z.B: LED) Parameter: 01 oder 00 (für An und Aus) Jetzt verpacken wir das mit Synczeichen und Endezeichen: Sync: 0x16 Ende: 0x04 Jetzt braucht man nur noch einen Zustandsautomaten, der sich auf das Sync-Zeichen synchronisiert und nach dem Endezeichen den String an einen Auswerter übergibt. Alternativ kann man sich allerdings auch das Ganze etwas anders aufbauen, wenn keine "Maschine" die Kommandos sendet. So dass alles ASCII ist und immer bei CR am Ende der Uaswerter angeworfen wird.
Hoppla: Das mit dem Verpacken ist noch nicht vollständig: "SYN L 0 1 END" oder HEX: "0x16 0x4C 0x30 0x30 0x04"
wie weit bist du denn schon in deinen Überlegungen gekommen?
nach meinem Verständniss hast du folgende Teilthemen:
1. aus dem ankommenden Datenstrom "die richtigen" 3 Zeichen
rauszufischen
2. bei ankommenden Steuerbefehlen eine bestimmte Subroutine aufrufen
(ggf. Errorhandler)
Zu 1.
Das kannst nur du alleine wissen was du hast oder brauchst.
Möglicherweise hast du Einfluss auf beide Seiten (Sender und Empfänger),
dann wäre es möglich ein gewisses Minimal-Protokoll zu implementieren.
Vielleicht ist ja aber auch das Sendeprotokoll vorgegeben (das macht
die Sache eventuell leichter)
:: woran erkennst du, welche 3 Zeichen zusammen gehören? Wenn z.B. im
Datenstrom ankommt: "123 4 56"
- ist es dann 123 (weil dazwischen eine Pause ist zum nächsten Zeichen)
- oder 23 4 (weil deine Steuerkommandos immer mit 2xx anfangen)
- oder 3 4 5 (weil zwischen den einzelnen Ziffern deinen Steuerkommandos
immer eine gewisse Pause sein muß)
- oder .... oder
(Zweckmäßigerweise könntest du Steuerbefehle mit einem bestimmten
"Zauberwort" einleiten, so wie die Modems z.B. auf "AT" reagieren
:: was machst du mit den restlichen Zeichen (eventuell Müll) der da
eingetroffen ist?
:: Was machst du wenn der Eingangspuffer deiner Befehlssequenzen voll
ist (weil deine Subroutinen etwas länger brauchen)? Verwirfst du alle
ankommenden weiteren Steuerzeichen bis wieder "Luft" ist, oder
verwendest du eine Art Handshake, um den Sender zu signalisieren, daß er
erst mal aufhören soll?
zu 2:
Da die Anzahl deiner Steuerzeichen gering ist, kannst du das über
Sprungtabelle realisieren. Nachdem du erkannt hast daß PQ3 ein gültiger
Steuerbefehl ist, wird dieser "übersetzt" zu "nutze Sprungvektor 9". Und
von da aus hüpfst du los.
> für das ich keine optimale Lösung habe
Die Optimum-Kriterien solltes du vorher festlegen (Geschwindigkeit,
Platzbedarf, Eleganz des Codes, ...)
> Drei auf einander folgende Zeichen sollten als Befehl interpretiert > werden. Das ist auch schon das hauptsächliche Problem. > Als Beispiel bestehen diese Befehle nur aus Zahlen und somit währen 999 > Befehle möglich. Für meine Anwendung reichen auch 100 Befehle. > Zu jeden dieser Befehle möchte ich eine Anwendung aufrufen und etwas > ausführen. Wenn du 000 mitzählst, sind es 1000 Befehle. Du legst eine 2-Byte Variable an. Der Befehl wird ermittelt, indem du aus der ASCII-Zahl den numerischen Wert bildest, also erstmal 0x30 davon abziehst, und entsprechend der Stelle mit 100, 10 oder 1 multplizierst. Das ergibt dann den kompletten numerischen Wert des Befehls, welcher in der 2-Byte Variablen abgelegt wird. Zum Schluss über einen Vergleich herausfinden, um welchen Befehl es sich handelt, und entsprechend reagieren. Ralf
Hallo erstmal! Ich kann auch nicht genau erkennen, womit deine Frage jetzt "auf den Punkt" zu beantworten wäre... Wichtig ist: (was auch von den Vorrednern ausgeführt wurde) es muß eine eindeutige Trennung von Befehl und Parameter geben. Dies ist gerade auch im Hinblick auf Störungen im Übertragungskanal wichtig. Oft wird dafür ein Startzeichen oder eine -sequenz benutzt, die sonst im Datenstrom nicht vorkommt. Intel-Hex nutzt dafür den Doppelpunkt [:] Wenn also das Startzeichen / die Startsequenz erkannt wurde liest man entweder eine vorgegebene feste Anzahl an Zeichen (hier evtl. 3) oder bis zu einem erwarteten Trennzeichen (z.B. 'Space',20h). Wenn dann der Befehl isoliert ist, könnte man ihn für Befehlsnummern von 1...255 in HEX wandeln. dann kann man aus einer Tabelle die Zieladresse für die weitere Verarbeitung ablesen. Das Byte 00 bietet sich als Endemarke füer die Tabelle an. z.B. so: BEFTAB: .DEFB 1 ;Befehl "001" .DEFW prog1 ;wird hier ausgeführt .DEFB 3 ;Befehl "003" .DEFW prog7 ;hier .DEFB 11 ; usw. .DEFW prog23 .DEFB 55 .DEFW prog4 .DEFB 178 .DEFW prog37 .DEFB 0 ;hier ist Schluss, wenn Befehl jetzt noch nicht gefunden, dann Fehlerroutine. Für allgemeine Methoden der Befehlsentschlüsselung mit variabler Befehlslänge und/oder -struktur (Buchstaben Zeichen Ziffern / Unterscheidung Groß-Kleinschreibung usw.) heißt das Zauberwort "Parser" oder auch Befehlsdekoder. So nennt sich das bei allen Programmiersprachen, Compilern, Assemblern oder wo sowas eingesetz wird.
Guten Tag die Herren. @Wegstaben Verbuchsler sorry ich hätte die ganze Angelegenheit etwas Präziser umschreiben sollen, und zwar ist es so das, dass Protokoll mein eigenes Hirngespenst ist :-) Das ganze sieht dann mal so aus: Startkondition Befehl bestehend aus 3 ASCII Zeichen Daten variabler Länge CRC (noch nicht implementiert) Stoppkondition Gegen überlauf ist das Ganze auch geschützt. @Route_66 Eine eindeutige Trennung von Befehl und Parameter ist vorhanden(siehe Protokollaufbau oben). Insofern ich deine Idee verstanden habe, empfiehlst du mir die Empfangenen ASCII- Zeichen in eine HEX- zu Wandeln. Das sollte kein Problem sein, da ich die Daten ständig für Docklight(Terminalprogramm) und andersrum aufbereiten muss. Doch das mit der Tabelle ist mir nicht ganz klar. Ich kenne nur die Mehrfachverzweigung aus’m AVR- Tutorial oder die simpelste Art. Cpi, Breq : -) Könntest du mir bitte deine Version anhand von einem Beispiel etwas genauer schildern. Währe echt super. Das Zauberwort like Parser ist mir in der Tat nicht bekannt, doch mit Befehlsdecoder hab ich’s bereits probiert , ohne Erfolg weil Befehlsdecoder oft mit CPU- Befehlen in Verbindung gebraucht werden. @Rene THX für den Link
Hi >Als Beispiel bestehen diese Befehle nur aus Zahlen und somit währen 999 >Befehle möglich. Wenn du deine 'Adresse' Hexadezimal auslegst hättest du sogar 4096 mögliche Befehle. Für deine 100 würden zwei Stellen genügen. Die Auswertung würde sich dadurch auch vereinfachen. Du müsstest nur die ASCII-Ziffer in einen Hexwert umwandeln. Dann legst du dir eine Tabelle mit Sprüngen zu den entsprechenden Routinen an. Z mit dem Anfang der Tabelle laden und zu Z den doppelten Hexwert addieren. Mit 'icall' wird deine Routine aufgerufen. Geht ganz ohne Parsen. MfG Spess
> die Suchanfrage hat auch nichts Sinnvolles rausgespuckt :-)
Sowas heisst Parser oder lexical analyzer.
Weil so ein Problem sehr haeufig vorkommt gibt es tools (z.B flex) die
soetwas automatisch machen. Du beschreibst dort also deine Sprache und
das Tools erzeugt dir einen C-Source.
Unter Linux sollte dir 'man flex' weiterhelfen.
Olaf
Du bräuchtest einen Parser. Am einfachsten schreibst Du den erst einmal in Prolog und überlegst Dir dann, wie Du den in Assembler implementierst. Das Buch "Programming in Prolog" hat da eine schönes Kapitel zum Thema parsen, welches auch für Programmierer anderer Sprachen interessant ist.
@spess53 ne hexadezimal passt nicht! so müsste ich ASCII und HEX mischen und das kann nicht gut gehen ich bleibe lieber bei ASCII, weil auch schon alle Routinen mit PAP und Doku belegt sind. Es ist mir schon klar, dass durch ASCII ein Mehraufwand betrieben wird, aber so kann ich mit Zeichen „STX“, „EOT“ Handshakes ersetzten, da das ganze über RS232 läuft. Schlussendlich werden jetzt 3 ASCII Zeichen, deren Gesamtwert nicht 255 überschreiten darf nach HEX gewandelt. Somit steht mir eine 8-Bit Zahl im Bereich von 0-255 zur Verfügung, dieser Wert wird in die Mehrfachverzweigung http://www.mikrocontroller.net/articles/AVR-Tutorial:_Mehrfachverzweigung geladen und anschließend durch die Tabelle zu Routinen umgeleitet. Vielen dank für die zahlreichen guten Tipps. Ihr habt mir dazu verholfen mein Projekt einen Schritt weiter zu bringen. //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XX Ich wünsch euch allen noch ein Frohes Weihnachtsfest XX //XX und einen guten rutsch ins neue Jahr! XX //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
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.