This time, I’m going to go away from the IDE topic and explain the code I added last time.
The code I added is related to the GPIO initialization.
Development environment at the time of posting
PC: Windows 10 OS
IDE: STM32CubeIDE Version1.1.0
Configurator: STM32CubeMX Version5.4.0
Board: STM32Nucleo-F401RE
/* USER CODE BEGIN 1 */
GPIO_InitTypeDef GPIO_InitStruct = {0}
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* USER CODE END 1 */
In using this IDE, users basically have to write their code between USER CODE BEGIN and USER CODE END.
In order to operate stm32’s peripherals, initialization is required.
There is a structure dedicated to initialization for each peripheral function.
Here, we use a structure of type GPIO_InitTypeDef for the “LED blinkey” GPIO.
Set a value to the structure and call the GPIO initialization function, HAL_GPIO_Init().
(The same pattern is used for the initialization of peripheral functions other than GPIO.
The initialization function is prefixed with the word HAL. Let me explain a little about HAL here.
HAL stands for Hardware Abstraction Layer, which means Hardware Abstraction Layer.
HAL is a hierarchy that absorbs differences in hardware specifications, and plays a role in making it possible for users to handle hardware in the same way.
Some microcontrollers have different addresses for the registers to control GPIOA.
The user can control GPIOA by using HAL functions without being aware of them.
It uses a little more memory than accessing the registers directly, but you don’t need to worry about it too much.
Let’s use the convenient HAL functions.
However, there are some things that need to be finely controlled and cannot be handled by the HAL function, so you may want to consider other means in that case.
The manual for the stm32F4 HAL can be downloaded from the following site.
It is a large PDF file, but you should be able to view and examine the parts you need when you need them.
It includes explanations of each member of the structure.
There are many things you cannot understand just by looking at it, so we recommend you to try out various settings.
To use GPIO as an output pin, set the clock to Enable, set the pin to the Pin member, and set GPIO_MODE_OUTPUT_PP to the Mode member.
Please note that even when handling GPIOs, the clock must be enabled to work.
Set the structure member Pin to initialize GPIO
To set the pins, each pin is defined as follows and assigned to one bit.
Each pin is defined as follows and assigned to one bit.
For example, if you use GPIO_PIN_ALL, you can set all 16 bits of the GPIO port at the same time.
However, this is only possible if you want the same setting for each bit.
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
(Example)
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPOP_PIN_5; // Set both PIN1 and 5 at the same time
Pin = GPIO_PIN_ALL; // set 16 bits at the same time
Set the structure member Mode to initialize the GPIO
The next step is to set the Mode member to determine how to operate the GPIO.
For details on each function, please refer to the manual mentioned earlier.
Since we will be setting the output pin for “LED blinky”, we will use
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
Set it to
Set the structure member Pull to initialize the GPIO
Set whether the GPIO should be pulled up, pulled down, or not.
Since it is not necessary, we will use
GPIO_InitStruct.Pull = GPIO_NOPULL;
since it is not necessary.
Setting the structure member Speed to initialize GPIO
Set the operating frequency.
Either is fine, but slow is good.
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
Set it to
Initialize the GPIO
Now we call HAL_GPIO_Init() with the GPIO port and the configured structure as arguments.
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
The above is a brief explanation of GPIO initialization.
After the initialization, the next function sets GPIOA5 pin to “1” (High level)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
The following function sets the GPIOA5 pin to “0” (Low level).
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
The next function inverts the state of the GPIOA5 pin.
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
This is a brief description of the code we have added.
In the next article, we will try to implement the timer interrupt process using the configurator.





