STM32F4 GPIO Configuration

EOS 5D Mark III-101-2124Here I will explain how to configure the general purpose input/output ports (GPIO) of the STM32F4xx micro controllers.  Like most other micro controllers the GPIO pins can have multiple configurations and mappings.

In this small tutorial, I’ll show the high level functions provided by the GPIO peripheral provided by CooCox.  In another post I will dig in the deeper, low level details by explaining the registers needed for configuring the GPIO ports on the STM32F4xx devices.

The CooCox GPIO peripheral is a great library for easy setup and understanding your micro controller. The GPIO_InitTypeDef is a structure defined in the ST’s library and it contains all the properties you can configure on the corresponding peripheral:

  • Speed
  • Mode
  • Type
  • Pull up/pull down resistors

The GPIO ports require a clock to operate, by default this clock is not connected to the peripheral and needs to be configured.  On the STM32F4xx the GPIO ports are connected to the AHB1 bus (the first out of 3 advanced high-performance buses). Enabling the clock:


The GPIO’s clock can be anything of the following:


  • GPIO_Speed_25MHz
  • GPIO_Speed_50MHz
  • GPIO_Speed_100MHz

On the STM32F4 the GPIO can have up to 4 modes (check the datasheet for which modes are available for which pin):

  • GPIO_Mode_OUT for digital output
  • GPIO_Mode_IN for digital input
  • GPIO_Mode_AN for analog input
  • GPIO_Mode_AF for the alternate functions (like SPI, I²C, USART, …)

The type indicates the hardware configuration of the pin which can be:

  • GPIO_OType_PP, a push-pull is driving the output
  • GPIO_OType_OD, the output is open-drain

Next we can configure pull up, pull down resistors or nothing at all for each pin:

  • GPIO_PuPd_NOPULL, no resistor connected
  • GPIO_PuPd_UP, pin is connected to a pull up resistor
  • GPIO_PuPd_DOWN, pin is connect to a pull down resistor

Let us assume that we would like to configure pins 11 and 12 of PortD as digital outputs at full speed, with a push-pull and no pull up or pull down:

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);

I’ve written this post also for myself as a kind of a cheat sheet when I need to configure my general purpose I/O ports.

Tagged , , , . Bookmark the permalink.

21 Responses to STM32F4 GPIO Configuration

  1. Greetings, I do believe your web site could be having
    internet browser compatibility problems. Whenever I take a
    look at your site in Safari, it looks fine however, when opening in IE, it has some overlapping issues.
    I simply wanted to give you a quick heads up! Aside from
    that, excellent site!

    • pleyman says:

      Thanks for the heads up!
      I had a look at my site in IE (version 10) and I couldn’t find any problems although. I’ll check with other versions later…

  2. Rodrigo says:

    hello, firstly i can congratulations for your post, i need handling gpio, read and execute a operation of according with the result, you can help-me ? thanks. sorry bad english.

    Rodrigo – Brazil

    • pleyman says:

      Probably I can, but you’ll have to give more information about what you want to achieve. Check out the basic GPIO functions, probably you’ll find there what you need. In CooCox, go to the repository and check on the peripherals tab the GPIO component; the help page will show you the basic functions.

  3. electronic says:

    Hello sir,
    i like your tutorials, they are very helpful. Can you please help me I want to have a 5V output voltage instead of 3.3V, can I do that with programming or I should have an amplifier circuit.

    • Patrick says:

      No, with software it is not possible to increase the voltage of the I/O pins to 5V with the STM32F4. Depending on the hardware you’re targeting, you might need a hardware level converter. In some cases the 3.3V output of might be sufficient to trigger a high level on the target device (check the datasheets) and then you won’t need a level converter; but it is quite risky as you will be flirting with the threshold values of the target device. I don’t recommend this.
      A level converter is fairly simple to create, if you need only a few I/O pins, a transistor + 2 resistors will suffice. Other option is a MOSfet, then only one transistor is needed. These options can’t have very high switching speeds (<1 MHz).
      A better solution are the multiline logic-level translators from Maxim, for instance MAX3013/23, these achieve speeds of 100MHz.

      • electronic says:

        Hi, thank you so much sir for replying, you help me a lot as i am working with the stm32f4 in school and i have some difficulties to use it. I’m targeting an l293d motor driver for a robot. So do you advise me to work with a mosfet or with the multiline logic-level translators from Maxim?

        • Patrick says:

          Depends on how much room you have on your controller board. If you only need a couple of I/O lines to use 5V, I would then use MOSfet. IF you have more than 4 lines to convert, use the MAX3023.
          In general L293D doesn’t require high speed at all, so any of both will do just fine.

          • electronic says:

            Then i will use MOSfet. Thank for your precious help sir.

          • Chris says:

            Hello electronic,

            for level converting I often use an ultra highspeed inverter like the NC7WZ14P6. Power up it with 5V and drive the inputs directly with the outputs from the STM. The high output drive +-24mA makes lot of things possible. There are lot of such inverters on the market. 1 channel till hex channel. Of course the signals are inverted, but who cares. Good luck

  4. electronic says:

    Hello Chris,
    Thank you soo much for the advice, i will look into it.

  5. Zaouche Khelil says:

    I have an STM32F429 discovery board
    I program it with : STM32-Matlab/target (embedded target for Matlab and Simulink), STM32CubMx (configuration tool) and the toolchain: Keil uVision5 (lite).
    I tray a very simple Simulink program, which consist of blinking a LED (PG13, green LED).
    For this purpose, I used a ramp generator, from simulink sources, (period 1s, 5% ramle ratio).
    The output of the generator is connected to the GPIO_Write block (pin PG13)
    The GPIO pin 13 configuration is set as :
    GPIO_Mode: OUT
    GPIO_Speed : Low
    type: pull up
    when I download the code in the board, the LED is fired but it doesn’t blink
    what can I do to resolve this problem ?
    thank you for your help
    best regards

    • Patrick says:

      This could be caused by lots of things.
      Two things I’m thinking of:
      First of all PG13 is not a PWM linked pin, this means you have to drive this pin by yourself in the interrupt routines of the ramp generator. Or provide a polling loop that reads the ramp’s status and drives the pin accordingly (not really recommended as polling wastes CPU cycles).
      Second did you enable the interrupts and the timers for the ramp generator?
      Good luck!

  6. Ravindra Kant says:

    I am using Coocox CoIDE to build my code and then downloading the same into the STM32F407VG discovery board,i am using the code mentioned above by you GPIOD pin 13 and pin 14 i could not see the change.
    Can you help me resolving the issue.

  7. Farhan says:

    May I ask few doubts?

    Hi Mr.Patrick and all, I have already gone through lot of studies regarding to GPIO configuration, TIM initialization and, to generate Pulse signal from one of I/O pins of stm32f4. Now I know the way to set the frequency and other necessary configuration except voltage level.

    when I wanted to learn that I need to set the specific voltage for the specific pins.

    for instance,
    If I have selected Pin (PD12 it is located at TIM4, Channel 1) – I need set 5V output
    If I have selected another Pin (PD13 it is located at TIM4, Channel 2) – here I need to set 3.3V output.

    what is the way to set the specific voltage for certain pins ?

    Thanks for your time. your comments would be greatly appreciated.

    • Patrick says:

      Simple answer: you can’t. Digital I/O pins can only be set at 0V or 3V3. Only analog pins can be set at different voltages via DAC, but I don’t think that these pins can be coupled to a timer. Also the output cannot be higher than 3V3.
      Complicated answer: you could, but you need extra hardware. If you only need 5V, you could use a level shifter. If you need more variation, use for instance a MOSFET and drive its gate via PWM from the micro controller, then filter via a low pass LC or RC.

  8. Mik says:

    Hi, I’m using until one or two months Keil uVision5 to program a STM32f429 and I need 3 pins that can give as output a 3.3 V signal. The board has “only” two channel for the DAC that use PA4 and PA5 to give analog output, so I have to find a way to obtain 3 output for my application. How can I obtain three pins that give 3.3 V as analog output?

    Thanks for attention,

Leave a Reply

Your email address will not be published. Required fields are marked *