Embetronicx Com Tutorials Microcontrollers stm32 stm32 Gpio
Embetronicx Com Tutorials Microcontrollers stm32 stm32 Gpio
This is the Series of tutorials on the STM32 Microcontroller. The aim of this series is to
provide easy and practical examples that anyone can understand. Basically, you can write
GPIO codes in multiple ways (Using HAL, GPIO driver). Using that HAL you can finish
your job in one line of code. But I would suggest you, learn to program using the bare-
metal code (without any HAL or driver) initially. This is the STM32 GPIO Tutorial without
HAL.
X
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
You can also read, Getting started with STM32 RTOS, PIC16F877A GPIO tutorial, GPIO
Linux device driver, and STM32 GPIO RTOS tutorial.
Table of Contents
Prerequisites
Before starting this STM32 GPIO Tutorial, Please go through the below tutorials.
Introduction
GPIO stands for “General Purpose Input/Output.” We are using STM32F401VE for our
1. PORT A
2. PORT B
3. PORT C
4. PORT D
5. PORT E
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
GPIO main features
output)
Bit set and reset register (GPIOx_BSRR) for bitwise write access to GPIOx_ODR
Alternate function input/output selection registers (at most 16 AFs per I/O)
Fast toggle capable of changing every two clock cycles
Highly flexible pin multiplexing allows the use of I/O pins as GPIOs or as one of
several peripheral functions
There are a couple of registers used in GPIO. I have classified these register into 4 types
1. Control Registers
2. Data Registers
3. Locking Registers
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
4. Alternate Function Registers
Control Registers
Before looking into the control register, we will see the Clock Register (RCC_AHB1ENR)
which will enable the AHB clock to the GPIO ports.
RCC_AHB1ENR
This is called as RCC AHB1 peripheral clock enable register. The register is given below.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
1 – IO port D clock enabled
We don’t need the rest of the bits as we are only working on GPIO.
Example
GPIOx_MODER
This GPIO port mode register is used to select the I/O direction. Please find the below
image of the GPIOx_MODER register.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Here 2-bits are combined for one particular GPIO pin.
Bits [31:0] – MODERy : Direction selection for port X and bit Y, (y = 0 … 15)
In this tutorial, we are using only the I/O operation. So, we will use either Input mode or
output mode.
Example
GPIOx_OTYPER
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
This is the GPIO output type register which is used to select the output type (Push-Pull or
Open Drain). First, we need to know what is push-pull and open drain.
I think most of them are aware of this. If you have worked on I2C you must have heard
this. But still, I will put my words. In open-drain mode, inside the microcontroller one
switch (transistor/MOSFET) is connected to the GPIO pin and the ground. So If you write
high to the GPIO pin using software, it will be connected to the ground through the switch.
Which means the original output is low. If you write low to the GPIO pin, it will be left
floating since the switch will be turned off. That’s why we are using a pullup resistor for
the open-drain pins.
Whereas in push-pull mode, two switches (transistor/MOSFET) will be there inside of the
microcontroller. One switch is connected to Vcc/Vdd and another switch is connected to
the ground. So when you write High to the GPIO pin, the switch will be connected to the
Vcc/Vdd. The resulting output will be high (1). And if you write low to the GPIO, then the
switch will be connected to the ground. The resulting output will be low (0).
Got some idea about both output modes? Okay, let’s go to the register now. Please find
the below image of the GPIOx_OTYPER register.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Here,
GPIOx_OSPEEDR
This GPIO Output speed register is used to set the speed of the GPIO pin. Please find the
below image of the GPIOx_OSPEEDR register.
Bits [31:0] – OSPEEDRy : Speed selection for port X and bit Y, (y = 0 … 15)
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
OSPEEDRy Selection:
GPIOx_PUPDR
This is the GPIO port pullup/pulldown register which is used to configure the GPIO pin
into Pullup or pulldown mode. Please find the below image of the GPIOx_PUPDR register.
Bits [31:0] – PUPDRy : pullup/pulldown selection for port X and bit Y, (y = 0 … 15)
PUPDRy Selection:
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Example
Data Registers
These data registers are used to make the store the data to be output/input. The below
registers are used for output/input.
where, x = A, B, C, D, and E.
GPIOx_IDR
This is the Input Data Register. When you configure the GPIO ports as input using
GPIOx_MODER register, this register is used to get the value from the GPIO pin. This
register is a read-only register. So you cannot write into it. Please find the below image of
the GPIOx_IDR register.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Here,
This will be containing the corresponding value of the corresponding I/O port.
And It can be accessed in 32-bit word mode only. Which means you cannot
read a single bit. You have to read the whole register.
Example
Let’s assume that I have configured PORT B as input, using the GPIOB_MODER register
and other control registers. Now we can read the GPIO pins like below.
GPIOx_ODR
This is the Output Data Register. When you have configured GPIO Port as output using
GPIOx_MODER register, this register is used to set the value to the GPIO pin. We can read
and write to the register. Please find the below image of the GPIOx_ODR register.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Bits [15:0] – ODRy : Port Output Data, (y = 0 … 15)
Note: When you read the output data register, it will give you the last written value.
Example
Let’s assume that I have configured PORT B as output, using the GPIOB_MODER register
and other control registers. Now we can write the GPIO pins like below.
You have to be careful when you are writing the GPIO port using this GPIOx_ODR.
Because you may disturb the other Pins (bits) of the register which you don’t want to.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Then what if I want to write a single bit without disturbing others? There is a way to do
that. Just keep reading.
GPIOx_BSRR
This is GPIO Bit Set/Reset Register. When you want to set or reset the particular bit or
pin, you can use this register. This is a write-only register. This register will do the atomic
set/reset. So we don’t worry about the interrupts that cause problems during set/reset.
And in this register, the lower 16-bits are used to set any of the 16 pins and the higher 16-
bits to clear/reset any of the 16 pins of a particular IO port. Please find the below image of
the GPIOx_BSRR register.
These bits are write-only and accessed in word, half-word, or byte mode. If
you read this register you will get 0x00000000. If you write 1 to any bit [0 to
15], it will set the corresponding bit in GPIOx_ODR register [0 to 15]. If you write
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Bits [31:16] – BRy : Port Reset Bit, (y = 0 … 15)
These bits are write-only and accessed in word, half-word, or byte mode. If
you read this register you will get 0x00000000. If you write 1 to any bit [16 to
31], it will set the corresponding bit in GPIOx_ODR register [0 to 15]. If you write
0 to any bit [0 to 15], no action will be performed to the corresponding bit in
If you set both BSx and BRx, BSx has the priority. So BRx will be ignored. Where, x = 0…
15.
Example
Let’s assume that I have configured PORT B as output, using the GPIOB_MODER register
and other control registers. Now we can write the GPIO pins like below.
Locking Registers
This register is used to lock the configuration of the port bits. The below register is used to
do that.
GPIOx_LCKR
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Using this register, you can freeze the GPIO configurations. Once you do the proper lock
let’s see that register. Please find the below image of the GPIOx_LCKR register.
This can be accessed in 32-bit word only and you can perform both read and write.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
This bit can be read at any time. But if we want to modify the bit, we have to
follow the Lock key write sequence. Once you have locked the GPIO, then it
will be locked until an MCU reset or a peripheral reset occurs.
RD LCKR
Note: During the Lock key write sequence, the value of LCK[15:0] should not change.
And in some other STM32, this GPIOx_LCKR is not available for all the GPIO ports. So
you should check with the datasheet before doing this. But in the STM32F401VE,
GPIOx_LCKR register is available for all the GPIO ports.
Any error in the lock key write sequence aborts the lock. Once you have done the lock
key write sequence properly on any bit of the port, any read access on the LCKK bit will
return ‘1’ until the next CPU reset.
1. /*
2. ** The below full code snippet, locks the GPIO configuration of Port B
3. */
4. #define GPIO_PIN_POS (5U) //I want to lock PB5. So setting 5th bit
5. #define LCKK_BIT_POS (16U) //Position of LCKK bit
6.
7. volatile uint32_t lock_gpio = 0;
8.
9. /* Lock key write sequence */
10. /* WR LCKR[16] = ‘1’ + LCKR[5] = ‘1’ */
11. lock_gpio = (( 1UL << LCKK_BIT_POS) | ( 1UL << GPIO_PIN_POS ));
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
12. GPIOB->LCKR = lock_gpio;
13.
14. /* WR LCKR[16] = ‘0’ + LCKR[5] should not change*/
15. GPIOB->LCKR = ( 1UL << GPIO_PIN_POS );
16.
17. /* WR LCKR[16] = ‘1’ + LCKR[5] should not change*/
18. GPIOB->LCKR = lock_gpio;
19.
20. /* RD LCKR */
21. lock_gpio = GPIOB->LCKR;
22. if((GPIOB->LCKR & ( 1UL << LCKK_BIT_POS)) != 0)
23. {
24. //PB5 configuration has been locked
25. }
26. else
27. {
28. //PB5 configuration has not been locked
29. }
Each GPIO pin has around sixteen alternative functions like SPI, I2C, UART, etc. So we
The below-mentioned two registers are used to select the one function out of sixteen
GPIOx_AFRL
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
This 32-bit register is grouped by 4bits. So This GPIOx_AFRL register is used to select the
alternate functions of Pin 0 to Pin 7. Please find the below image of the GPIOx_AFRL
register.
Bits [31:0] – AFRLy : Alternate function selection for port X and bit Y, (y = 0 … 7)
AFRLy Selection:
GPIOx_AFRH
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
This 32-bit register is grouped by 4bits. So This GPIOx_AFRH register is used to select the
alternate functions of Pin 8 to Pin 15. Please find the below image of the GPIOx_AFRH
register.
Bits [31:0] – AFRHy : Alternate function selection for port X and bit Y, (y = 0 … 7)
AFRHy Selection:
As of now, we are using these pins as a GPIO and we are not selecting other functions
than Input/Output. So in our future post, we will discuss these GPIOx_AFRL and
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
GPIOx_AFRH.
I think we have covered almost all the registers. Now we will just put them all together and
make our hands dirty by playing with the LEDs. Let’s dive into the programming part.
In the below example, I have enabled all the Ports (A, B, C, D, and E) as an output. and
toggling them with some delay. You can also find the complete project on GitHub.
Code
1. /*********************************************************************
2. * \file main.c
3. *
4. * \details Setting all the Ports (A, B, C, D, and E) as output
5. * and toggling them with some random delay - STM32 GPIO
6. *
7. * \author EmbeTronicX
8. *
9. * \This code is verified with proteus simulation
10. *
11. **********************************************************************
12.
13. #include "stm32f4xx.h"
14.
15. #define DELAY_COUNT ( 30000 ) //delay count
16.
17. /*********************************************************************
18.
19. \details Providing Delay by running empty for loop
20.
21. \return void
22.
23. \retval none
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
24.
25. **********************************************************************
26. static void delay( void )
27. {
28. uint32_t i = 0;
29. for( i=0; i<=DELAY_COUNT; i++ );
30. }
31.
32. /*********************************************************************
33.
34. \details The main function. It should not return.
35.
36. \return void
37.
38. \retval none
39.
40. **********************************************************************
41. int main(void){
42.
43. //Enable the AHB clock all GPIO ports
44. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
45. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
46. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
47. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
48. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);
49.
50. //set all Port A to Port E as output
51. GPIOA->MODER = 0x55555555;
52. GPIOB->MODER = 0x55555555;
53. GPIOC->MODER = 0x55555555;
54. GPIOD->MODER = 0x55555555;
55. GPIOE->MODER = 0x55555555;
56.
57. //Endless loop
58. while(1){
59.
60. //Turn ON the LED of all the ports
61. GPIOA->BSRR = 0x0000FFFF;
62. GPIOB->BSRR = 0x0000FFFF;
63. GPIOC->BSRR = 0x0000FFFF;
64. GPIOD->BSRR = 0x0000FFFF;
65. GPIOE->BSRR = 0x0000FFFF;
66.
67. delay();
68.
69. //Turn OFF the LED of all the ports
70. GPIOA->BSRR = 0xFFFF0000;
71. GPIOB->BSRR = 0xFFFF0000;
72. GPIOC->BSRR = 0xFFFF0000;
73. GPIOD->BSRR = 0xFFFF0000;
74. GPIOE->BSRR = 0xFFFF0000;
75.
76. delay();
77. }
78. }
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Output
I have connected the button to the PA0 (Port A.0) and LEDs to the PD0 to PD3. You can
also find the project on GitHub.
Code
1. /*********************************************************************
2. * \file main.c
3. *
4. * \details Setting PORT D0 to D3 as output and PORT A0 as input.
5. * When we press the Port A0, we will turn on the PD0-PD3
6. *
7. * \author EmbeTronicX
8. *
9. * \This code is verified with proteus simulation
10. *
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
11. **********************************************************************
12.
13. #include "stm32f4xx.h"
14.
15.
16. /*********************************************************************
17.
18. \details The main function. It should not return.
19.
20. \return void
21.
22. \retval none
23.
24. **********************************************************************
25. int main(void){
26.
27. //Enable the AHB clock all GPIO PORT A and PORT D
28. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
29. SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
30.
31. //set Port A as input
32. GPIOA->MODER = 0x00000000;
33. //Enable Pullup on PA0
34. GPIOA->PUPDR = 0x00000001;
35.
36. //set PORTD0 to PORTD3 as output
37. GPIOD->MODER = 0x00000055;
38.
39. //Turn OFF the LEDs of PORTD
40. GPIOD->BSRR = 0xFFFF0000;
41.
42. //Endless loop
43. while(1){
44.
45. //Button is connected to PA0. So we need to check bit 0 of IDR reg
46. if( ( GPIOA->IDR & 0x01) == 0 )
47. {
48. //Turn ON the LEDs
49. GPIOD->BSRR = 0x0000000F;
50. }
51. else
52. {
53. //Turn OFF the LEDs
54. GPIOD->BSRR = 0x000F0000;
55. }
56. }
57. }
Output
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
Note: The code is tested with the Proteus simulation. Not with the
real hardware. If you have figured out any problems and issues with
code while testing with the hardware, Please inform us and provide
us as the workaround. So that, We will update here also. This will
help others to learn.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
If you want to use RTOS in STM32, you can refer to the STM32 GPIO with the RTOS
tutorial.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
VHDL Tutorials UDS Protocol Tutorials
Product Reviews
SLR
Embedded Software | Firmware | Linux Devic Deriver | RTOS
STM32
Subscribe Login
{} [+]
This site uses Akismet to reduce spam. Learn how your comment data is processed.
1 COMMENT
Oldest
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
hi sir my name is samseer from india. wright now i’m learning the stm32f401 baremetal
programing on the keil ide .but i have a doubt about intialization process.my doubt is why did
you mention the clock initialization and pll configuration when create a simple led program.
0 Reply
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com