Fragen PORTC, DDRC, PINC ..

Hallo Leute,

sind PORTC, DDRC, PINC (und Konsorten) Variablen -
kann ich sie als solche behandeln und zb als Parameter
einer Funktion übergeben ?

Viele Grüße

Harry

Jein. Die Namen der Register selbst zu übergeben ist etwas komplizierter als einfache Parameter:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass

Man muss eine Adresse übergeben (d.h. der Parameter ist ein Zeiger) und der muss als volatile deklariert sein:

void set_bits_func (volatile uint8_t* port, uint8_t mask)
{
   *port |= mask;
}

Und bei Aufruf braucht man dann entsprechend den adress-of Operator:

set_bits_func(&PORTB, 0x55);

Jein ist die perfekte Antwort.
Eine Alternative ist eine Referenz, dann sieht es etwas gefälliger aus, ist aber das Gleiche wie Serenifly's Vorschlag:

void set_bits_func ( volatile uint8_t& port, uint8_t bits)
{
  port |= bits;
}
   ...
    set_bits_func(PORTB, 0x55);

Das funktioniert nicht nur mit den avr-gcc Innereien wie PORTB, sondern mit jeder passenden Variablen.

Ausprobiert hast du das aber klar nicht :slight_smile:

error: invalid initialization of reference of type 'uint8_t& {aka unsigned char&}' from expression of type 'volatile uint8_t {aka volatile unsigned char}

Mit volatile kompiliert es und geht auch.

Die Register sind in den Innereien als volatile deklariert. Also kann man das nicht weglassen. Beim Zeiger genauso:

error: invalid conversion from 'volatile uint8_t* {aka volatile unsigned char*}' to 'uint8_t* {aka unsigned char*}'

Den Rückgabe-Wert habe ich übrigens vergessen. Aber das ist eine Nebensache

Ausprobiert hast du das aber klar nicht :slight_smile:

Erwischt!

Danke :wink:

Den Rückgabe-Wert habe ich übrigens vergessen

Da hätte ich dich auch ohne ausprobieren erwischen können, hab ich aber nicht :frowning:

Jetzt habt ihr mich verwirrt, welche Version geht denn nun durch den Compiler ?

Grüßle

Harry

Beides wenn du den Parameter für das Register als volatile deklarierst.

michael_x ist es auch ausgebessert