Page 1 of 1

STM32 Programming. Part 1-2: Documentation

Posted: 14 Oct 2023, 04:21
by Oleg
The best way to start getting to know any thing is to start with the manual. In some cases everything is clear, in others - "hmm, nothing works, I guess I should read the manual after all". Microcontrollers are quite complex devices, and without reading the documentation you will certainly not be able to do anything useful with them, though....

In this article we will look at how the manufacturer's official website organizes the documentation for STM32 microcontrollers, in particular the STM32F1 series.

After some AVR-oks, you may be slightly shocked by the number of different PDFs on STM32 microcontrollers. Where to look first of all? How to use it? What the hell is going on? At first glance nothing is clear. So I decided to make a small review of the world of documentation on these wonderful microcontrollers. I will emphasize on STM32F103C8T6, as I plan to write some lessons on how to use this particular stone.

The main documents for STM-ki are the following:
  1. Datasheet
  • Reference manual
  • Programming Manual
  • Errata Sheet
Datasheet

Datasheet contains information about the presence of certain peripherals in a particular MCU, pinout, electrical characteristics and chip labeling for STM32F103x8 and STM32F103xB, i.e. for these ones, which are circled with a red rectangle:
image.png
image.png (316.31 KiB)
Viewed 2561 times
Not bad, one datasheet for 8 microcontrollers.

The main things in the Datasheet

First of all you should pay attention to section 7. Ordering information scheme, which specifies what each symbol in the marking means. For example, for STM32F103C8T6: LQFP-48 case, 64Kb flash, temperature range -40 to 85 °C.
image.png
image.png (33 KiB)
Viewed 2561 times
Next is 2.1 Device overview. It has a table that tells you what peripherals a particular microcontroller has and how many:
image.png
image.png (65.07 KiB)
Viewed 2561 times
The main difference between the microcontrollers from different columns is the number of legs and the amount of flash, the rest is the same. A small exception is the first column of Tx versions: these microcontrollers have fewer SPI, I2C and USART modules. Peripherals are numbered from one: that is, if in STM32F103Cx we have 2 SPIs, they are named SPI1 and SPI2, while in STM32F103Tx we have only SPI1. Since we have Datasheet for STM32F103x8 and STM32F103xB microcontrollers, this table is valid only for these models. For example, STM32F103C8 or STM32F103CB correspond to this table, but STM32F103C6 does not, there is a separate datasheet for it.

Section 2.2 Full compatibility throughout the family states that STM32F103xx devices are programmatically, functionally and pin-to-pin (for the same packages) compatible.

In the reference manual there is a division into the following "types" of microcontrollers: STM32F103x4 and STM32F103x6 are designated as low-density devices, STM32F103x8 and STM32F103xB as medium-density devices, STM32F103xC, STM32F103xD and STM32F103xE as high-density devices. Low-density devices have less Flash and RAM memory, timers and peripherals. High-density devices have more Flash and RAM memory, as well as have additional peripherals such as SDIO, FSMC, I2S and DAC, while remaining fully compatible with other members of the STM32F103xx family. That is, if at some stage of development it became clear that the selected microcontroller is not enough to realize all the possibilities, you can painlessly choose a more advanced stone without the need to rewrite all the existing software, and if the new stone will be in the same case, there is no need to re-design the printed circuit board.

Reference manual

Let's move on. Reference manual contains a detailed description of all peripherals, registers, offsets, and so on. This is the main document that is used when creating firmware for the microcontroller. Reference manual is compiled for a large group of microcontrollers, in our case for all STM32F10xxx, namely STM32F101xx, STM32F102xx, STM32F103xx and STM32F105xx/STM32F107xx. But STM32F100xx are not included in this RM, there is its own for them.

The main thing in the Reference manual

As mentioned above, the reference manual divides the microcontrollers into the following "types": low-, medium-, high-density and connectivity.
line. Glossary 2.3 explains who is who:
  • Low-density devices are STM32F101xx, STM32F102xx, and STM32F103xx microcontrollers that have Flash memory sizes between 16 and 32 Kbytes.
  • Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx, with Flash memory size between 64 and 128 Kbytes.
    • High-density devices
    are STM32F101xx and STM32F103xx, flash memory size between 256 and 512 Kbytes.
  • XL-density devices are STM32F101xx and STM32F103xx, flash memory size between 768 Kbytes and 1 Mbyte.
  • Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
Our STM32F103C8T6 is a Medium-density device. It will be useful to know this when studying peripherals, for example, there are separate sections about RCC for Low-, medium-, high- and XL-density devices, and Connectivity line devices.

Next, let's turn to Tabe 1. It notes which section applies to a particular type of microcontrollers. In our case it is Medium-density STM32F103xx:
image.png
image.png (198.95 KiB)
Viewed 2561 times
Then it's simple: there are a bunch of sections, each with a description on a specific peripheral and its registers

Programming Manual

The Programming Manual is not a document of the first necessity at the very beginning of the introduction to STMs, but it is very important when studying these microcontrollers in depth. It contains information about the processor core, instruction system and core periphery. It is not the same periphery described in the Reference manual. It includes:
  • System timer - system timer
  • Nested vectored interrupt controller - priority interrupt controller
  • System control block
  • Memory protection unit
Once we start to familiarize ourselves with interrupts in STM32, we will need section 4.3 Nested vectored interrupt controller (NVIC). And the system timer is a very cool thing that will be useful in some RTOS or for creating program timers.

Errata Sheet

Errata Sheet is a collection of all known hardware glitches and glitches of microcontrollers and tips on how to get around them. Quite a fun document Before using any peripheral, I suggest you take a look. It may help to reduce the number of lost nerve cells when debugging your miracle firmware that doesn't want to work in any way

STM32 Programming. Part 2: IAR + CMSIS

Posted: 14 Oct 2023, 04:47
by Oleg
This is the second part of the series of articles about STM32F1xxx microcontrollers. Here we will talk about CMSIS library, why it is needed, where to get it and how to connect it to your project.

Introduction

The Cortex Microcontroller Software Interface Standard (CMSIS) contains a description of all microcontroller registers, a table of interrupt vectors, and some starting code that is executed before passing control to the main() function. Generally speaking, CMSIS is an optional component of the project, however, you will have to take care of a huge number of things yourself. In addition, this library allows you to write somewhat portable code from one microcontroller, to another.

Downloading CMSIS

At the moment CMSIS is supplied together with STM32Cube MCU Package. You can download it on the page of the selected microcontroller (where you downloaded datasheet, Reference manual and so on), it is called STM32CubeF1:
image.png
image.png (30 KiB)
Viewed 2558 times
You need to register on their site to download it. Why did they do that?:\ I'll leave the link to the archive at the end of the article, so as not to bother with all these registrations. But still it's better to download the actual version of the library on the official site. The archive weighs quite a lot, 97 meters.

Creating a project in IAR ARM

Now we do a little preparatory work to create a project in IAR ARM. Start IAR Embedded Workbench environment:
image.png
image.png (48.4 KiB)
Viewed 2558 times
In IAR-e all projects (Projects) are inside a Workspace, and the number of projects in one Workspace can be several.

Choose Project->Create New Project....
image.png
image.png (71.54 KiB)
Viewed 2558 times
In the opened window select the project type: C->main:
image.png
image.png (8.6 KiB)
Viewed 2558 times
Click OK, type some name (in my case test_proj) and save in some folder.

The project is created. After that choose File->Save All and in the opened window type the name of our Workspace, it can be named the same way as the project.

Now we need to customize the project for a specific microcontroller, namely STM32F103C8. Right-click on the name of our project and select Options... item.
image.png
image.png (34.31 KiB)
Viewed 2558 times
In the General Options section on the Target tab, select our microcontroller:
image.png
image.png (25.65 KiB)
Viewed 2558 times
Next, we insist on the compilation optimization level. When debugging, I sometimes encountered some problems with high optimization level, so I advise you to set None or at least Low on the Optimizations tab in C/C++ Compiler:
image.png
image.png (25.88 KiB)
Viewed 2558 times
Putting all source files in the root of the project is not a good idea, in the future it will be difficult to navigate among the pile of files, so for CMSIS we will create a folder with the same name CMSIS . But we need to specify to the compiler the path where to look for the sources. To do this, on the Preprocessor tab we need to specify the path to the folder with the library. In order not to specify absolute paths, IAR has a variable $PROJ_DIR$, which stores the path to the folder with the project:

Code: Select all

$PROJ_DIR$\
$PROJ_DIR$\CMSIS\
The first line points to the root of the project, where main.c is located, it's kind of unnecessary, but let it be, the second line points to the future folder with CMSIS. Pay attention to the tab scroll arrows, highlighted in blue:
image.png
image.png (26.23 KiB)
Viewed 2558 times
Now the debugger. In the Debugger section of the Setup tab select ST-LINK, which is included with the Discovery debugging boards:
image.png
image.png (23.32 KiB)
Viewed 2558 times
and on the Download tab check the Use flash loader(s) checkbox:
image.png
image.png (22.95 KiB)
Viewed 2558 times
After that in the ST-LINK section select the type of connection interface, we have SWD:
image.png
image.png (22.84 KiB)
Viewed 2558 times
Phew, the project is set up. Click OK to save the changes.

After that we go to the project directory and create a CMSIS folder, where we will put the CMSIS library files:
image.png
image.png (62.65 KiB)
Viewed 2558 times
CMSIS library

The archive with STM32CubeF1 has been downloaded and unzipped. It contains many different things: documentation, examples for debug boards, HAL drivers and CMSIS itself, which we need. CMSIS is located in .\STM32Cube_FW_F1_V1.6.0\Drivers\CMSIS.


First go to .\CMSIS/Device\ST/STM32F1xx/Include:
image.png
image.png (80.61 KiB)
Viewed 2558 times
We have a lot of .h files for different microcontrollers here, but we don't see anything like stm32f103x8.h. Let's open stm32f1xx.h. There is a thing like this there:

Code: Select all

#if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \
    !defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \
    !defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC)
  /* #define STM32F100xB  */   /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */
  /* #define STM32F100xE */    /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */
  /* #define STM32F101x6  */   /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */
  /* #define STM32F101xB  */   /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */
  /* #define STM32F101xE */    /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */ 
  /* #define STM32F101xG  */   /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */
  /* #define STM32F102x6 */    /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */
  /* #define STM32F102xB  */   /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */
  /* #define STM32F103x6  */   /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */
  /* #define STM32F103xB  */   /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
  /* #define STM32F103xE */    /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */
  /* #define STM32F103xG  */   /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */
  /* #define STM32F105xC */    /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */
  /* #define STM32F107xC  */   /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */  
#endif
Pay attention to the line:

Code: Select all

/* #define STM32F103xB  */   /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
Aha, STM32F103C8 is here. So for our microcontroller will fit the sources from the B version: STM32F103xB. Let's remember this. From this folder copy the following files to CMSIS of the project:

Code: Select all

stm32f1xx.h
stm32f103xb.h
system_stm32f1xx.h
Then go to .\CMSIS\Device\ST\STM32F1xx\Source\Templates and take the file system_stm32f1xx.c from here.

After that we need the startup file. Go to .\CMSIS\Device\ST\STM32F1xx\Source\Templates\iar. There is also a lot of files waiting for us and we are also looking for the one ending with xB: startup_stm32f103xb.s. Copy it to $PROJ_DIR$\CMSIS\.

Then go to .\CMSIS\Include and take these 3 files:

core_cm3.h
core_cmFunc.h
core_cmInstr.h


Since in STM32F103C8 microprocessor core Cortex M3, we take the corresponding sources.

Total 8 files:
  1. stm32f1xx.h
  • stm32f103xb.h
  • system_stm32f1xx.h
  • system_stm32f1xx.c
  • startup_stm32f103xb.s
  • core_cm3.h
  • core_cmFunc.h
  • core_cmInstr.h

This is how it should look like in the $PROJ_DIR$\CMSIS folder:
image.png
image.png (54.87 KiB)
Viewed 2558 times
Now these files should be added to the project browser in IAR. For convenience, let's create a group with the same name CMSIS. Right-click on the project name and select Add->Add Group.....
image.png
image.png (30.02 KiB)
Viewed 2558 times
Enter the name of the group and click OK:
image.png
image.png (3.15 KiB)
Viewed 2558 times
Then add the files from the CMSIS folder to the CMSIS group:
image.png
image.png (31.53 KiB)
Viewed 2558 times
In the dialog box that opens, select all files and click Open

The result is this:
image.png
image.png (13.78 KiB)
Viewed 2558 times
After that, open the file stm32f1xx.h and uncomment the stack with #define STM32F103xB:

Code: Select all

#if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \
    !defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \
    !defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC)
  /* #define STM32F100xB  */   /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */
  /* #define STM32F100xE */    /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */
  /* #define STM32F101x6  */   /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */
  /* #define STM32F101xB  */   /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */
  /* #define STM32F101xE */    /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */ 
  /* #define STM32F101xG  */   /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */
  /* #define STM32F102x6 */    /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */
  /* #define STM32F102xB  */   /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */
  /* #define STM32F103x6  */   /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */
#define STM32F103xB     /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
  /* #define STM32F103xE */    /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */
  /* #define STM32F103xG  */   /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */
  /* #define STM32F105xC */    /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */
  /* #define STM32F107xC  */   /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */  
#endif
Next, we write the following main:

Code: Select all

#include "stm32f1xx.h"

int main()
{
  return 0;
}
Choose Project->Make. If you have done everything correctly, you will get a message about successful compilation of the project:
image.png
image.png (31.22 KiB)
Viewed 2558 times
Here we have learned how to connect CMSIS to our project. In the next article we will continue studying STM32 microcontrollers