Forum: Compiler & IDEs Problem mit Makro


von Volker (Gast)


Lesenswert?

Hallo,

ich habe früher für 8051 Controller in C programmiert.
Bei diesem Compiler konnte ich folgendes machen:

#define heizung P11 // Portpin 1.1

Im Programm konnte ich dann mittels
heizung=1; bzw. heizung=0; den entsprechenden Pin auf 0 oder 1 setzen.

Da ich nun einige Programme auf den winavr portieren möchte gibts damit
ein Problem.

Wollte mir nun ein Makro basteln, damit ich nichts umschreiben muß.
Aber egal wie ich es versuchte, gab es immer ein Problem mit dem
"=".

Hab mir jetzt folgendermaßen geholfen:

#define PDOUT(x,wert) if (wert==1) {sbi(PORTD,x);}else {cbi(PORTD,x);}




#define heizung_an PDOUT(5,1)
#define heizung_aus PDOUT(5,0)


somit kann ich im Programm nun schreiben

heizung_an; bzw. heizung_aus;

aber das ist nicht so ganz das was ich möchte

Kann sein, dass sbi, cbi mittlerweile abgekündigt sind, aber darum
gehts mir hier nicht.

Wie kann ich ein Makro schreiben, dass ich im Programm einfach
heizung=1; heizung=0;
schreiben kann, also in meinen alten Programmen nichts umändern muß?

Bin über Hilfe sehr dankbar.

Volker

von peter dannegger (Gast)


Lesenswert?

Das geht nicht unter WINAVR.

Du kannst höchstens eine Variable "heizung" definieren und dann in
die main loop schreiben:

if( heizung )
  PORTD |= 1<<PD5;
else
  PORTD &= ~(1<<PD5);

Oder in einen Timerinterrupt, d.h. irgendwas, was ständig durchlaufen
wird.


Peter

von Christof Krüger (Gast)


Lesenswert?

Erstmal: Ja, cbi und sbi sind deprecated und sind in den neueren Version
wohl auch nicht mehr dabei.

Es gibt eine Möglichkeit, die ist aber extrem hässlich.

Aber wenn es unbedingt sein muss, hier mein kleines Test-Programm:

------------------------------------


struct test {
  int b1:1;
  int b2:1;
  int b3:1;
  int b4:1;
  int b5:1;
  int b6:1;
  int b7:1;
  int b8:1;
} __attribute__((_packed_));

#define BIT4 ((struct test*)&bla)->b4
#define BIT5 ((struct test*)&bla)->b5

int
main(void)
{
  short int bla = 0;

  BIT4=1;
  BIT5=1;

  printf("bla = 0x%02x\n", bla);

  BIT4=0;
  printf("bla = 0x%02x\n", bla);

  return 0;
}

------------------------------------

Es gibt wie erwartet

bla = 0x18
bla = 0x10

aus.

von Volker (Gast)


Lesenswert?

Danke für die Antworten,

@Peter
eigentlich eine gute Idee, hat aber leider den Nachteil,
daß die Ausgabe dann etwas zeitversetzt kommen kann (je nachdem wo der
Timer gerade steht und auf welchem Zeiraster er läuft). Wenn ich da nur
ans Timing eines DS18B20 denke...

@Christof
sieht gut aus, wenn es mir noch gelingt die Variable bla direkt mit
einem Ausgansport des AVR zu verheiraten dann gehts, werd ich mal
versuchen.

Naiv wie ich war hab ich es auch mal so versucht

#define heizung=0  (PORTD |= 1<<PD5;)
#define heizung=1  (PORTD &= ~(1<<PD5);)

aber das schluckt halt der Compiler nicht (kommt halt mit der Zuweisung
im define nicht klar), na ja ein Versuch wars wert.
Hab mir auch schon überlegt, ob es evt. noch Sonderzeichen zum kapseln
von "heizung=0" gibt.

nochmals vielen Dank

Volker

von Matthias (Gast)


Lesenswert?

Hi

Vorschlag:

#define HEIZUNG_AUS PORTD |= 1<<PD5
#define HEIZUNG_EIN PORTD &= ~(1<<PD5)

und dann ein

sed /s/heizung=1/HEIZUNG_EIN/
und
sed /s/heizung=0/HEIZUNG_AUS/

auf alle deine umzustellenden Dateien.

Matthias

von Volker (Gast)


Lesenswert?

Danke Matthias,

denke ich werds wirklich so machen, wird eh Zeit sich von
Compilerspezifischem Syntax weitestgehend zu verabschieden.
Am besten nur reines Ansi-C


Gruß Volker

von Christof Krüger (Gast)


Lesenswert?

Würde dir zwar auch raten, auf standard-c umzurüsten, es sollte aber
dennoch klappen, wenn du das Makro z.B. so schreibst:

#define PORTB_BIT4 ((struct test*)&PORTB)->b4
#define PORTB_BIT5 ((struct test*)&PORTB)->b5

und dann z.b.

PORTB_BIT4 = 1;

schreibst

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.