Home > database >  Neat/compact C code for working with multiple GPIO ports on a microcontroller
Neat/compact C code for working with multiple GPIO ports on a microcontroller

Time:12-29

I'm writing a program where I need to control many output pins on my Atmega4809. How can I work with these without having to write duplicate code (using loops and arrays for example)?

Instead of doing this...

PORTA.OUT |= (1 << PIN2);
PORTB.OUT |= (1 << PIN4);
PORTC.OUT |= (1 << PIN1);
PORTD.OUT |= (1 << PIN3);

.. I want to do something like this

for (int i = 0; i < 4; i  ) {
    myPorts[i].OUT |= (1 << myPins[i];
}

I tried to #define all the ports and pins, and putting them in arrays like this: (for context the output pins are connected to rows and columns of an LED_matrix)

#define COL0_PORT PORTF
#define COL1_PORT PORTD
#define COL2_PORT PORTA
#define COL3_PORT PORTB

PORT_t col_ports[] = {COL0_PORT, COL1_PORT, COL2_PORT, COL3_PORT};

When building, I get "initializer element is not constant".

CodePudding user response:

Assuming that variables like PORTA have type PORT_t, then you can store pointers to them in an array using this syntax:

PORT_t * col_ports[] = { &PORTA, &PORTA, &PORTF, &PORTB };

You might try putting the const keyword right before col_ports as well; that might move the array to flash, thus saving you some RAM space.

CodePudding user response:

Assuming 8 bit MCU with 16 bit register map, then your ports will be defined in a register map along the lines of this:

#define PORTA (*(volatile uint8_t*)0x1234u)

Why is explained here: How to access a hardware register from firmware?

You will want an array of volatile uint8_t* pointers: volatile uint8_t* col_ports[]. However, you most likely also want this array to be allocated in flash not RAM, therefore add const after the *, to make the array itself read-only:

volatile uint8_t* const col_ports[] =
{
  &PORTA,
  &PORTB,
  &PORTC
};

There might also be various memory mapping hiccups related to the old AVR Harvard architecture, so you might have to add PROGMEM after the const, or similar compiler-specific non-standard keywords.

  • Related