Forum: Compiler & IDEs #define


von Miks (Gast)


Lesenswert?

Hallo,
ich möchte einen RESET an einem IC durchführen, dazu soll ein Port 
gelöscht und wieder gesetzt werden. Kann man das mit einem #define 
lösen? Betonung liegt hierbei auf EINEM.
Bsp.

#define RESET          PORTB.7=0; PORTB.7=1


RESET;


vorangegangenes wird vom Compiler nicht bemeckert. Das was ich möchte 
wird aber auch nicht ausgeführt. Gibt es eine (andere) elegante 
Möglichkeit?


Dank und Gruß

von Karl H. (kbuchegg)


Lesenswert?

Ein #define ist nur die Anweisung an den Präprozessor
im restlichen Quelltext eine Textersetzung zu machen.
Wenn du also schreibst

#define RESET          PORTB.7=0; PORTB.7=1

int main()
{
  RESET;
}

dann bekommt der Compiler dieses zur Übersetzung
vorgeworfen;

int main()
{
  PORTB.7=0; PORTB.7=1;
}

Ob das das macht, was du möchtest musst du selbst
entscheiden.

> Das was ich möchte wird aber auch nicht ausgeführt

Wenn etwas nicht ausgeführt wird, dann liegt das normalerweise
daran, dass der Programmfluss niemals zu diesen Anweisungen
gelangt. Das ist wie eine Funktion, die du zwar schreibst,
aber nie aufrufst.


von TT (Gast)


Lesenswert?

hi,
ich denke du suchst sowas hier:

Beitrag "Re: sbit macro für avr-gcc"

oder?

MFG

TT

von Miks (Gast)


Lesenswert?

Danke,

@Karl heinz

 PORTB.7=0; PORTB.7=1;
genau das soll er vorgeworfen bekommen ;)

dann sollte es an etwas Anderem liegen, mal schaun.

von Oliver (Gast)


Lesenswert?

Wenn dein gcc die Schreibweise PORTX.PIN tatsächlich kennt 
(avr-gcc/avrlibc tun das nicht, die brauchen die im o.a. link gezeigten 
Datenstrukturen dazu), dann bleibt noch die Frage, ob der zu resettende 
IC eine Mindestimpulsdauer erfordert. Ein direkt aufeinanderfolgedes 
rücksetzen/setzen eines Pins geht verdammt schnell.

Oliver

von yalu (Gast)


Lesenswert?

> PORTB.7=0; PORTB.7=1;

Was hast du denn für einen GCC, der obiges beim kompilieren nicht
anmeckert? Meiner kann so etwas nicht. Eine Ziffer nach einem Punkt
kenne ich nur von FP-Konstanten, um die es hier aber offensichtlich
nicht geht.

Noch ein Tipp:

Wenn man mehrere Anweisungen in ein Makro packen möchte, empfiehlt es
sich, die Anweisungen in eine einmalig ausgeführte Schleife zu packen,
also statt
1
#define DOBOTH() a=1; b=2;

oder
1
#define DOBOTH() { a=1; b=2; }

folgendes:
1
#define DOBOTH() do { a=1; b=2; } while(0)

Dann funktionieren auch Anweisungen wie
1
  if(condition)
2
    DOBOTH();
3
  else
4
    sonstwas();

korrekt. Das do/while wird vom Compiler wegoptimiert.

von Falk (Gast)


Lesenswert?

@yalu

>man mehrere Anweisungen in ein Makro packen möchte, empfiehlt es
>sich, die Anweisungen in eine einmalig ausgeführte Schleife zu packen,

??? Wieso das? Das mit den geschweiften Klammern versteh ich ja noch 
irgendwie (als Block gruppieren, wegen If Konstruktion etc.), aber mit 
ner Schleife?

MFG
Falk

von yalu (Gast)


Lesenswert?

> ??? Wieso das? Das mit den geschweiften Klammern versteh ich ja noch
> irgendwie (als Block gruppieren, wegen If Konstruktion etc.), aber mit
> ner Schleife?

Die zweite Alternative (mit den {} aber ohne do/while) würde zu
1
  if(condition)
2
    { a=1; b=2; };
3
  else
4
    sonstwas();
expandieren (man beachte das Semikolon hinter der gechweiften Klammer). 
Das geht so nicht, da der Anweisung { a=1; b=2; } nicht sofort das else 
folgt, sondern eine leere Anweisung (;), die nicht dem if zugehörig 
betrachtet wird. Das else für sich gesehen kann aber nicht der Anfang 
einer neuen Anweisung sein und führt deswegen zum Syntax-Fehler.

Die do/while-Methode ist die einzige Möglichkeit, mehrere Anweisungen 
per #define zu einem Makro zusammenzufassen, das sich in beliebigen 
Kontexten syntaktisch wie ein Funktionsaufruf verwenden lässt.

von Falk (Gast)


Lesenswert?

@ yalu

>Die do/while-Methode ist die einzige Möglichkeit, mehrere Anweisungen
>per #define zu einem Makro zusammenzufassen, das sich in beliebigen
>Kontexten syntaktisch wie ein Funktionsaufruf verwenden lässt.

Soviel zum Thema C und seine kryptische Syntax . . . :-(
Trotzdem Danke.

MfG
Falk


von Falk (Gast)


Lesenswert?

Ähhh Moment,

Wer sagt denn, dass ich hinter das Macro ein Semikolon schreiben muss?

#define DOBOTH { a=1; b=2; }

Dann funktionieren auch Anweisungen wie

  if(condition)
    DOBOTH
  else
    sonstwas();

Das sollte doch passen, oder? Und wie siehts jetzt aus, wenn ich dem 
macro Argumente übergeben will?

MfG
Falk

von Walter (Gast)


Lesenswert?

>Das sollte doch passen, oder? Und wie siehts jetzt aus, wenn ich dem
>macro Argumente übergeben will?

ja klar, das passt
unt mit Parametern schauts auch nicht anders aus, man darf nur hunter 
dem Makro kein Semikolon machen

das kryptische kommt hier nicht von C an sich, sondern durch den 
Präprozessor

von Falk (Gast)


Lesenswert?

@ Walter

>ja klar, das passt
>unt mit Parametern schauts auch nicht anders aus, man darf nur hunter
>dem Makro kein Semikolon machen

Ja eben, so hatte ich es auch in Erinnerung. Also ist doch kein 
Würg-Around mit do/while nötig.

>das kryptische kommt hier nicht von C an sich, sondern durch den
>Präprozessor

Kann man aber schlecht in der Praxis trennen.

MFG
Falk


von Christoph _. (chris)


Lesenswert?

@Falk:

> Die do/while-Methode ist die einzige Möglichkeit, mehrere Anweisungen
> per #define zu einem Makro zusammenzufassen, das sich in beliebigen
> Kontexten syntaktisch wie ein Funktionsaufruf verwenden lässt.

Der Schwerpunkt lag darauf, dass sich das Makro syntaktisch wie ein 
Funktionsaufruf verwenden lässt. Wenn man das Makro nur ohne folgendes 
Semikolon in jedem Kontext sicher aufrufen kann, ist das ziemlich 
ungewohnt und daher fehleranfällig.

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.