STM32F4xx GPIO`s (as Output)

Keywords: Embedded systems, ARM, STM32F4, GPIOs, Multiplexed Pins

Code Link: Source Code Github Keil- Bare-Metal

Code Link: Source Code Github Keil- HAL Libraries

GPIOs (General Purpose Input Output) enable a processor to interact with outside world. GPIOs are the most common way of interacting processor with off-chip devices and peripherals. In this tutorial we will explain how to use STM32F4xx GPIOs to blink an LED connected to a GPIO pin. The board used is STM32F4-Discovery. The board contains 4 on-board LEDs connected to PD.12,13,14,15 (Port D Pins 12 – 15). In this tutorial we will blink on-board Blue LED connected to PD.15.

Following are the steps to configure a GPIOx as an Output on STM32F4xx.

1. Enable GPIOx Module:

As can be seen from STM32F407VG (MCU on STM32F4-Discovery) datasheet[2] – Figure-1, GPIOD (as LED is connected to GPIOD Pin#15) is connected to AHB1 bus (Advance High Speed Bus).

Figure-1: GPIOD AHB1 bus Connection.

To reduce power consumption, by default various SoC modules (GPIO, USART, UART etc.) and associated registers are disabled. In order to use them, clock must be enabled to them. On STM32F40xx clock to GPIOs is enabled/disabled via AHB1ENR Register – Figure-2.

Figure-2: AHB1ENR Register.

As can be seen from Figure-2, the clock to GPIOD is enabled/disabled via bit-3 (GPIOD-EN). Let’s enable GPIOD module by setting bit-3 to 1.

// enable clock to GPIOD
__setbit(RCC->AHB1ENR, 3);

2. GPIOx as Digital Output:

The next step is to decide for which purpose the GPIO needs to be used. On STM32F4 GPIOs can be configured as:
    1. As Digital Input – Code : 00
    2. As Digital Output – Code : 01
    3. As Analog Input/Output – Code : 10
    4. As Alternate function Pin. – Code : 11

The respective GPIO can be configured with above associated code in GPIOx-MODER register – Figure-3.

Figure-3: GPIOx_MODER Register.

For blinking LED-example, PD.15 pin needs to be configured as digital output i.e. MODER15 (bit- 31,30) needs be set to 01 as per above codes.

/*
    configure PD.15 as general purpose output
*/
__setbit(GPIOD->MODER, 30);
__clearbit(GPIOD->MODER, 31);

3. GPIOx Output Type:

On STM32F4, GPIOs can be configured as Push-Pull or open-drain.
Push-Pull: In this state, GPIO Pin can be set to Logic-0 and Logic-1 by Software (if configured as output) or External Logic (if configured as input).
Open-drain: In this state, the GPIO Pins state (logic-0, logic-1) can’t be set by means of Software. Unless an external resister connecting pin to Vcc / Ground. In open-drain state, GPIO Pin remains in High-Impedance floating state.

The output type can be set via GPIOx_OTYPER register – Figure-4.

Figure-3: GPIOx_OTYPER Register.

For blinking LED-example, configure PD.15 pin as Push-Pull i.e. OT15 should be set to 0.

/*
    GPIOs output type: Push-Pull
    so that it can be pulled high (logic-1) and pulled down (logic-0)
*/
__clearbit(GPIOD->OTYPER, 15);

4. GPIOx Speed:

In order to reduce power, GPIOs speed can be set to application requirements accordingly. Higher the speed, the more will be the power consumption. On STM32F4, GPIO speed can be set via GPIOx_OSPEEDR-Figure-4.
    Low Speed (00): Speed goes up to 2Mhz.
    Medium Speed (01): Speed goes up to 25Mhz.
    Fast Speed (10): Speed goes up to 50Mhz.
    High Speed (11): Speed goes up to 100Mhz.

Figure-4: GPIOx_OSEEDR Register.

For blinking LED-example, Medium speed would be more than enough.

/*
    Lets keep GPIO speed: Medium
*/
__setbit(GPIOD->OSPEEDR, 30);
__clearbit(GPIOD->OSPEEDR, 31);

4. GPIOx Pull-up/Pull-down:

The GPIO default Hardware based state can be set to Pull-up or Pull-down via Resister. These states indicates what will be the state of GPIO pin if no state is set via software.
Pull-Up: GPIO pin remains in Logic-1/High state and Software can only pull it down to Logic-0.
Pull-Down: GPIO pin remains in Logic-0/Low state and Software can only pull it up to Logic-1.

On STM32F4, Pull-up/Pull-down state can be set via GPIOx_PUPDR register – Figure-5.

Figure-5: GPIOx_PUPDR Register.

For blinking LED-example, No pull-up/down is required. Both GPIO Pin state (High/Low) are under software control.

/*
   Initial Level: --> No Pull-up/down
*/
__clearbit(GPIOD->PUPDR, 30);
__clearbit(GPIOD->PUPDR, 31);

5. GPIOx State:

Now all required steps to configure a GPIOx Pin as output has been made. The final step is to set pin state i.e. writing 1/0 to GPIOx Pin. This can done via GPIOx_ODR – Figure-6. Setting corresponding bit in GPIOx_ODR to 1/0 will set the pin voltage to 3.3-volts (LED-ON) / 0-volt (LED-OFF) respectively.

Figure-6: GPIOx_ODR (Output Data) Register.

Let’s finally toggle the PD.15 – LED Pin with some delay.

while (1) {
   __togglebit(GPIOD->ODR, 15);
   for ( i = 0; i < 100000; ++i);
}

For complete source code refer to the Github links given at the start of this tutorial.

Video Demonstration:

[1] – Reference manual-RM0090



18 thoughts on “STM32F4xx GPIO`s (as Output)”

Leave a Reply

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