www.mikrocontroller.net

Forum: Compiler & IDEs #define


Autor: Miks (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: TT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
ich denke du suchst sowas hier:

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

oder?

MFG

TT

Autor: Miks (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#define DOBOTH() a=1; b=2;

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

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

Dann funktionieren auch Anweisungen wie
  if(condition)
    DOBOTH();
  else
    sonstwas();

korrekt. Das do/while wird vom Compiler wegoptimiert.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
  if(condition)
    { a=1; b=2; };
  else
    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.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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


Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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


Autor: Christoph __ (chris)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.