- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: Register an Funktion übergeben

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360

    Register an Funktion übergeben

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    wie kann ich die Adresse eines Registers an eine Funktion übergeben?

    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;
    }
    Aufruf: outSet(&PORTA,3,1);

    Nur der Compiler meldet: ../main.c:84: warning: passing argument 1 of 'outSet' discards qualifiers from pointer target type


    Was mache ich falsch?
    Gruß

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    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

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    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
    Code:
    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;
    }
    Eventuell mit ausreichend "volatile"s beflastern
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von PicNick
    Diese Warnung bringt er gerne, wenn man mit Pointer arbeitet, das sagt garnix.
    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".
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Du weißt das vielleicht, weil Du Dich auskennst. Aber mir, PicNick und dem Topic-Eröffner sagte diese Meldung offensichtlich "garnix".

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von thewulf00
    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.
    MfG
    Stefan

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    @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.

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von PicNick
    sag' uns doch endlich, was genau passiert, wenn wir die Warnung ignorieren und das Programm einfach starten.
    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):

    Code:
    void WaitForZero ( uint8_t *port ) {
        while (*port);
    }
    
    ...
    
    WaitForZero(&PINC);
    MfG
    Stefan

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.11.2004
    Ort
    Aachen
    Alter
    38
    Beiträge
    246
    Zitat Zitat von PicNick
    [...] was genau passiert, wenn wir die Warnung ignorieren und das Programm einfach starten.
    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!

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.06.2005
    Ort
    Göppingen
    Beiträge
    360
    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.
    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;
    	}
    }
    Könnt ja nochmal über diesen code schauen. Compiliert mit 0 warnings. Noch nicht getestet.

    Gruß

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus