In this new tutorial we will examine the usage of the GPIO (General Purpose Input/Output) peripheral within the System Workbench software. After all these steps below we will see a LED blinking. First we will go through the standard procedure for creating a new project using the autonomous code generation tool STM32CubeMX. Thereafter we will add our user code and program it to the chip.
Please note that I am using a Nucleo-303K8 development board. Because of this it can happen that some steps are quite different if you are using another development board. There can be differences in the code creation step as well as different pinning in the STM32CubeMX tool. Nevertheless you will enhance your knowledge of the tools if you follow this tutorial. If you have any problems building your project please post your questions in the comments and I will try to help you as fast as possible. To cut a long story short, let’s begin coding.
First we need to open the application STM32CubeMX.
Now choose File – New Project.
Selecting the Microcontroller or Development Board
After this step we now have to select our board or microcontroller. If you have a Nucleo or another development board you can switch to the tab “Board Selector” as shown below. All development boards listed are directly offered by ST Microelectronics. If you do not use a development board but only the microcontroller on a self-made PCB you can choose it directly using the “MCU Selector”. After making the selection, press on Start Project. If asked, please select not to initialize the peripherals to their default mode.
Configuration of Port Pins
After selecting the board or also the microcontroller you are presented with an image of the controller with the proper pinning. Here you can assign functions to the pins. As you can see there are also some default settings that are used for the SWD (Single Wire Debug) interface, the VCP’s which is the virtual COM port and the LED, that we want to use. Additionally, the power supply pins are drawn.
Detailed Configuration of GPIO Peripheral
Next, we click on System Core – GPIO and then on the line containing the pin PB3. Here we can configure the GPIO pin in more detail.
In this window you can change several setting of the GPIO module and every port that we have defined before. Here a list of the meanings of the different parameters:
- GPIO output level: This is the logical level at which the pin is set after initialization of the GPIO module. In our case we start with a low or logical “0”
- GPIO Mode: Here you can choose if you want the pin to run in a push-pull configuration where the output can be driven to high or low or open-drain where the output can only be driven to logical low and is open otherwise. In the latter case you should add a pull-up resistor so that you can switch between low and high.
- GPIO Pull-up/Pull-down: You can define a Pull-up or Pull-down resistor here. In this case we don’t need any of them.
- Maximum output speed: Here you can specify separate output speeds. In our case the LED is toggled every 500 ms which is very slow. We only need low-speed in this situation.
- User Label: I added a user Label called LED. You can use this label afterwards in the program to call and change the pin level for example. I would recommend that you name it the same for code compatibility reasons.
After this step we select the clock configuration. There it shows that the system clock as well as the peripherals are running at 8 MHz. This is ok for now because we do not have any specifications that limit us. Next we click on “Project Manager” as shown below.
Generation of Code
After this step we are done with the configuration. Now we have to add some project settings before we can start the code generation.
In this window you can specify the name of the project and its location. The toolchain must be SW4STM32 in our case, otherwise we would run into problems. I also enabled the tick at “Generate under Root”. Now you can press the button “Generate Code”.
If you did not install the needed repository for your microcontroller, the program will remind you to do this now. Please just follow the instructions.
Importing the Project
After successful code generation you can directly open the project. If you want to import the project yourself please find the description below.
Open the software “System Workbench”, also called SW4STM32, and choose your workspace. To add the project, please click on “File – Import”.
Here you have to choose “Existing Projects into Workspace”.
In the following window you have to click on “Browse” to set up the project directory.
Just click on the project folder just created by the plugin and select “Open”.
It automatically finds the necessary project files so just select it in this window and click “Finish”.
These were the steps necessary to set up your project in System Workbench and you are ready to use the files in there. In the next section I will explain the project structure and show you which files you have to change for getting a working project.
On the left you can see the expanded folders of the project structure. First we will begin with the Inc and Src folders.
There you can find all code which is user code. The main.c file is self explanatory. It is the starting point of our program. The file “stm32f3xx_hal_msp.c” contains the initialization of the “MCU specific package” MSP. These functions are especially written for a specific microcontroller. We also do not need to touch this file. The “stm32f3xx_it.c” file contains all interrupt-related code. We are going to use it in later tutorials. It is not relevant for this easy GPIO tutorial. The “system_stm32f3xx.c” file contains startup code which is needed to initialize the microcontroller.
The startup folder holds the startup files that is necessary for getting the microcontroller running.
Next, the Drivers folder is on the same level as the Src and Inc folders and represents all necessary code for handling the peripherals via HAL(Hardware Abstraction Layer) and the CMSIS(Cortex Microcontroller Software Interface).
Inside the HAL Driver folder there are all the code files for each peripheral. If you want to have a closer look just open the files and scan through them. I would also encourage you to open the specific header files because very often there is a description about how to use a peripheral. You can find the header files in the include folders on the top of the project structure or also in the .c files themselves. They most likely will be defined there. Just ctrl-click (cmd-click on mac) on the include statement and they will open.
Adding User Code
Ok, now the settings are all done and we can start to code. Unfortunately we only need to add two lines to our project to make it running. Please add the following code in the section as shown in the image below.
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(500);
The first code line toggles the specified pin. It is possible to use the designators LED_GPIO_Port and LED_Pin because we defined the user label in STM32CubeMX. If we did not do that, we would have to write the following:
The second code line just adds a delay of 500 ms before it toggles the LED pin again.
Building the Code
After adding the necessary code we have to build it. This is done using the “Build All” button as shown in the image below.
A new window appears showing the current status of the build process.
The next step is to program the binary to the microcontroller. Please make sure to connect your development board before you press this button. It will fail otherwise.
In the next window you have to choose the binary.
After programming you should see a similar result as in the video below. Every half second the LED changes it’s state.
This example showed how to toggle a LED continuously using the automatic code generation tool of ST Microelectronics. As you saw this is very easy and straightforward. The STM32CubeMX tool does all the initialization which is a huge advantage in implementation time and effort. As always, if you have any questions please ask in the comments, I will answer them as soon as possible. Also if there are any improvements, please tell me.
The next blog post will be about further functions of the GPIO HAL driver. I am looking forward seeing you there.