Forum: Compiler & IDEs Port als Parameterübergabe


von Timelimelim (Gast)


Lesenswert?

Ich möchte gerne eine funktion schreiben, die mir an einem beliebigen
Port einen beliebigen Pin invertiert. Meine Idee hierzu ist:

void invert_pin (uint8_t * PINX, uint8_t * PORTX, uint8_t pin) {
 if (*PINX & (1 << pin))
  *PORTX &= ~(1 << pin);
 else
  *PORTX |= (1 << pin);
}

Doch leider entsteht beim Compilieren immer die Warnung

warning: passing arg 1 of `invert_pin' discards qualifiers from
pointer target type
warning: passing arg 2 of `invert_pin' discards qualifiers from
pointer target type

wenn ich die Funktion mit

invert_pin (&PIND, &PORTD, 0);

aufrufe. Von welchem Typ sind denn die Ports und neben bei gefragt:
Kann ich das Invertieren nicht auch mit dem ~ - Operator realisieren.
Das hat bei mir aber nur geklappt, wenn ich einen kompletten Port
invertieren wollte.

Wie hängen eigentlich PinD und PortD zusammen? Kann man es irgendwie
erreichen, dass nur ein Parameter dafür nötig ist. So ist es doch
irgendwie doppelt gemoppelt.

von Hubert.G (Gast)


Lesenswert?

Vieleicht solltest du das einmal lesen:
www.mikrocontroller.net/articles/AVR-GCC-Tutorial#I.2FO-Register
Ich denke das erklärt den Unterschied zwischen PinD und PortD

von Timelimelim (Gast)


Lesenswert?

Ich kenne den Unterschied zwischen PIN und PORT. Meine Frage war, ob es
in C eine möglichkeit gibt bei der Übergabe eines Ports, der sich aus
den Registern DDRX, PINX und PORTX zusammensetzt, aus einem Parameter
auf die beiden anderen (ich benötige aber nur PORTX und PINX) zu
schließen OHNE sie einzelt, explizit zu nennen. Verstehst du meine
Frage? Aber das ist ja auch gar nicht mein eigentliches Problem (lese
Betreff).

von Chris (Gast)


Lesenswert?

Die Parameter müssen auf ein volatile-Objekt zeigen (dieser
"Qualifier" wird bei dir unterschlagen).

von Jörg Wunsch (Gast)


Lesenswert?

Jein.  Du kannst natürlich annehmen, dass Atmel sein Portlayout nie
ändert und daraufhin eine Beziehung zwischen DDRx, PINx und PORTx
aufbauen.  Auf der wirklich sicheren Seite bist du allerdings damit
nicht.

von Lanius (Gast)


Lesenswert?

warum nicht mit Macros?

#define setBit(x,y)    ((x) |=  (y))
#define clearBit(x,y)   ((x) &= ~(y))
#define toggleBit(x,y)   ((x) ^=  (y))

wenn du dann noch:

#define BIT0 0x01
#define BIT1 usw..

hast, dann schreibe einfach:

setBit(P2OUT,BIT1);
clearBit(P1DIR,BIT3);

oder

toggleBit(P3IN,BIT4);  //invertieren

von Lanius (Gast)


Lesenswert?

toggleBit(P3IN,BIT4);  //invertieren

... P3IN ist natärlich ein bloedes Beispiel :)

von Timelimelim (Gast)


Lesenswert?

Vielen Dank für eure rasche Hilfe. Der Tip mit dem volatile-Objekt hat
den Fehler beseitigt. Die Möglichkeit mit Macros zu arbeiten kannte ich
bis gerade gar nicht. Werde da gleich mal ein wenig mit herumspielen.
Kennst du vielleicht eine kleine Doku über Macros, dir mir noch ein
bißchen mehr zeigen kann???

von Timelimelim (Gast)


Lesenswert?

Das mit den Macros hat sich schon erledigt. Mir ist das Licht
aufgegangen. g

von Lanius (Gast)


Lesenswert?

Das schöne an den Macros ist das die der Compiler schon erledigt, der MC
hat dadurch keine zusätzliche Arbeit. Wenn du dafür eine Funktion
schreibst hast du zusätzlichen Code.

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.