Skip to main content
December 4, 2025
Solved

Confusion about Pin Numbering (Nucleo-L432KC Arduino Headers)

  • December 4, 2025
  • 5 replies
  • 298 views

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

    This topic has been closed for replies.
    Best answer by Andrew Neil

    @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

    5 replies

    Super User
    December 5, 2025

    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

    Super User
    December 5, 2025

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

    Graduate II
    December 5, 2025

    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.

    Super User
    December 5, 2025

    @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

    December 5, 2025

    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?

    Super User
    December 5, 2025

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

    December 5, 2025

    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

    December 12, 2025

    Yes, I have a printed schematic of my Nucleo-BoardL432 lying on my desk. Just to make check if tutorials, tipps given for other boards have to be adapted to my board.