Forum: Mikrocontroller und Digitale Elektronik UART für Parameterübergabe


von Peter (Gast)


Lesenswert?

Hallo,
ich brauch mal ein Gedankenanstoß.
Ich benutz die Uart von ATMegas gern um Programme einzustellen und zum 
debuggen.
Bisher ist es aber recht umständlich oder nicht flexible. zb ein Byte 
für den Kommand und dann ein Byte oder 2 (als int) für den Wert.
Zb. 5 (PWM) 100(Wert).
Im Programm sieht es dann so aus:
1
...
2
Uart_prog=5;
3
Uart_var=100;
4
...
5
switch(Uart_prog)
6
{
7
 case...
8
9
 case 5:
10
 ORC0A=Uart_var;
11
 break;
12
13
 case ...
14
}
Hat einer eine elegantere Lösung, meine Lösung ist etwas.. primitiv und 
unhandlich?

von Cyblord -. (cyblord)


Lesenswert?

Ist eigentlich normal mit Switch/Case.

Man kann das ganze mit einem Array aus Structs anlegen. In einem Struct 
steht dein UART_PROG und ein Funktionszeiger. Diese Funktion verarbeitet 
dann deine UART_Var. Kommen nun Bytes an, so durchsucht der Handler alle 
Structs im Array bis er das Struct mit dem gleichen UART_PROG findet und 
führt dessen Funktion(szeiger) mit UART_VAR aus.

Am Programmbeginn müssen einmal alle Structs erzeugt und mit den 
korrekten Funktionszeigen befüllt und ins Array aufgenommen werden.

Also eine Art Objektorientierter Ansatz.

gruß cyblord

von Peter (Gast)


Lesenswert?

Vielen Dank für deine Antwort.
Ich werde mir die Idee mal anschauen, aber glaub allzu anders als meine 
Switch/Case ist das auch nicht. Hat man vorteile bei größeren Listen in 
sachen Übersicht oder Speicherverbrauch?

Hab bisher noch nicht so mit Zeigern gearbeitet, meist übergeb ich 
Variable Structs als Zeiger in andere Unterprogramme.

von B. S. (bestucki)


Lesenswert?

Peter schrieb:
Hat man vorteile bei größeren Listen in
> sachen Übersicht oder Speicherverbrauch?

Ich mache das meist auch mit einem Array aus Strukturen. Von der 
Übersicht her finde ichs ganz angenehm, da ich nicht mitten im Code nach 
den Befehlen suchen muss, sondern ganz am Anfang der Sourcedatei. Die 
Auswertung erfolgt dann in einer for-Schleife, also eher kurzer Code. 
Bezüglich Speicherverbrauch kann ich keine Aussage machen.


> Hab bisher noch nicht so mit Zeigern gearbeitet, meist übergeb ich
> Variable Structs als Zeiger in andere Unterprogramme.

Einfach mal im Internet suchen oder in einem C-Buch nachlesen.
Stichwort: Funktionszeiger

von Peter (Gast)


Lesenswert?

Oki vielen Dank.
Denke mit dem Stichwort Funktionszeiger komm ich weiter.

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Vielen Dank für deine Antwort.
> Ich werde mir die Idee mal anschauen, aber glaub allzu anders als meine
> Switch/Case ist das auch nicht. Hat man vorteile bei größeren Listen in
> sachen Übersicht oder Speicherverbrauch?

Übersicht: ja, weil die relevanten Informationen mehr oder weniger an 
einer Stelle gesammelt beisammen bleiben

Speicherverbrauch: eher nicht, weil die Strukturierung in ein immer 
gleiches Daten-Schema fast zwangsläufig zuätzliche 
Strukturierungselemente benötigt und zum anderen nicht so optimal auf 
individuelle Probleme eingehen kann.

> Hab bisher noch nicht so mit Zeigern gearbeitet, meist übergeb ich
> Variable Structs als Zeiger in andere Unterprogramme.

Alles halb so wild
FAQ - Funktionszeiger

von Peter (Gast)


Lesenswert?

Sieht wirklich Übersichtlicher aus als mit der Switch Case variante.
Vielen Dank, an die FAQ hatte ich gar nimmer gedacht..

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Sieht wirklich Übersichtlicher aus als mit der Switch Case variante.
> Vielen Dank, an die FAQ hatte ich gar nimmer gedacht..

Bevor du loslegst:
Bei mir hat es sich immer bewährt, wenn ich mir vorher mal kurz 
aufschreibe, wie ich im Endergebnis dann meine 'Daten' eingeben möchte. 
Und von dort fange ich dann an, das Pferd aufzuzäumen.

Ich könnte mir zb vorstellen, dass deine 'Parameter Auswertungs 
Beschreibung' (ein furchtbares Wort) zb so aussieht
1
  {  0x01, 1, SetToByte,      &Seconds },
2
  {  0x02, 1, SetToByte,      &Minutes },
3
  {  0x03, 1, SetToByte,      &Hours },
4
  {  0x04, 1, SetToPrescaler, &TCCR1A },
5
  {  0x05, 2, SetToWord,      &OCR1A },
6
7
                                ^
8
                                | in welche Variable soll der Wert
9
                 ^
10
                 | welche Funktion macht das (wegen Byte, Word, ...)
11
           ^
12
           | wieviele Datenbytes kommen noch von der UART
13
       ^
14
       | Wert des Kommandobytes von der UART

Ich sag jetzt nicht, dass das die einzig mögliche Art und Weise ist. Zb 
ist es fraglich, ob man die Anzahl der Bytes von der UART explizit 
anführen muss oder nicht, oder ob das nicht die aufgerufene Funktion 
wissen sollte. Da steht vieles offen.

Aber so fange ich normalerweise an. Ich überlege mir, wie so eine 
Beschreibung beispielsweise aussehen könnte, so dass da alles drinnen 
ist, was ich haben möchte.
1
{  0x02, 1, SetToByte,      &Minutes },
Wenn das Kommando 0x02 kommt, dann kommt da noch 1 Datenbyte hinten 
nach, welches in die Variable Minutes bugsiert werden soll und genau 
dafür ist die Funktion SetToByte zuständig.

Wobei: wenn ich es mir so recht überlege. Für die 3 oder 4 verschiedenen 
Funktionen die es da gibt, da lohnt sich ein Funktionspointer eigentlich 
gar nicht. Ein Aktions-Typ, der entsprechend ausgewertet wird, tuts 
eigentlich auch. Spart pro Kommando schon wieder 1 Byte ein.

Und dann gehts erst mit Code los - angefangen bei der 
Strukturdefinition.


Denk dir was aus - implementiere es - sieh nach wo dich die Idee 
hinführt. Und wenn sich nach ein paar Stunden rausstellt "äääääää, war 
nicht so prickelnd", dann merk dir was das eigentliche Problem in diesem 
Ansatz war, und probier was anderes.

Letzten Endes ist das genau das, was wir alle getan haben um heute vorab 
schätzen zu können: Die Idee ist gut - die Idee ist nicht so gut.
Macht man das ein paar mal, dann entwickelt sich auch ein Bauchgefühl, 
ob eine Idee tragfähig ist oder nicht.

von Peter (Gast)


Lesenswert?

Danke Buchegger für den Ablauf.
Mir gehts nur um mich etwas Weiterzubilden, ich prorgammier schon eine 
ganze Weile und fand die Switch Case immer etwas Primitiv.

Ich wollte mir eine kleine Shell aufbauen die relativ flexible ist.
Zb das ich mal schnell mit einem Bluetooth vom Tablet oder Handy aus ein 
System vorort umkonfigurieren kann oder Prüfdaten ablesen kann.

Sprich ich hab nachher ein klein Parser vom ASCII nach Binär und das 
wollt ich danach in den Funktionspointer schicken.
Je nach Anwendung benutz ich direkt Binärdaten oder ebent ASCII.

Mit dem Funktionspionter kommt ich wieder ein Stück weiter und schreib 
etwas sauberen Code.

Ist es einglich Sinnvoll sich die Variablen in einem Struct zu packen 
und die in den Funktionen zu übergeben?

Zb im Main setz ich mir ein Struct stc_sys System;
und wenn ich zb Uhr_akt(&System); aufruf um die Uhrzeit zu 
aktualisieren.
So hätte ich die Uhrzeit dann in jeder Funktion zur Verfügung über den 
Pointer auf dem Struct vom System.
Gibt es da sinnvollere Programmablauftechniken?
Ich weiß ist sehr Oberflächlich und Allgemein gefragt.

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:

> Ich weiß ist sehr Oberflächlich und Allgemein gefragt.

und daher schwierig zu beantworten.
Meine Antwort wäre: Ja, doch. Kann sinnvoll sein. Wenns nicht zu viele 
sind. Eine Struct mit 200 Member ist wahrscheinlich nicht mehr sinnvoll.

Es hängt eben auch immer vom konkreten Programm ab.

von Falk B. (falk)


Lesenswert?


von Peter (Gast)


Lesenswert?

Danke euch beiden. Dann war meine Idee von einer sinnvollen 
Hauptspeicherstelle gar nicht so falsch.
Ich weiß das viele Details wichtig sind, wollte nur mal horchen obs 
grundsätzlich Sinnvoll ist.

Deine Routine hab ich bisher noch gar nicht gesehen, Falk.. ich dachte 
ich hätte alle Post zu UART gelesen..
Es ist ähnlich wie bei mir, nur nicht ganz so raffiniert und 
Übersichtlich geschrieben. Besonders die Unterteilung in extra Funktion 
hatte ich nicht. In meiner wurden nur Variable umgesetzt.

Besten Dank für den ganzen Input und ich hatte schon befürchtet ich werd 
in der Luft zerfetzt wegen meiner Frage.. lach

Die Sachen werden mir sicher sehr weiter Helfen, ich muss sie mal in 
ruhe alle Durchspielen und mit rumprobieren.

Falks Switch Version gefällt mir gut von der Übersicht her und scheint 
für kleine Dinge optimal zu sein und die Pointer sache scheint mir für 
größere Projekte ideal zu sein, rein vom Bauchgefühl her.

Nun werd ich meine Erfahrung damit sammeln.

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.