Hallo,
ich bin noch relativer Anfänger und habe eine Frage:
Folgendes sollte funktionieren:
Am Anfang des Programms:
#define Ausgabeport1 PortB
#define Ausgabeport2 PortC
#define GLUE(a, b) a##b
#define PORT(x) GLUE(PORT, x)
#define SET(bit) Ausgabeport1 |= _BV(bit))
#define RESET(bit) Ausgabeport1 &= ~_BV(bit)
#define OUT_RESET 4
#define OUT_Start 5
Irgendwo im Programm:
SET(OUT_RESET)
RESET(OUT_RESET)
SET(OUT_START)
SET und RESET setzen also das definierte Bit in PortB.
Nun die Frage: Wie kann ich die Definition für den Präprozessor so
abändern, dass durch Nutzung der definierten Port-Bits wie z.B.
OUT_START auch der Port (Ausgabeport1 oder Ausgabeport2) vorab definiert
werden kann?
Beispiel: OUT_RESET soll also z.B. Port B4 sein
und OUT_START soll Port C5 sein.
Ich möchte aber trotzdem eine Routine Set / Reset haben. D.h mit SET
(OUT_START) wird C5 gesetzt und mit SET(OUT_RESET) wird B4 gesetzt. Ich
komme hier nicht weiter. Danke für die Hilfe
Oh, die drei Fragezeichen sind auch hier :-)
Das ging ja fix.
Danke für die Hilfe. Das hilft mir schon mal weiter. Ich vermute also,
dass es nicht möglich mittels #define OUT_RESET .... direkt den Port
zuzuweisen, so dass ein einfaches
SET(OUT_RESET) für PortB.4 und ein
SET(OUT_START) für Port C.5 reicht?
Danke nochmals
> #define SET(...) SET_(_VA_ARGS_)> #define RESET(...) RESET_(_VA_ARGS_)
Jetzt bin ich verblüfft.
Das geht ?!?
Ist das Standard oder eine gcc Erweiterung?
#define OUT_RESET B,4
Mit derselben Idee habe ich auch rumgespielt, bin aber an der
falschen Makro Auswertereihenfolge gescheitert.
Karl heinz Buchegger wrote:
> Ist das Standard oder eine gcc Erweiterung?
C99, wobei's der GCC auch im gnu89-Mode (das ist der Default) bereits
kennt.
_VA_ARGS_ löst insbesondere endlich den gordischen Knoten mit den
Debug-printf()s. Man möchte sie verwenden wie printf() (also mit
variabler Argumentliste), aber sie sollen so als Makro implementiert
sein, dass sie im Nicht-Debug-Code zu rein gar nichts evaluieren.
Das ging im C90 gar nicht. Im C99 geht es als:
p.s.: Der Trick hier ist allerdings nur die doppelte Auswertung durch
den Präprozessor, ... und _VA_ARGS_ braucht man nicht unbedingt
dafür. Das hier geht auch, und ist plain ISO C90 compliant:
1
#define OUT_RESET B,4
2
#define OUT_START C,5
3
4
#define GLUE(a, b) a##b
5
#define PORT(x) GLUE(PORT,x)
6
7
#define SET_(p, b) PORT(p) |= (1 << (b))
8
#define RESET_(p, b) PORT(p) &= ~(1 << (b))
9
#define SET(x) SET_(x)
10
#define RESET(x) RESET_(x)
11
12
#include<avr/io.h>
13
14
void
15
foo(void)
16
{
17
SET(OUT_RESET);
18
RESET(OUT_START);
19
SET(OUT_START);
20
}
Ich hatte die __VA_ARGS__-Variante halt nur zuerst ausprobiert.