Forum: Mikrocontroller und Digitale Elektronik Funktion mit je 2 rückgabewerten?


von x5 (Gast)


Lesenswert?

Guten Morgen zusammen,


ich habe eine kleine Frage und zwar habe ich mir eine Funktion gebaut
die kurz überprüft ob und welche meiner 2 Tasten gedrückt worden ist.
Wenn Taste_Links(4) gedrückt ist soll eine 1 zurück gegeben werden wenn 
Taste_Rechts(8) gedrückt worden ist soll eine 0 zurückgegeben werden.

nur wo bzw wie kann ich das ergebnis dieser funktion im weiteren 
programm ablauf abrufen?

hier die kleine funktion
1
test_funktion()
2
{
3
while(auswahl_getroffen == 0)
4
    {
5
    if(Schalter == 4)
6
      {auswahl_getroffen = 1; return 1;}
7
    if(Schalter == 8)
8
      {auswahl_getroffen = 1; return 0;}
9
  
10
    Schalter = 0;
11
    }
12
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

x5 schrieb:
> hier die kleine funktion
Diese kleine Funktion ist noch nicht ganz fertig, denn es fehlt
1. die Definition eines Rückgabetyps:
1
int test_funktion() {...

Und
2. kannst du dir die while-Abfrage sparen, denn die Funktion wird 
soweiso bei einem return verlassen:
1
{
2
while(1)
3
    {
4
    if(Schalter == 4) return 1;
5
    if(Schalter == 8) return 0;
6
    Schalter = 0;
7
    }
8
}

Eine Frage bleibt: woher kommt jetzt der Wert für den Schalter?
So wie die Funktion derzeit aussieht, ist das eine Endlosschleife... :-o

von x5 (Gast)


Lesenswert?

Ach sorry vergessen - Ich frage im Timer1 Interrupt alle 100 ms die 
schalter zustände ab die an PING angeschlossen sind und setze dann die 
jeweiligen bits in "Schalter"

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Du testest aber weder die Bits noch prüft deine Funktion ob eine Taste 
gedrückt wurde vielmehr wartet die Funktion bis genau die eine 
oder andere Taste gedrückt wurde (grusel) und das "Ergebnis der 
Funktion" ruft man njicht ab sondern die Funktion auf und wertet 
dann den Rückgabewert aus...

von x5 (Gast)


Lesenswert?

Ja das ich nur auf diese beiden Tasten warte ist wichtig - Später soll 
da noch eine kurze zeitschleife rein das man nur ca 5 sekunden in der 
funktion hängt und danach wird die abfrage abgebrochen. Die endscheidung 
ist sehr wichtig welche taste da gedrückt wird.

aber wie werte ich denn dann den rückgabe wert aus ?

von Justus S. (jussa)


Lesenswert?

x5 schrieb:
> aber wie werte ich denn dann den rückgabe wert aus ?

das sollte wohl in jedem C-Buch oder Tutorial, egal wie schlecht, 
erklärt werden...

von Klaus W. (mfgkw)


Lesenswert?

z.B. in der Art:
1
#define SCHALTER1 (0b00000100)
2
#define SCHALTER2 (0b00001000)
3
...
4
    while(1)
5
    {
6
        if( Schalter & SCHALTER1 )
7
        {
8
           Schalter  &= ~SCHALTER1; // dieses Bit wieder löschen
9
           return 1;
10
        }
11
        else if( Schalter & SCHALTER2 )
12
        {
13
           Schalter  &= ~SCHALTER2; // dieses Bit wieder löschen
14
           return 1;
15
        }
16
    }

Das passt zum Stil der meisten Beispiele hier.

von Artur R. (artur2000)


Lesenswert?

in C können Funktionen nur einen Rückgabewert zurückgeben. Möchtest du 
trotzdem mehrer Rückgabewerte haben, macht man das mit Zeigern, indem 
die Adressen der rückgegbenen Variablen der Funktion übergeben wird und 
in der Funktion mit den Adressen gearbeitet wird. Für nähere 
Erläuterungen und Beispiele bitte googeln bzw. in einem C Buch 
nachgucken.

Wenn du mit Tastern arbeitest, wirst du Probleme mit Prellungen haben. 
Das heißt, du drückst einmal auf einen Taster, aber die Kontakte 
schließen und öffnen sich mehrmals. Deshalb empfehle ich dir die fertige 
Funktion "debounce" zu verwenden, die findest du hier irgendwo.

von Klaus W. (mfgkw)


Lesenswert?

Oder eher meine Art:
1
typedef struct
2
{
3
   unsigned  schalter1:1;
4
   unsigned  schalter2:1;
5
   // ... weitere ...
6
} schalter_t;
7
8
schalter_t  derSchalter;
9
10
...
11
12
    while( 1 )
13
    {
14
        if( derSchalter.schalter1 )
15
        {
16
            derSchalter.schalter1 = 0;
17
            return 1;
18
        }
19
        else if( derSchalter.schalter2 )
20
        {
21
            derSchalter.schalter2 = 0;
22
            return 0;
23
        }
24
    }

von Klaus W. (mfgkw)


Lesenswert?

Artur R. schrieb:
> in C können Funktionen nur einen Rückgabewert zurückgeben.

ich glaube, er will einen von 2 Werten zurückgeben, nicht beide 
gleichzeitig.

von M3 (Gast)


Lesenswert?

Artur R. schrieb:
> in C können Funktionen nur einen Rückgabewert zurückgeben.

Und? Das will er ja machen; er will GENAU EINEN Wert zurückgeben, dieser 
soll je nach Situation unterschiedlich sein. Er will NICHT auf einmal 2 
Returnwerte zurückgeben das würde so gehen wie Du beschrieben hast.
So werden ja auch z.B. Fehlermeldungen realisiert.
Wenn gut: return 0; Wenn schlecht: return 1; ...

>Wenn du mit Tastern arbeitest, wirst du Probleme mit Prellungen haben.
Is hier auch nicht Thema...

2 Themaverfehlungen ;)

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Artur R. schrieb:
>> in C können Funktionen nur einen Rückgabewert zurückgeben.
>
> ich glaube, er will einen von 2 Werten zurückgeben, nicht beide
> gleichzeitig.

Das glaub ich ehrlich gesagt nicht.
Sein Denken wird um die Fragestellung kreisen: Was, wenn beide Tasten 
gedrückt sind?
Dafür wurden ja auch schon Lösungen gennant, die alle nach dem Muster 
laufen: Man überlegt sich ein Schema, mit dem man auch beide Tasten 
kodieren kann und so wieder nur einen Returnwert braucht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Artur R. schrieb:
> Wenn du mit Tastern arbeitest, wirst du Probleme mit Prellungen haben.
Da wäre es dann gut, wenn eine Kühlpackung in der Nähe wäre, damit es 
keine blauen Flecken gibt... ;-)

von x5 (Gast)


Lesenswert?

Ja genau ich möchte nur einen wert der funktion übergeben. und zwar soll 
damit eine EnTscheidung getroffen werden. Ob der Zustand eines Ventils 
geändert werden soll und zwar wollte ich das in eine Funktion packen 
weil das auch noch mit 10 anderen Ventilen passieren sollte und ich 
nicht diese Auswertung 10 mal schreiben wollte


das sollte dann ungefähr im code so aussehn
1
......
2
test_funktion();
3
4
if("Funktionrückgabewert == 1")
5
{PORT_OUT |= (1<<V1);}
6
else
7
{"mache noch nichts"}
8
......

so in der art.

nur wie ich dann nach der funktion elegant deie Entscheidung abfragen 
kann. Klar ich könnte irgendne globale Variable auf 1 setzen in der 
Funktion - aber das müsste doch eleganter gehen oder ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

x5 schrieb:
> Ach sorry vergessen - Ich frage im Timer1 Interrupt alle 100 ms die
> schalter zustände ab die an PING angeschlossen sind und setze dann die
> jeweiligen bits in "Schalter"
Dann ist diese Denkweise hier falsch:
1
test_funktion()
2
{
3
while(auswahl_getroffen == 0)
4
    {
5
    if(Schalter == 4)
6
      {auswahl_getroffen = 1; return 1;}
7
    if(Schalter == 8)                       // **1**
8
      {auswahl_getroffen = 1; return 0;}
9
  
10
    Schalter = 0;                           // **2**
11
    } 
12
}
Denn was würde hier passieren, wenn genau hier (**1**) ein Interrupt 
käme und Schalter auf 4 setzen würde?
Richtig: gleich danach wird bei (**2**) der Schalter wieder auf 0 
zurückgesetzt...  :-o

Sogar das kann schiefgehen:
1
        if( Schalter & SCHALTER1 )
2
        {
3
           Schalter  &= ~SCHALTER1; // dieses Bit wieder löschen
4
           return 1;
5
        }
Wenn der Read-Modify-Write unterbrochen wird... :-o

Merke:
Interrupts kommen immer dann, wenn du sie am wenigsten vermutest!

x5 schrieb:
> - aber das müsste doch eleganter gehen oder ?
Ja, wenn du eine richtige Sofwarestruktur aufbauen würdest:
alle diese Tastenabfragen usw. usf. gehören in die Hauptschleife.
Und Tasten/Eingänge werden nicht über Interrupts, sondern in dieser 
Hauptschleife abgefragt.

Zeig doch mal deine komplette C-Datei (als Anhang mit Endung .c).

von H.Joachim S. (crazyhorse)


Lesenswert?

Du kannst doch dem Rückgabewert verschiedene Werte geben, gerade bei 
Tastern oder Errorwerten nehme ich gerne eine direkte Bitkodierung.

#define TASTER1 1   //Bit 0
#define TASTER2 2   //Bit 1
#define TASTER3 4   //Bit 2
.
.



unsigned char Taster_lesen ()
{unsigned char temp=0;
if (xx) temp=temp | TASTER1;
if (xx) temp=temp | TASTER2;
if (xx) temp=temp | TASTER3;
return (temp);
}

So kannst du dann feststellen, ob überhaupt was passiert ist (return>0)
und wenn ja, welche, auch mehrere und beleibige Kombinationen.

von x5 (Gast)


Lesenswert?

das sind rund 2k zeilen code wo es später eingesetzt werden soll. das 
ist momentan nur ein kleines test programm. Aber ich denke mal ich hab 
den rest schon nicht so toll programmiert. bei mir haperts an mangelnder 
erfahrung und zeitdruck. ich muss mir C# so schnell wie möglcih selbst 
beibringen und halt lernen

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

x5 schrieb:
> das sind rund 2k zeilen code wo es später eingesetzt werden soll.
Ja und? Dann poste das eben (als Anhang mit Endung .c)...
"Rat" kommt nicht von "Raten".

von x5 (Gast)


Lesenswert?

Also speziell jetzt in meinem Fall wird später auf dem Display stehen 
Soll das V xy wirklich geöffnen werden und dann als Auswahl Ja / Nein 
welche man mit den Besagten Tasten auswählen kann.


Meine Menustruktur ist auch schon leicht Marode sowie die 
Tastenenprellung sollte geändert werden nur bleibt mir dafür grade keine 
Zeit. Momentan ist alles einfach nur mehr oder weniger eingeprügelt bis 
es läuft - weil da so ein druck hinter steht

von Sebastian B. (sebastian86)


Angehängte Dateien:

Lesenswert?

Oki ich hänge das Hauptfile dran. Nur nicht erschlagen ;)


Zum groben Aufbau in der Mainschleife ist man im Hauptmenu in dem man 3 
Verschiedene Programmmodi auswählen kann "Programm Automatik" habe ich 
vor 3 tagen auf eine Statemachine geändert das war vorher eine Abfolge 
ind If und Ifelse ich kannte bis Dato noch keine Statemachine

Programm Manuell ist grade in meiner Bearbeitung

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

x5 schrieb:
> das sind rund 2k zeilen code wo es später eingesetzt werden soll.

Ich will Dir ja nicht zu nahe treten, aber meinst Du nicht, daß Du Dich 
da ein winzigkleines Bisschen übernommen haben könntest? Das "Auswerten" 
des Rückgabewertes einer Funktion ist kein obskures Wissen, das man in C 
(oder oder auch beliebigen anderen Programmiersprachen) nur alle paar 
Monate mal braucht, das ist absolutes Grundlagenwissen.

Der Ansatz "learning by doing" ist ja an und für sich nicht völliger 
Mumpitz, wenn aber das "doing" überbetont wird und auf das "learning" 
komplett verzichtet wird, dann wird das ganze vollkommen nutzlos.

Literaturhinweis: Brian Kernighan & Dennis Ritchie "Programmieren in C", 
Hanser-Verlag, 2. Auflage.

Durchlesen! Übungen darin nachprogrammieren, Aufgaben darin bearbeiten. 
Nochmal durchlesen! Programmcode von anderen Leuten ansehen, versuchen, 
die dort gemachten Dinge zu verstehen und im Buch die entsprechenden 
Stellen finden.

Dann kannst Du gerne auch "2k zeilen code" entwickeln wollen. Dann. 
Aber nicht so.

von Sebastian B. (sebastian86)


Lesenswert?

joar ich weiss :/ am anfang wars auch ein winziges Projekt alá kannst du 
mal gucken ob du das und das hinbekommst. Dann kam immer mehr und mehr 
dazu und wurde extrem aufgebläht.... :(

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann nimm Dir 'ne Auszeit und lerne die Grundlagen. Jetzt! Sonst 
fällst Du später immer wieder auf irgendwelche Banalitäten rein.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian B. schrieb:
> joar ich weiss :/ am anfang wars auch ein winziges Projekt alá kannst du
> mal gucken ob du das und das hinbekommst. Dann kam immer mehr und mehr
> dazu und wurde extrem aufgebläht.... :(

Der übliche Softwarezyklus.
"Ach, das ist doch ganz einfach. Da ist doch die universelle 
Standardlösung komplett überkandidelt. Das machen wir ganz einfach"

Wochen, Monate, Jahre später: "Hätte ich doch damals nur ...."

Merke: Jede, aber ausnahmslos jede voreilig angenommene Vereinfachung 
oder Jugendsünde rächt sich irgendwann!

Eine zeitlang kann man das alles kaschieren, aber irgendwann bricht das 
Kartenhaus zusammen.

Dann ist es meistens mit 1 oder 2 Zeilen ändern nicht getan. Software 
entwickeln bedeutet auch, dass man sich mit jeder Erweiterung immer der 
Frage stellt: Ist meine Architektur dem Problem noch angemessen oder 
sollte ich sie besser jetzt anpassen anstatt in ein paar Wochen, wenn 
alles kurz vor dem Kollaps steht.
In der Theorie ist das nicht notwendig. Denn in der Theorie nimmt man 
immer von vorne herein gleich den richtigen Ansatz. Aber in der Praxis, 
gerade bei unerfahrenen Programmierern, ist diese Theorie nichts wert.

Aus genau diesem Grund wird hier im Forum Wert darauf gelegt, auch bei 
kleinen Programmen mit Softwareansätzen zu arbeiten, die sich bewährt 
haben und von denen wir wissen, dass sie auch nach einiger Zeit noch 
tragfähig sind. Selbst wenn das am Anfang nach unnötiger Mehrarbeit 
aussieht.

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.