STM32 Part 1. How to blink an LED
Greetings!
This article opens a series of articles on programming STM32 microcontrollers for beginners.
Today I will tell you how to write an LED blink in two ways using tools that are hard to find in 2023
Tools: Iron
BlackPill or BluePill Board
Programmer ST-LinkV2
Downloading the Development Environment
To set up clocking and peripherals, we will use ST CubeMX. We will write the code in Keil. Cube MX can be downloaded Hereand Keil Here. To download CubeMX you will need to register on the ST website To download Cube MX, the link to the Telegram post is relevant at the time of writing and has already lived for six months. Installation does not require special knowledge, I will not describe its process, but I can answer questions in the comments. If you have Mac OS or Linux, then Here you can download CubeIDE – Eclipse similar development environment from ST with integrated CubeMX (if you do not live in Russia or know how to use Tor Browser and VPN), but the article will last until the second coming if I describe the whole process for all development environments, so I will just specifically mention the critical points when it is required.
Creating a project in CubeMX
Open CubeMx and see the following window
To create a new project, select “Access to MCU selector”. After a short (relative to the period of rotation of the earth around its axis) loading of the components, a new window will open, where we are asked to select the microcontroller we are interested in.
Important note: In the article, here and below, examples will be given for programming on BluePill and BlackPill boards, as the most common among beginners. You can have any other board – NUCLEO, DISCOVERY, but the process of setting up peripherals, clocking and programming will not fundamentally differ from those given in the article.
“Take the black pill…”
If you have a BlackPill board, you need to choose the STM32F401CC or STM32F411CC option – the laser markings are usually quite clearly engraved on the stone itself.
For BluePill:
After selecting the chip you need, click “Start Project” in the upper right corner and get into the “Pinout & Configuration” window (Figure 5). Here, in the System Core -> Sys section, in the “Debug” item, select “Serial Wire” and on the right we see two pins of the microcontroller, highlighted in green. These are the pins of the debugging interface, through which the firmware and debugging of programs will take place.
Now turn on pin 13 of port C in GPIO Output mode – General purpose input in output mode – click on the leg with the mouse, select “GPIO Output” (Figure 6)
For BluePill, the legs are the same – also select pin 13 of port C
Now go to the “Project manager” tab and get into the “Project” menu (Figure 7)
In the “Toolchain / IDE” item, select MDK – ARM for Keil or STM32CubeIDE for the appropriate option. Further I will use Keil, I choose it.
For convenience in further work, open the tab “Code generator” (Figure 8, left column, second button) and check the box next to “Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral “. What it gives is that each peripheral module of the microcontroller will be initialized not in main.c, but in its own file, which improves readability in large projects.
Now press the “Generate code” button (Figure 9)
After successfully creating the project, open it (Figure 10)
Introduction to the project
Now consider the default project window (Figure 11) 1 – project tree, 2 – compiler output, 3 – main window, which displays the current open document, 4 – project build button (F7), 5 – microcontroller firmware (F8), 6 – Project settings, 7 – switch to debug mode (Ctrl+F5)
Let’s move the console under the project tree so as not to take up useful space for code
Let’s expand the “Application/User/Core” folder and open the main.c file (Figure 13) Ctrl + wheel allows you to change the font size.
Consider what is here: first, the main.h file and the gpio.h file are connected, if the separate generation of peripheral files is checked. Next, the prototype of the peripheral configuration function is declared and then we get into the main () function, in which the HAL (Hardware Abstraction Layer) framework and clocking with I/O ports are initialized (Figure 14)
Kodim
In the main() function, after initialization, which occurs once, there is an infinite while (1) loop in which our program will be executed. Pay attention to the USER CODE sections – if you write code inside them, then when you regenerate the project from CubeMX, your code will not be overwritten.
Let’s add to the USER CODE BEGIN 3 section turning on the LED on the GPIOC 13 leg, waiting for 500 ms and turning it off (Figure 15)
Line 98: A number equal to
1 << 13;
// или в бинарном выражении
0010 0000 0000 0000
Since the bits are numbered from right to left (and from zero), it turns out that we put a “1” in the 13th bit of the ODR register
Line 99: Called the HAL_Delay() function with argument 500, where “500” is milliseconds, i.e. 500 ms do nothing
Line 100: Recall the number (1<<13) and invert it
1 << 13;
// или в бинарном выражении
0010 0000 0000 0000
// когда делаем ~(1<<13), мы побитово инвертируем число в скобках
1101 1111 1111 1111
now we multiply the current value of the register bit by bit by the resulting number, i.e. all the bits that were, retain their value, except for the 13th, it was multiplied by zero and reset
0010 0000 0000 0000
// когда делаем ~(1<<13), мы побитово инвертируем число в скобках
1101 1111 1111 1111
//
the LED at this moment lights up, because on the BlackPill board the LED is pulled up by a resistor to 3.3V
Line 101: again waiting 500ms
Now you can press F7 to build the project, it should look like this
Now configure the debugger, click “Settings”
And change the compiler to 6.16 – it is much faster and go to the “Debug” tab (Figure 18)
In the “Debug” tab, select ST-Link and confirm the choice
Now you can connect the programmer to the board, insert it into the USB of the computer and flash it by pressing F8. If it doesn’t work right away, double-check that the contacts of the programmer and the board are not mixed up. After the firmware, you need to press the Reset button on the board so that the LED starts blinking
I really hope that you succeeded, because next we will try to do the same, but by changing a couple of lines of code and delay values from 500 to 100 ms (Figure 20):
Now on line 98 there is a function that turns on pin 13 of the GPIOC port.
On line 99, “500” was changed to “100”.
On line 100, the corresponding pin turns off.
On line 99, “500” was changed to “100”.
We will build the project again using F7 and sew the project by pressing F8, restart the MK by pressing RESET
If everything is done correctly, the LED will blink much more often.
Homework
In order to invert the value of a bit, there is an XOR operand
^=
Try using it for the case with registers to reduce the number of lines of code in while(1) to two.
Thank you all for reading the publication, I look forward to your questions and correction of inaccuracies in the comments or by email mailto:mgostev.it@gmail.com