cancel
Showing results for 
Search instead for 
Did you mean: 

Confusion about Pin Numbering (Nucleo-L432KC Arduino Headers)

DSebastian
Associate II

Dear community,

first of all: I'm new to using STM32 controllers. 

I did some quite complex project using Arduino (consisting of Arduino Nano Every (ATMega4809) and a custom board using ATMega328P), but for my next project I consider switching to STM32 due to higher need for SRAM. So, I begin with simple blink-application to learn.

Board used: Nucleo-L432KC

IDE: STM32CubeIDE, STM32CubeMX

OS: Win 11

LED that shall blink: LD3 (the green one)

So far, code is working, but with unexpected GPIO_PIN_3.

I did some search here in the forum related to my question, but no sucess. Consulting documentation was also not helping at the end:

With reference to User Manual UM1956 Rev 6, Table 16 on page 30, and schematic on page 33 (of Rev 5!, Rev 6 does not show the schematic), the green LED LD3 is connected to pin PB3 of STM32L432KC. In Table 16 of UM1956 the pin number is given for PB3 as 15.

So, I would have expected to toggle the pin by using:

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_15);

but instead I have to use

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);

which matches the define given in main.h to

#define LD3_Pin GPIO_PIN_3

that also matches corresponding lines in MX_GPIO_Init below (created by STM32CubeMX)

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA8 */
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : LD3_Pin */
  GPIO_InitStruct.Pin = LD3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD3_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

Why is that? The Manual UM1956 is not giving any hint that LD3 is connected to GPIO_PIN_3 but to Pin 15.
Unfortunately I was not sucessful in finding a table on how the various Pins PA0, PA1, ... etc are mapped on GPIO_PIN_x with x = 0..15. So my question is: where can I find such a table? Am I reading the manual UM1956 in the wrong way?

Your support is appreciated.

Regards

Sebastian

1 ACCEPTED SOLUTION

Accepted Solutions
Andrew Neil
Super User

@DSebastian wrote:

the green LED LD3 is connected to pin PB3 of STM32L432KC.


You are confusing the the pin on the microcontroller itself with the name that Arduino gives to the pin in its standard UNO header layout

"PB3" identifies the pin on the MCU itself  - it means Pin 3 in GPIO port B.  So:

  • GPIO_PIN_3 is the pin number on the MCU itself;
  • GPIOB identifies the GPIO port on the MCU itself.

The microcontroller neither knows nor cares anything about what board it is mounted on; it just knows its own Ports & Pins - so your software has to use the Microcontroller Port name & pin number.

 

"D13", on the other hand, refers to the pin in the standard Arduino UNO header layout:

AndrewNeil_0-1764929169136.png

This header pin is always called "D13" on any Arduino (or Arduino-compatible) board - irrespective of what microcontroller is used.

On the good ol' original Arduino Uno, the header pin "D13" connects to "PB5" on the ATmega microcontroller:

AndrewNeil_1-1764929378522.png

https://deepbluembedded.com/arduino-uno-pinout/

 

When you write an Arduino "sketch", the digitalWrite() and digitalRead() functions perform the translation from header pin name to the actual microcontroller port & pin.

(This is why Arduino IO using digitalWrite() and digitalRead() is often criticised as being very slow)

 

You could, if you wished, write yourself some functions to do the same thing.

 

Or use the Arduino Core for STM32: https://github.com/stm32duino

https://www.stm32duino.com/

 

Or, you could use macros to help with the translation:

#define ARDUINO_D13_PORT GPIOB
#define ARDUINO_D13_PIN  GPIO_PIN_3

HAL_GPIO_TogglePin( ARDUINO_D13_PORT, ARDUINO_D13_PIN  );

 

Although, if it's the LED you want, it would be better to do something like:

#define LED_PORT GPIOB
#define LED_PIN  GPIO_PIN_3

HAL_GPIO_TogglePin( LED_PORT, LED_PIN );

to make the intent clear.

 

PS:

 


@DSebastian wrote:

I did some quite complex project using ... Arduino Nano Every (ATMega4809) 


So, on that, the "D13" header pin connects to "PE2" on the ATMega4809 microcontroller:

AndrewNeil_2-1764930553159.png

https://docs.arduino.cc/hardware/nano-every/

 

#ArduinoPins #ArduinoPinNames #ArduinoPinNumbers

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

10 REPLIES 10
TDK
Super User

The table lists three different references to the pin.

  • 15: pin number 15 on connector CN4.
  • D13: pin D13 on the Arduino Nano connector standard.
  • PB3: pin PB13 on the MCU.

TDK_4-1764894398555.png

TDK_2-1764894091836.png

 

When using HAL functions, you need to pass MCU pin numbers. It doesn't know anything about other connectors. This is in contrast to the Arduino IDE, which does use these.

If you're using the arduino IDE, there will be a board file which maps PB3 to D13.

 

Here's a reference for the Arduino Nano connector (ignore MCU numbers on this)

TDK_3-1764894207650.png

If you feel a post has answered your question, please click "Accept as Solution".

Should be a variant file with a table associating the Arduino pin# with the STM32 GPIO, ie bank and pin within the bank. ie D13 mapping to PB3

You can also find a schematic under the "CAD Resources" tab of the product page.

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

@DSebastian wrote:

the green LED LD3 is connected to pin PB3 of STM32L432KC.


You are confusing the the pin on the microcontroller itself with the name that Arduino gives to the pin in its standard UNO header layout

"PB3" identifies the pin on the MCU itself  - it means Pin 3 in GPIO port B.  So:

  • GPIO_PIN_3 is the pin number on the MCU itself;
  • GPIOB identifies the GPIO port on the MCU itself.

The microcontroller neither knows nor cares anything about what board it is mounted on; it just knows its own Ports & Pins - so your software has to use the Microcontroller Port name & pin number.

 

"D13", on the other hand, refers to the pin in the standard Arduino UNO header layout:

AndrewNeil_0-1764929169136.png

This header pin is always called "D13" on any Arduino (or Arduino-compatible) board - irrespective of what microcontroller is used.

On the good ol' original Arduino Uno, the header pin "D13" connects to "PB5" on the ATmega microcontroller:

AndrewNeil_1-1764929378522.png

https://deepbluembedded.com/arduino-uno-pinout/

 

When you write an Arduino "sketch", the digitalWrite() and digitalRead() functions perform the translation from header pin name to the actual microcontroller port & pin.

(This is why Arduino IO using digitalWrite() and digitalRead() is often criticised as being very slow)

 

You could, if you wished, write yourself some functions to do the same thing.

 

Or use the Arduino Core for STM32: https://github.com/stm32duino

https://www.stm32duino.com/

 

Or, you could use macros to help with the translation:

#define ARDUINO_D13_PORT GPIOB
#define ARDUINO_D13_PIN  GPIO_PIN_3

HAL_GPIO_TogglePin( ARDUINO_D13_PORT, ARDUINO_D13_PIN  );

 

Although, if it's the LED you want, it would be better to do something like:

#define LED_PORT GPIOB
#define LED_PIN  GPIO_PIN_3

HAL_GPIO_TogglePin( LED_PORT, LED_PIN );

to make the intent clear.

 

PS:

 


@DSebastian wrote:

I did some quite complex project using ... Arduino Nano Every (ATMega4809) 


So, on that, the "D13" header pin connects to "PE2" on the ATMega4809 microcontroller:

AndrewNeil_2-1764930553159.png

https://docs.arduino.cc/hardware/nano-every/

 

#ArduinoPins #ArduinoPinNames #ArduinoPinNumbers

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.
DSebastian
Associate II

Hi,

thanks for your responses.

So, first:

  • agreed, the table of UM1956 is refering to header pin numbers of the Nucleo-Board, CN3 amd CN4. I have taken those wrongly as GPIO_Pin numbers.
  • "Pin Name" is refered to Arduino pin names. Fine, but I'm using STM32CubeIDE, which is requesting GPIO_PIN_x (x = 0..15), so things like D1 (Arduino pin name) or PA9 (STM32 pin) are not working

So, I think, two columns are missing in the table, ohhh, wait.... while creating the picture to explain I probably found the answer (so no picture to add here): Is it such that, e.g.

  • PB3 translates to GPIOB and GPIO_PIN_3, say, for HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3)
  • PA4 translates to GPIOA and GPIO_PIN_4, say, for HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4)
  • PA11 translates to GPIOA and GPIO_PIN_11, say, for HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_11)

Is this translation correct? If so, this is I'm looking for.

Regards

Sebastian

Andrew wrote (don't know how citation works here):

-->

PB3" identifies the pin on the MCU itself  - it means Pin 3 in GPIO port B.  So:

  • GPIO_PIN_3 is the pin number on the MCU itself;
  • GPIOB identifies the GPIO port on the MCU itself.

<--

Sorry, so in other words what I just wrote above, right?


@DSebastian wrote:

(don't know how citation works here):


Use this button: AndrewNeil_0-1764933494290.png

 


@DSebastian wrote:

Sorry, so in other words what I just wrote above, right?


Yes - just explaining why that is the case.

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.

@Andrew Neil wrote:

Use this button: 

 


@DSebastian wrote:

Sorry, so in other words what I just wrote above, right?


Yes - just explaining why that is the case.


Thanks.

So, e.g., PB3 translates to GPIOB and GPIO_PIN_3.


@DSebastian wrote:

So, e.g., PB3 translates to GPIOB and GPIO_PIN_3.


Exactly.

Just as for the ATMega328P (eg, PB5)  and .ATMega4809 (eg, PE2).

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.

@TDK wrote:

The table lists three different references to the pin.

  • 15: pin number 15 on connector CN4.
  • D13: pin D13 on the Arduino Nano connector standard.
  • PB3: pin PB13 on the MCU.

@DSebastian Although not shown in that table, there is also another "pin number" involved:  that's the number of the physical pin on the microcontroller's 32-pin LQFP (or UFQFPN) package - in this case, it's pin 26:

AndrewNeil_0-1764947134670.png AndrewNeil_0-1764947720121.png

 

 

But, again, the executing code knows nothing of this external hardware detail - all it sees the the Port (GPIOB), and the pin number within that port (3).

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.