Forum: Mikrocontroller und Digitale Elektronik UART Kommunikation - Statemachine


von Steffen (Gast)


Lesenswert?

Hallo zusammen,

mir geht es gerade nicht um ein konkretes Problem, sondern ich bin 
gerade am Überlegen, wie ich einen Programmteil am effektivsten aufbaue.

Implementiert werden soll eine UART Kommunikation mittels AT-Befehlen 
mit einem Handy. Hierzu wird immer ein Kommando vom uC gesendet und das 
Handy antwortet hierauf. Je nach Antwort soll dann ggf. wieder ein 
weiterer Befehl gesendet werden usw.

Um nicht das ganze Programm zu blockieren, kann ich natürlich nicht 
einfach warten, bis das Handy antwortet. Im Moment plane ich, das ganze 
wie folgt zu lösen:

- Eine Funktion wird von der Mainschleife ständig aufgerufen. In dieser 
wird die Variable "Zustand" abgefragt. Diese hat zunächst den Wert 0. 
Beim Wert 0 wird der erste Befehl an das Handy geschickt und der Wert 
auf 1 gesetzt. Diese Funktion reagiert nicht mehr auf den Wert 1.
- Die Empfangsdaten vom UART werden per Interrupt in einen Buffer 
geschrieben.
- In der Mainschleife wird der Buffer ständig auf "\n\r" geprüft. Sobald 
diese Zeichen gefunden wurden, hat das Handy geantwortet. Jetzt wird 
"Zustand" um 1 inkrementiert.
- Die oben genannte Funktion reagiert auf Zustand = 2, liest dann den 
Empfangspuffer aus und setzt dann Zustand auf 3 (und sendet ggf. wieder 
ein Kommando)

Damit das Programm bei einem Fehler nicht hängen bleibt, wird mittels 
eines Timeouts Zustand auf 0 gesetzt.

Das ganze sollte soweit funktionieren. Die Frage ist nur, ob es auch 
irgendwie intelligenter und effektiver gehen könnte. Vielleicht hat 
hierzu jemand einen Vorschlag.

Ich hoffe, ich habe mich einigermaßen verständlich ausgedrückt.

Vielen Dank!
Steffen

von Matthias D. (marvin42)


Lesenswert?

ja, du hast dich verständlich ausgedrückt und das ist auch m.E. die 
effektivste Methodeüberhaupt um eine async. Kommunikation zu 
programmieren.
Evt. verwendest du für die Zustände ENUMs anstelle einer Zahl, dann wird 
der Code lesbarer.

matthias

von Purzel H. (hacky)


Lesenswert?

Ich wuerde die End of Befehl Sequenz im Rx Interrupt prufen und in der 
Main() nur schauen ob ein flag gesetzt wurde.

von dunno.. (Gast)


Lesenswert?

wenn man es macht wie matthias vorgeschlagen hat, und enums für die 
einzelnen zustände benutzt, kann man auch aus einem zustand in den 
anderen wechseln, indem man die variable gezielt verändert (nicht nur 
++)

zb kann man dann im fehlerfall eine fehlerbehandlung aufbauen, und 
direkt die sequenz von vorne beginnen, etc..


- wir habens an der uni als methode der wahl gelernt.

mfg

von Steffen (Gast)


Lesenswert?

Das mit den ENUMS hatte ich vor, ich wollte meinen Text allerdings nicht 
noch komplizierter bauen.

Danke dir für die Antwort!

von Karl H. (kbuchegg)


Lesenswert?

> - In der Mainschleife wird der Buffer ständig auf "\n\r" geprüft. Sobald
> diese Zeichen gefunden wurden, hat das Handy geantwortet. Jetzt wird
> "Zustand" um 1 inkrementiert.


Leg den Teil noch in die Statemachine und du bist auf einem guten Weg.

DIe Statemachine ist für ihre Zustände selber zuständig.
WEnn sie im Status 1 ist, dann bedeutet dieser Status dann eben: Den 
Eingangsbuffer auf \n\r überprüpfen. Und nur die Statemachine selber 
entscheidet, ob das der Fall ist und ob sie daher in den nächsten 
Zustand wechseln darf/soll.

von Steffen (Gast)


Lesenswert?

Also im Beispiel oben der Zustand "1" überprüft, ob "\n\r" im Buffer 
steht.

Sehr schön, dann werde ich heute Abend gleich mal anfangen, wenn ich aus 
der Arbeit komme. Vielen Dank!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Steffen schrieb:
> Also im Beispiel oben der Zustand "1" überprüft, ob "\n\r" im Buffer
> steht.

Mit "\n\r" wirst du nicht viel Freude haben. Erst kommt das CR, dann das 
NL.

Gruß,

Frank

von Steffen (Gast)


Lesenswert?

Dann eben anders rum ;-) Hatte nur aus dem Kopf berichtet

Aber danke schön für den Hinweis!

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
Noch kein Account? Hier anmelden.