uint8_t outSet(volatile uint8_t *port, uint8_t pin, uint8_t level) {
Außerdem:
if (*port == PORTA) { *DDR = DDRA; }
->
if (port == &PORTA) { DDR = &DDRA; }
Aber wozu das, du verwendest DDR doch gar nicht?
Hallo,
wie kann ich die Adresse eines Registers an eine Funktion übergeben?
Aufruf: outSet(&PORTA,3,1);Code:uint8_t outSet(uint8_t *port, uint8_t pin, uint8_t level) { uint8_t *DDR = 0; if (*port == PORTA) { *DDR = DDRA; } if (*port == PORTB) { *DDR = DDRB; } if (*port == PORTC) { *DDR = DDRC; } if (*port == PORTD) { *DDR = DDRD; } asm("nop"); if (level) { *port |= (pin << *port); } else { *port &= ~(pin << *port); } return level; }
Nur der Compiler meldet: ../main.c:84: warning: passing argument 1 of 'outSet' discards qualifiers from pointer target type
Was mache ich falsch?
Gruß
uint8_t outSet(volatile uint8_t *port, uint8_t pin, uint8_t level) {
Außerdem:
if (*port == PORTA) { *DDR = DDRA; }
->
if (port == &PORTA) { DDR = &DDRA; }
Aber wozu das, du verwendest DDR doch gar nicht?
MfG
Stefan
Diese Warnung bringt er gerne, wenn man mit Pointer arbeitet, das sagt garnix.
Übrigens: es ist nicht notwendig, aus den Pointer das DDRx Register zu ermitteln: Alle IO Register haben die gleiche struktur
Eventuell mit ausreichend "volatile"s beflasternCode:typedef struct { uint_8_t Pin; // in uint_8_t Ddr; // control uint_8_t Port; // out } IO_REG; // Aufruf outSet((IO_REG*)&Pinb, 3, 1 ) uint8_t outSet(IO_REG* port, uint8_t pin, uint8_t level) { port->Ddr |= (1 << pin); // DDR auf Output if (level) port->Port |= (1 << pin); // Port.pin = 1 else port->Port &= ~(1 << pin); // Port.pin = 0 return level; }
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Das sagt in diesem Fall, dass das Ziel vom Zeiger port in der Funktion nicht mehr volatile ist, und das ist alles andere als "garnix".Zitat von PicNick
MfG
Stefan
Du weißt das vielleicht, weil Du Dich auskennst. Aber mir, PicNick und dem Topic-Eröffner sagte diese Meldung offensichtlich "garnix".
Es besteht aber ein wichtiger Unterschied zwischen "das sagt garnix" und "das sagt mir garnix". PicNick sagt mit dem Satz, dass die Warnung quasi keine Bedeutung hat und einfach ignoriert werden sollte, und das ist ein ziemlich schlechter Rat.Zitat von thewulf00
MfG
Stefan
@sternst: jetzt ist die Spannung der Laien am Höhepunkt:
sag' uns doch endlich, was genau passiert, wenn wir die Warnung ignorieren und das Programm einfach starten.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
In diesem konkreten Fall wohl nichts. Aber wenn du z.B. bei dieser Funktion diese Warnung ignorierst, hast du bei eingeschalteter Optimierung eine sehr gute Chance auf eine Endlosschleife (außer natürlich, das Register ist bei Betreten der Funktion schon null):Zitat von PicNick
Code:void WaitForZero ( uint8_t *port ) { while (*port); } ... WaitForZero(&PINC);
MfG
Stefan
Warnungen einfach zu ignorieren ist, so wie ich finde, generell eine sehr schlechte Angewohnheit. Es ist zwar so, dass oft nicht schlimmes passiert, wenn man es tut, manchmal (siehe sternst`s Beispiel) hat es aber unangenehme Fehler zur Folge, wo man unnötig lange nach einer Lösung sucht. Daher mein Rat: Immer den Code so schreiben, dass keine Warnungen mehr vorhanden sind!Zitat von PicNick
Hab mir mal PicNics Vorschlag näher angeschaut..
Über die Typendefinition hab ich automatisch DDR,PIN und PORT? Wenn ja wäre dies ja super.
Könnt ja nochmal über diesen code schauen. Compiliert mit 0 warnings. Noch nicht getestet.Code:typedef struct { uint8_t PIN; uint8_t DDR; uint8_t PORT; } IO_REG; uint8_t outSet(IO_REG* port, uint8_t pin, uint8_t level) { port->DDR |= (1 << pin); //DDR as output if (level) { port->PORT |= (1 << pin); } else { port->PORT &= ~(1 << pin); } return level; } uint8_t inGet(IO_REG* port, uint8_t pin, uint8_t pullup) { port->DDR &= ~(1 << pin); //DDR as input if (pullup) { port->PORT |= (1 << pin); } else { port->PORT &= ~(1 << pin); } if (port->PIN & (1 << pin)) { return 1; } else { return 0; } }
Gruß
Lesezeichen