Getting Started With STM32L476
Getting Started With STM32L476
By ShawnHymel
As you can see, ST has 8-bit microcontroller units (MCUs), 32-bit microprocessor units (MPUs), 32-bit
MCUs, and 32-bit MCUs designed for automotive use. For now, we will focus on the 32-bit MCUs.
Additionally, you can see that the 32-bit MCUs (non-automotive) are divided up into 4 categories:
Mainstream, Ultra-low-power, High-performance, and Wireless. This should help you figure out which
microcontroller you should use depending on your application(s). If you are just starting out, I
recommend sticking with the Mainstream line to learn the ropes.
Within the Mainstream line, you have a number of options. At the time of this writing, you can choose
among:
STM32F0 Series: Based on the ARM Cortex-M0 architecture. Inexpensive and a good place to start
if you’re coming from the 8- and 16-bit microcontroller world.
STM32F1 Series: Based on ARM Cortex-M3. These microcontrollers generally have more speed,
memory, and peripherals than their Cortex-M0 cousins.
STM32F3 Series: Based on ARM Cortex-M4. The M4 architecture is very similar to the M3
architecture with added digital signal processing (DSP) functions, such as a hardware floating-
point unit (FPU) and specialized assembly instructions (e.g. multiply-accumulate).
STM32G0 Series: Based on ARM Cortex-M0+, which works similarly to M0, but has some extra
features to allow for low-power operation.
STM32G4 Series: Based on ARM Cortex-M4. Similar to the F3 with even more power: up to 170
MHz. USB Type-C is also available on many of the G4 series.
ST has worked to make transitioning among its lineup as seamless as possible. Microcontrollers that
come in the same package are often pin-for-pin compatible. If you are working with an STM32F0 and
find that you are running out of resources in the controller, you can (in most cases) drop a F1 series
with the same package in its place on your board, and it will just work. ST’s HAL libraries also make
this transition seamless, as it abstracts away most direct register reading and writing.
Welcome, Nucleo
Once again, the naming convention of the Nucleo line can be slightly daunting. The 3 pinout versions
are referenced by the number of pins:
Nucleo-32: Breadboard-compatible development boards useful for learning and small projects
Nucleo-64: Arduino-like boards with the Arduino pinout. Can be used with Arduino shields.
Nucelo-144: More pins than you can shake a stick at. These boards often include the most
powerful and largest of the STM32 microcontrollers. Note the double row Arduino-compatible
headers, which allow the Nucleo-144 to accept Arduino shields.
Note that not every STM32 part has an associated Nucleo board. This chart on ST’s site offers a
useful visual for choosing the right Nucleo board.
All of the Nucleo boards can be programmed using assembly, C, or C++ with the GNU ARM Toolchain
(in any number of IDEs). Most of them have support in ARM’s mbed online editor/compiler. Some of
them even have Arduino and PlatformIO support. Similarly, keep an eye on the CircuitPython list of
supported Nucleo boards.
You can use any Nucleo board to complete this tutorial. I will be showing the Nucleo-L476RG, as it is
the only STM32 board supported by the DigiKey IoT Studio at the moment (which I plan to show in a
later tutorial).
Installing STM32CubeIDE
Until recently, Atollic’s TrueSTUDIO and AC6’s
System Workbench for STM32 were the two
primary, professional, Eclipse-based integrated
development environments (IDEs) that were
supported for STM32 development. In 2017, ST
acquired Atollic and has since released a new
IDE that combines TrueSTUDIO and the
STM32CubeMX graphical tool. This new IDE is
called STM32CubeIDE, and it’s what ST
recommends for new developments.
To begin, navigate to the STM32CubeIDE page
and download the installer for your operating
system (at the time of this writing, I am using
STM32CubeIDE v1.0.1). Note that you will need
to sign up for an account on ST’s site (free, but
requires an email address). Follow the
installation process, accepting all the defaults.
Select File > New > STM32 Project. You’ll be presented with a Target Selection window. Select
the Board Selector tab (as our Nucleo is an officially supported development board), and search for
“Nucleo-L476RG” (or your Nucleo’s name) in the search bar. You should see the Nucleo board appear
in the center pain. Click on the Nucleo-L476RG name in the lower, middle pane to select it, and
click Next.
Give your project a name, like “nucleo-l476rg-blinky” and leave the other options at their defaults.
Click Finish.
You will be asked to initialize all components in their default mode. Click Yes. If you are working with
a bare chip (instead of a Nucleo board), you might want to click No here to have better control over
which peripherals are on by default.
You will then be asked to open the STM32CubeMX perspective. Once again, click Yes.
A perspective in Eclipse is a set of windows, panes, and visuals that take up the IDE in support of a
particular feature or programming mode.
After that, you should have the CubeMX view open, showing a pinout of your chosen STM32 part
(notice that this is the microcontroller and not the whole Nucleo board).
By default, you should have the peripherals and pins enabled to support the bare minimum of Nucleo
board functionality (LED, button, oscillators, and USART).
At this point, we’re ready to code. However, note that the CubeMX offers a powerful, graphical way to
initialize peripherals and pins on your microcontroller. If you click on a pin, you get a list of peripherals
that pin supports. If you click on one, you can enable the peripheral on that pin. For example,
clicking GPIO_Output will turn that pin into an output (ready to toggle some digital logic).
We don’t need any other pins right now (the onboard LED is already enabled for us). If you’ve enabled
some features on pins, simply click on that feature (in the drop-down menu after clicking on a pin) to
disable it.
Click File > Save, and you will be asked to generate code. Click Yes.
Programming Blinky
In the file viewer on the left side, click on Src > main.c to open main code of our project. In the code
section, scroll down to find the int main(void) function. This is the entry point to our program. You will
see a number of automatically generated function calls that assist in setting up our system clocks
and peripherals.
You will also see a number of comment guards (labeled with BEGIN and END, as highlighted in the
screenshot above). Generally, you will want to write your user code in between the BEGIN and END
part of these guards. If you ever need to change something in the CubeMX graphical tool (double-click
on the .ioc file in your project to open the tool), you will need to regenerate code. Any code you write
between these comment guards will persist when you update the generated code.
Inside the while(1) loop, add the following two lines:
Copy Code
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
This is the actual blinky code: we’re telling GPIO Port A, Pin 5 (PA5) to toggle every 1000 ms. If you
look above the while(1) loop, you will see the following function call:
Copy Code
MX_GPIO_Init();
Find this definition (below in main.c), you will see how the Port C clock was enabled and how PC5
(also assigned the name “LD2” to match with the board’s LED) was configured to be an output. The
MX_GPIO_Init() function was automatically generated from the CubeMX graphical tool we used
earlier.
Your finished main() function should look like the following:
Copy Code
int main(void)
{
/* USER CODE BEGIN 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
/* USER CODE END WHILE */
At the time of this writing, there are no good online tools to help you navigate the available HAL
documentation from ST. Unfortunately, the documentation exists in a series of PDFs that you must
read or search through. The best place I have found to download these PDFs is from ST’s STM32Cube
MCU & MPU Packages page.
Scroll down to the graphic of the various available families. Each family name (F0, G0, F1, etc.) can be
clicked on to take you to that family’s page. If you’re following along with the Nucleo-L476RG, click
on L4. In the Resources tab, find the PDF labeled Description of STMxx HAL and Low-level
drivers (where xx is the family name of your part, such as L4). Download it to see all the available HAL
functions for your particular part.
Note that most of the HAL functions are the same among all of the STM32 parts. This helps keep
your code portable when moving to a new family. However, if your part lacks a particular feature (e.g.
touch sensing), the HAL functions will not be available.
When asked about switching perspectives, click Switch. You should get a new perspective with a new
toolbar at the top of your IDE. Click the Resume button.
The green LED on your Nucleo board (labeled LD2) should begin to flash on for 1 second and off for 1
second.
If you double-click on a line number (e.g. 102 as shown in the screenshot below), you can add a
breakpoint (shown by the hook-like symbol to the left of the line number).
The code will stop execution at this line. You can then use the Step Into, Step Over, and Step
Return buttons (to the right of the Stop button.
To step through lines of code, one at a time.
Step Into: If you are currently on a function call, go into that functions definition to execute lines of
code one at a time. If not on a function call, execute the line of code.
Step Over: If you are currently on a function call, execute all the code within that function without
going into the function’s definition. If not on a function call, execute the line of code.
Step Return: If you are currently inside a function definition, execute the rest of the code in that
function and return from the function.
Feel free to play around with these debugging features to see how powerful a real step-through
debugger can be.
Resources
Overview of DigiKey’s STM32
offerings: https://www.digikey.com/en/product-highlight/s/stmicroelectronics/stm32-overview
DigiKey’s Nucleo offerings: https://www.digikey.com/en/product-highlight/s/stmicroelectronics/
nucleo-development-boards
Download STM32CubeIDE: https://www.st.com/en/development-tools/stm32cubeide.html