GPIO Peripheral in STM32F103 MCU
Table of Contents
GPIO Theory
![](http://gettobyte.com/wp-content/uploads/2023/06/GPIO-1.png)
So now we’ll talk about GPIO pins . GPIO stands for general purpose input output pins; they are the means for communication between the microcontroller and the external world (using sensors etc).It is signal that arrives on these pins or a signal that is sent or written on these pins that facilitates this communication. These pins can be configured to act as input or output via the application software(in our case stm32cube ide). The programmer can configure the pins as LOW or 0V or HIGH or 3.3V(or 5V ).
These GPIO pins can also be configured to act as special purpose pins as well where their alternate functionality is exploited . These alternate functionality includes UART , ADC , SPI etc . In the case of UART communication, Transmitter(Tx) and Receiver(Rx) pins are required. GPIO pins can be configured to act as TX or RX pins . Even in ADC the pins are configured to act as Analog pins having 12 bits of resolution . The alternate functions of various pins are shown below:
Input floating
Input pull-up
Input pull-down
Analog
Output open-drain
Output push-pull
Alternate function push-pull
Alternate function open-drain
![](http://gettobyte.com/wp-content/uploads/2023/06/Input-floating-and-Analog-1.png)
GPIO Peripheral in STM32F103
All the pins of STM32F103 are grouped in multiple ports as PORT A, PORT B, PORT C As can be seen from Pin configuration chart in the PA1 stands for Port A Pin 1. There are 37 GPIO pins in stm32f103 which are divided as PORT A with 16 pins, PORT B with 16 pins, PORT C with 3 pins and PORT D with 2 pins.
- Each GPIO port has two 32-bit configuration registers (GPIOx_CRL, GPIOx_CRH), two 32-bit data registers (GPIOx_IDR, GPIOx_ODR), a 32-bit set/reset register (GPIOx_BSRR), a 16-bit reset register (GPIOx_BRR) and a 32-bit locking register (GPIOx_LCKR).
- In the register names, x stands for the port to which pin belongs. If we are configuring pin PA1, it has Port A then registers would be accessed by GPIOA_CRL and etc.
- Out of above-mentioned registers, GPIO peripheral has 2 most important registers:
GPIO Peripheral Block Diagram in STM32F103
- First after selecting the pin the port is decided
- Then after following the arrow the busses are selected based on it: APB/APB1 or AHB
- After which the clock is enabled to the particular port using either __HAL_RCC_GPIOX_CLK_ENABLE() function or using the RCC AHB1 peripheral clock enable register and selecting the port to which clock has to be provided by enabling it.
![](http://gettobyte.com/wp-content/uploads/2023/06/SELECTING-2.png)
Methods to configure the GPIO Peripheral
![](http://gettobyte.com/wp-content/uploads/2023/06/image-8.png)
![](http://gettobyte.com/wp-content/uploads/2023/06/image-7.png)
![](http://gettobyte.com/wp-content/uploads/2023/06/image-5.png)
![](http://gettobyte.com/wp-content/uploads/2023/06/image-6.png)
- Configuring the busses i.e AHB1, AHB2, APB1, APB2 . The AHB bus is faster than APB bus and in case of certain modules they are connected to the same bus .Hence it depends upon the application which bus to use. As can be seen from the picture below the AHB1 takes clock to PORT A , PORT B , PORT C etc . Hence to initialize a pin to a particular port the in RCC AHB1 clock enable register GPIOEN is set to 1 (For Port A GPIOAEN , For Port B GPIOBEN etc)
- Enabling the clock to that port otherwise the particular pin will not be functional
- Creating an instance of the structure and then using the members of the structure set the following:-
- PIN – Takes the pin no as input GPIO_PIN_X {where X -0 to 15}
- MODE– Selects the mode the specified pin is supposed to work in . It takes in value Output Push Pull ,Output Open drain
- PULL- It selects the initial value of the pin and takes value no pull up no pull down, pull up or pull down
- SPEED- Selects the speed of the working of the specified pin i.e low, medium or high
- ALTERNATE- Specifies the alternate function performed by the pin UART TX OR RX , ADC etc,
GPIO Peripheral SDK using STM32HAL
We are going to use STM32 HAL SDK for using the GPIO peripheral of the STM32F103. STM32HAL is a very versatile and robust Software package for using Peripherals of the STM32 Microcontroller family. To know more about STM32HAL, refer to this link.
![](http://gettobyte.com/wp-content/uploads/2023/06/Screenshot-2023-06-16-215906.png)
Each STM32 HAL has drivers for all the peripherals of the STM32 Microcontroller(One can navigate to the Driver folder in the STM32F1 HAL local repo installed). These drivers can be configured and enabled to use in the project via the STM32 CubeMX configuration tool, which is also integrated into STM32CubeIDE( just like told in the above section for configuring GPIO peripherals). Will be digging into that part, in the next section. For now, let’s understand the STM32HAL GPIO SDK for STM32F103 MCU.
- stm32f1xx_hal_gpio.c: This file consists of various macros and is responsible for the intialization and configuration of the functions which in turn configures the peripheral.
- stm32f1xx_hal_gpio.h: consists of various structure definitions that help configure various parameters of the pin, enumeration, and various macros
- stm32f1xx_ll_gpio.c & stm32f1xx_ll_gpio.h: GPIO Low-level driver source/header file, contains functions that configure the GPIO Peripheral registers at the hardware level. These files are the ones that actually interact with the hardware and make it configurable to our needs. 
STM32 HAL Functions for GPIO Peripheral
Functions are set of instructions that required to perform certain tasks. In general, a function is first declared in header file(.h) and then it is definied in source file(.c) and then called in main.c or application code.
It is of the form function return data type, function name and function arguments.
// Basic introduction of functions in c
void func(int x);
int main()
{
func(x);
}
void func(int x)
{/*function body/*}
In Embedded functions are required to initialize a peripheral or configure it on the basis of various parameters which are passed on using arguments. This information is then passed on to the registers.
List of functions used for GPIO HAL:
FUNCTION NAME
HAL_RCC_GPIOX_CLK_ENABLE()
FUNCTION DESCRIPTION
This API is used to enable the clock to a particular port that will be delivered using AHB OR APB busses. This function basically sets the APBENR bit in RCC register and after a delay enables the clock.
RETURN VALUE
NONE
![](http://gettobyte.com/wp-content/uploads/2023/06/AHP-2.png)
USAGE
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
}
FUNCTION NAME
- void HAL_GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef *GPIO_Init)
FUNCTION DESCRIPTION
This API takes 2 arguments as input that are pointer to structure GPIO_TypeDef* GPIOx this is usually used to specify the port (A,B etc) and GPIO_InitTypeDef *GPIO_Init which is basically the pointer to the structure GPIO_InitTypeDef this contains information of the pin configuration such as pin , mode , speed , pull , alternate. This API basically initializes the specified pin according to configuration specified in GPIO_Init.
PARAMETERS (ARGUMENTS)
GPIOx:specifies the PORT ie X(A,B,C)
GPIO_Init: Pointer to GPIO_InitTypeDef that has the configuration information of the GPIO peripheral
RETURN VALUE
NONE
USAGE
static void MX_GPIO_Init(void){
/*STEP 2*/
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = led_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(led_GPIO_Port, &GPIO_InitStruct);
}
FUNCTION NAME
- GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
FUNCTION DESCRIPTION
This API is used to Read the value from a specified pin and it returns value of the type GPIO_PinState which is an enumeration in which GPIO_PIN _RESET has been assigned the value 0U and anything apart from this is GPIO_PIN_SET. This API takes in 2 arguments as input that are pointer to structure GPIO_TypeDef* GPIOx this is usually used to specify the port (A,B etc) and uint16_t GPIO_Pin this specifies the pin to be chosen and takes value from 0-15.
PARAMETERS (ARGUMENTS)
GPIOx:specifies the PORT ie X(A,B,C)
GPIO_Pin:specifies the pin or the port bit to read from i.e from 0-15.
RETURN VALUE
The input pin state value
USAGE
uint8_t buttonval = 0;
while (1)
{
buttonval=HAL_GPIO_ReadPin(BTN_GPIO_Port, BTN_PIN);
}
FUNCTION NAME
void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
FUNCTION DESCRIPTION
This API is used to write either a HIGH or LOW at the specified pin . It takes in 3 arguments as input that are pointer to structure GPIO_TypeDef* GPIOx this is usually used to specify the port (A,B etc) , uint16_t GPIO_Pin this specifies the pin to be chosen and takes value from 0-15 and GPIO_PinState PinState which is an enum of the type GPIO_PinState which takes in value SET or RESET.
PARAMETERS (ARGUMENTS)
GPIOx:specifies the PORT ie X(A,B,C)
GPIO_Pin:specifies the pin or the port bit to read from i.e from 0-15.
PinState:specifies the state to be written on the specified pin.These values are:
SET- To write a HIGH on the pin
RESET- To the clear or write LOW on the pin
RETURN VALUE
NONE
USAGE
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);
}
FUNCTION NAME
void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
FUNCTION DESCRIPTION
This API is used to toggle or switch the state of the specified pin high to low or low to high. This API also takes in 2 arguments as input that are pointer to structure GPIO_TypeDef* GPIOx this is usually used to specify the port (A,B etc) and uint16_t GPIO_Pin this specifies the pin to be chosen and takes value from 0-15.
PARAMETERS (ARGUMENTS)
GPIOx:specifies the PORT ie X(A,B,C)
GPIO_Pin:specifies the pin or the port bit to read from i.e from 0-15.
RETURN VALUE
NONE
USAGE
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);
}
Data Types Involved
- uint8_t
- uint16_t
- uint32_t
- GPIO_InitTypeDef
- GPIO_PinState
- uint8-t– This data type is used to store unsigned value of 8 bits which means that only positive or zero value can be stored in the data type .Ranging from 0-255. This data type can be used to store state of a pin in a variable
- uint16_t– This data type stores unsinged values of 16 bits . The range in this case is 0-65535.This data type can be used to define pins of a port as there are 16 pins in port A
- uint32_t-This data types stores unsigned values of 32 bits i.e it stores non-negative values in the range 0 to 4,294,967,295. This data type stores 4 bytes per element.
- GPIO_InitTypeDef- A structure that helps configure pin state such as:-
- PIN-It defines the pin to be selected
- MODE-It defines the mode the specified pin has to be set in such as input , output , alternate function and even in these modes push pull , open drain etc
- PULL- It sets the pin in 3 modes which are nopull , pull up , pull down
- SPEED- It defines the speed or frequency of the operation which can be low, medium , high
5.GPIO_Pinstate- An enumerator that stores the pin state which can be SET or RESET
DEMO EXERCISE
1 CODE FOR BLINKING THE ON BOARD LED PC13 WITH A DELAY OF 1s
MX_GPIO_Init();/*STEP 1*/
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);/ *STEP 6*/
HAL_Delay(1000);/*STEP 7*/
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET); /*STEP 8*/
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
static void MX_GPIO_Init(void){
_HAL_RCC_GPIOC_CLK_ENABLE(); /*STEP 2*/
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET); /*STEP 3*/
GPIO_InitStruct.Pin = led_Pin; /*STEP 4*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(led_GPIO_Port, &GPIO_InitStruct); /*STEP 5*/
STEPS INVOLVED
STEP 1
Create a function to configure all the pins involved in the application . Configuration such as clock enable , pin state initially, Pin no , mode, pull, speed. This function also involves HAL_GPIO_Init function that initializes the pin and has the information of its configurations.
STEP 2
Enable clock to the specified port in this case PORTC
STEP 3
Specify the initial state of the pin
STEP 4
Specify the pin no ( used a label for the pin led_Pin) the original pin no is 13 in this case. Also configure the pin mode which takes value output push pull or output open drain. Next configure the pull method which takes value no pull up and no pull down in our case.Configure the speed of the peripheral according to requirement in this case we are choosing low frequency .
STEP 5
Create the function specifying the port and all the information about the pin configuration
STEP 6
Write value to the pin as SET or HIGH
STEP 7
Include a delay in our case it is 1000ms or 1s using HAL_Delay() function
STEP 8
Write value to the pin as RESET or LOW . Since all this is in a while (1) loop the led will continue to blink
NOTE-The above exercise can also be performed by replacing the 2 HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET), HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET) with the HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin) and since the HAL API is called in the while loop the led will blink forever in a loop.
2 TURNING THE LED ON OR OFF USING A PUSH BUTTON
MX_GPIO_Init();/*STEP 1*/
uint8_t buttonval = 0;
while (1)
{
buttonval=HAL_GPIO_ReadPin(BTN_GPIO_Port, BTN_PIN);/ *STEP 7*/
/* USER CODE END WHILE */
if(buttonval == 0){
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);/ *STEP 8*/
}
else{
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);/ *STEP 9*/
}
/* USER CODE BEGIN 3 */
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();/*STEP 2*/
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);/*STEP 3*/
/*Configure GPIO pin : led_Pin */
GPIO_InitStruct.Pin = led_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(led_GPIO_Port, &GPIO_InitStruct);/*STEP 5*/
/*Configure GPIO pin : BTN_Pin */
GPIO_InitStruct.Pin = BTN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(BTN_GPIO_Port, &GPIO_InitStruct);/*STEP 6*/
}
STEPS INVOLVED
STEP 1
Create a function to configure all the pins involved in the application . Configuration such as clock enable , pin state initially, Pin no , mode, pull, speed. This function also involves HAL_GPIO_Init function that initializes the pin and has the information of its configurations
STEP 2
Enable clock to the specified port in this case PORTC
STEP 3
Specify the initial state of the pin
STEP 4
Specify the pin no ( used a label for the pin led_Pin) the original pin no is 13 in this case. Also configure the pin mode which takes value output push pull or output open drain. Next configure the pull method which takes value no pull up and no pull down in our case.Configure the speed of the peripheral according to requirement in this case we are choosing low frequency .
STEP 5
Create the function specifying the port and all the information about the pin configuration(PORT C PIN 13)
STEP 6
Create the function specifying the port and all the information about the pin configuration(PORT A ,PIN 0)
STEP 7
Initialize a variable buttonval to read the state of the Pin PA0 using HAL api GPIO_ReadPin
STEP 8
Write value to the pin as SET or HIGH when the pin is pressed
STEP 9
Write value to the pin as RESET or LOW when the button is not pressed . Since all this is in a while (1) loop the led will continue to blink
Author
Kunal
Starting with RTOS: FreeRTOS
Table of Contents Intro From this blog, we will be starting with RTOS(FREERTOS). In RTOS there are many concepts & things related to kernel, tasks
GPIO Peripheral in S32K144 MCU
Table of Contents So hello guys, welcome back to NXP Semiconductors S32K144 MCU Tutorial series. In the last blog we just started with S32K144 MCU.
Overview of Programming languages
Compiled language: are translated to the target machine\’s native language by a program called a compiler. This can result in very fast code, especially if
What is Altium CircuitStudio?
Altium Circuit Studio is an entry-level but professional PCB design suite. Which offers interactive automated routing, intuitive ECAD-MCAD collaboration, integrated SPICE simulations, and unparalleled design
Getting Started with S32 Design Studio Part 2
Table of Contents Overview So, hello guys, welcome to Gettobyte website. This blog is part of the Microcontroller coding series on NXP Semiconductors S32K144 MCU.
What are Device driver, Application Codes and HAL in Embedded Softwares
What are Peripherals in MCU? What is peripheral driver in MCU? What is sensor/module interfacing in MCU. What is device driver and RTD? What is HAL/BSP?
Author