cancel
Showing results for 
Search instead for 
Did you mean: 

Array for GPIO pins

Huzo
Associate III

Hello,

 

I am new to STM world.

I am trying to make an array of GPIO pin in this format {{PIN1_GPIO_PORT, PIN1_PIN}.....

This would then be used in custom function so I can dynamically access this pins.

How should I declare such array and how would i use them with HAL_GPIO_WRITEPIN function.

Main use of this is to select SPI slave to communicate with.

 

Thanks in advance

 

1 ACCEPTED SOLUTION

Accepted Solutions

@Huzo wrote:

I am new to STM world.


Do you have any experience with any other microcontrollers?

Do you have any experience with programming in general? With C programming?

 


@Huzo wrote:

I am trying to make an array of GPIO pin in this format {{PIN1_GPIO_PORT, PIN1_PIN}.....


I would have a struct for the {port,pin} pair, and then make an array of those structs ...

As you want to use it with HAL_GPIO_WritePin, make the types compatible with what that function requires:

 

 

 

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

 

 

 

So you'd have something like

 

 

 

typedef struct { GPIO_TypeDef* GPIOx; uint16_t GPIO_Pin; } port_and_pin_t; port_and_pin_t ports_and_pins[length]; : : HAL_GPIO_WritePin( ports_and_pins[x].GPIOx, ports_and_pins[x].GPIO_Pin, value );

 

 

 

You might want to make a "wrapper" function which just takes the struct, breaks-out the 2 elements, and passes them to HAL_GPIO_WritePin ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

View solution in original post

16 REPLIES 16
gbm
Principal

<deleted - the right answer was posted below>

 

struct pin_ {
    GPIO_TypeDef *port;
    uint16_t pinmask;
};

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Create a structure, array the structure. More C than STM32

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Huzo wrote:

I am new to STM world.


Do you have any experience with any other microcontrollers?

Do you have any experience with programming in general? With C programming?

 


@Huzo wrote:

I am trying to make an array of GPIO pin in this format {{PIN1_GPIO_PORT, PIN1_PIN}.....


I would have a struct for the {port,pin} pair, and then make an array of those structs ...

As you want to use it with HAL_GPIO_WritePin, make the types compatible with what that function requires:

 

 

 

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

 

 

 

So you'd have something like

 

 

 

typedef struct { GPIO_TypeDef* GPIOx; uint16_t GPIO_Pin; } port_and_pin_t; port_and_pin_t ports_and_pins[length]; : : HAL_GPIO_WritePin( ports_and_pins[x].GPIOx, ports_and_pins[x].GPIO_Pin, value );

 

 

 

You might want to make a "wrapper" function which just takes the struct, breaks-out the 2 elements, and passes them to HAL_GPIO_WritePin ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Note that the GPIO_Pin parameter of HAL_GPIO_WritePin is a bitmask - not a pin number ...

 

 

/** @defgroup GPIO_pins GPIO pins * @{ */ #define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */ #define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */ #define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */ #define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */ #define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */ #define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */ #define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */ #define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */ #define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */ #define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */ #define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */ #define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */ #define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */ #define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */ #define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */ #define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */ #define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */

 

 

EDIT

As @gbm suggested, calling the member of your struct something like "pinmask" would help.

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

I have some experience with AVR and C programming. I was also thinking about structures but I am not fond of them.

So new structure would use definitions for pins as setup by STM32CUDEide. I have added comments to your code snippet.

typedef struct { GPIO_TypeDef* GPIOx; // example PIN1_GPIO_PORT uint16_t GPIO_Pin; // example PIN1_PIN } port_and_pin_t; port_and_pin_t ports_and_pins[length]; : : HAL_GPIO_WritePin( ports_and_pins[x].GPIOx, ports_and_pins[x].GPIO_Pin, value );

To be honest right now I am using nested switch case to make changes to 2 SPI chips (I/O expanders). I would need to scale this up to 12 or even 15 of them so nested switch case would be crazy long.

 


@gbm wrote:

<deleted - the right answer was posted below>


For one thing, I think your choice of "pinmask" as the name for the pin element is better than mine!

I always find the ST documentation very unclear on whether these HAL functions expect a pin mask or a pin number.

:frowning_face:

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

There is no perfect documentation. I will try to make the structure and use without my function, for testing purposes, and will come here with a reply. Thanks.


@Huzo wrote:

 I was also thinking about structures but I am not fond of them.


Why not?

They are exactly the language solution for this type of problem - collecting together items of differing types.

 

EDIT

If you really can't stand structs, you could just have 2 separate arrays - one array holding ports, and the other holding pins; eg,

GPIO_TypeDef* ports [size]; // example PIN1_GPIO_PORT uint16_t pinmaps[size]; // example PIN1_PIN : : HAL_GPIO_WritePin( ports[x], pinmaps[x], value );

 

 But then you lose the inherent benefit of structs in keeping the pin and its associated port together.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

With arrays it works as intended. So next stop is with a structure. If that works than I will go to structured array and to function. That should lower the complexity of the code. The structure would consist of 5 (or more) variables Number of MCP (1st, 2nd..) Ports, pins and  PORTA and PORTB (IO expander port register).