How to address Port names (PORTB etc) in an array (solved)

Is it possible to put the names of ports in an array?

I'm looking something like:

const ??? my_ports_config[8]= { PORTB, PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTD };

So to do (direct register bit set):

my_ports_config[i] |= _BV(7);

Is it possible?

EDIT:

This solution worked fine (proposed by @Coding Badly)
byte volatile * const port_config[] = { &PORTD, &PORTB, &PORTB, &PORTD, &PORTB, &PORTB, &PORTB, &PORTD };

What happened when you tried?

.

const byte* PortConfigs[] = { PORTB, PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTD };
*PortConfigs[2] = _BV(7);

I guess :slight_smile:

Great thank you very much!

Port names are actually numbers like ints. So make your array by an array of ints. Then it should work I think.

@septillion answer compiles and uploads ok but does not work. I will try now @papaFred idea, i'm not really sure how to make it an integer array...

I tried this and doesn't work: (I think arduino hungs)

uint8_t port_config[8] = { PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTB, PORTD };

also tried

int port_config[8] = { PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTB, PORTD };

also tried

volatile byte* port_config[8] = { PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTB, PORTD };

and

volatile byte* port_config[] = { PORTD, PORTB, PORTB, PORTD, PORTB, PORTB, PORTB, PORTD };

unfortunately nothing worked. Arduno seems to hung after compile.

This works:

if( pulse[0] == 4095 && !oneStep[0]){ oneStep[0] = true; PORTD |= _BV(7); } else
 if( oneStep[0] && !pulse[0] ){ oneStep[0] = false; PORTD &= ~(_BV(7)); }

this doesn't: (compiles and uploads ok but arduino hangs, everything stops working)

if( pulse[0] == 4095 && !oneStep[0]){ oneStep[0] = true;  *port_config[0] |= _BV(7); } else
 if( oneStep[0] && !pulse[0] ){ oneStep[0] = false; *port_config[0] &= ~(_BV(7)); }

@Delta_G

I don't understand what you are saying. Try what without the array?

I managed to make it work by using the ternary operator:

( ( i == 0 || i == 3 || i == 7 ) ? PORTD : PORTB ) |= _BV( pins_config[i] );

Any ideas how to make it work from an array are still welcomed.

Thanks!

I tried this:

volatile byte* ports_config[] = {PORTD,PORTB};

now this compiles and uploads ok but does not work:

if( pulse == 4095 && !oneStep){ oneStep = true; ( ( i == 0 || i == 3 || i == 7 ) ? PORTD : ports_config[1] ) |= BV( pins_config ); }
(only PORTD works which is directly assigned)*_

You are right. I'm a bit tired now to test it right.

I tried also without the array like:

volatile byte* ports_config = PORTB;

But the compiler complained about the ternary: "needs lvalue".

I will try again tomorrow when I will be less tired.

Thanks for your help.

I don't have an AVR to try this. But, assuming an Uno, the address of PORTB is 0x25. So, this might work:

volatile uint8_t *myport = (volatile uint8_t *) 0x25;

and access it with:

*myport = *myport | _BV(7);

If this works, you can then move on to building your array. Get the addresses from the datasheet.

PORTa is essentially a reference Try this...

volatile byte* port_config[] = { &PORTD, &PORTB, &PORTB, &PORTD, &PORTB, &PORTB, &PORTB, &PORTD };

You are welcome.

For the fanatics...

byte volatile * const port_config[] = { &PORTD, &PORTB, &PORTB, &PORTD, &PORTB, &PORTB, &PORTB, &PORTD };

(Will also give the optimizer a leg up.)

Thanks people. @Coding Badly solution worked fine.

Regards,
John

Lot of replies when I was out. And yes, of course a address operator was needed, I forgot ::slight_smile:

Using an int would just be stupid... Call it what it is. And using the name is a lot easier to read (and port!) then 0x25...

I had considered the &PORTn notation, but wasn’t exactly sure how it would parse. As far as I can tell PORTB is a macro that resolves to:

*(volatile uint8_t *) 0x25

So, putting a ‘&’ in front results in:

&*(volatile uint8_t *) 0x25

I suppose you could say that the ‘&’ “cancels” the first ‘*’ leaving you with a pointer to the uint8_t stored in address 0x25.

It obviously works, but wondering if someone could explain exactly how it’s processed.