cancel
Showing results for 
Search instead for 
Did you mean: 

Array for GPIO pins

Huzo
Associate II

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
Andrew Neil
Evangelist

@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 ...

View solution in original post

16 REPLIES 16
gbm
Lead II

<deleted - the right answer was posted below>

 

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

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..
Andrew Neil
Evangelist

@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 ...

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.

 

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.

☹️

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.

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).