Getting Started with STM32: Difference between revisions

From Embedded Workshop
Jump to navigation Jump to search
No edit summary
No edit summary
Line 114: Line 114:
  If not yet enabled, enable it in the "Mode" section as "I2C"
  If not yet enabled, enable it in the "Mode" section as "I2C"
  In the "GPIO Settings" section, we want it to display '''PB8''' for I2C_SCL and '''PB9''' for I2C_SDA.
  In the "GPIO Settings" section, we want it to display '''PB8''' for I2C_SCL and '''PB9''' for I2C_SDA.
  If it doesn't, select the pin in the "Pin Name" field for I2C_SCL, and then select '''PB8''' in the Pinout view
  If it doesn't, go to the Pinout view on the right, select the '''PB8 pin''', and then select the '''"I2C1_SCL"''' function.
   Doing this will usually define both pins.  If not, repeat the process for I2C_SDA and PB9.
   Doing this will usually define both pins.  If not, repeat the process for '''PB9''', with function '''I2C_SDA'''.


<strong>Additional Resources:</strong>
<strong>Additional Resources:</strong>

Revision as of 07:19, 28 March 2022

Although this getting started class will work well for many of the STM32 processors and boards, we will focus on the NUCLEO-F103RB board with its STM32-F103RB processor.

64-Pin NUCLEO Board

  • Green LED, LD2, connected to PA5, illuminates when driven high
  • Blue PushButton, B1, connects to PC13, grounding the signal when pressed
  • 32,768Hz crystal oscillator, LSE, used for Real Time Clock (RTC)
  • 8MHz HSE, is provided by the 8MHz crystal oscillator from the attached ST-Link, into PD0
  • UART2 connects the target processor to the ST-Link, providing a USB COM port connection on the host computer. Uses PA2 for TX, and PA3 for RX.
  • ST-Link connects to TCK (PA14), TMS (PA13)

Board: https://www.st.com/en/evaluation-tools/nucleo-f103rb.html
Manual: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
Schematic: https://www.st.com/resource/en/schematic_pack/nucleo_64pins_sch.zip

Processor: STM32F103RBT6

* 128KB Flash
* 20KB SRAM
* 72MHz clock
* Single-cycle multiplication and hardware division
* 2.0 to 3.6 V application supply and I/Os
* Within this part series, this is considered a "Medium-density device",
  and as such, has the following peripherals:
* 3 USARTs
* 3 16-bit timers
* 2 SPIs, 2 I2Cs, USB, CAN, 1 PWM Timer, 2 ADCs
Notes:
   "Low-density device" has fewer peripherals.
   "High-density device" has more peripherals.

Software - Development Tools - IDE (I recommend creating an STMicro account)

Download the following tool(s) from STMicro:
https://www.st.com/en/development-tools/stm32cubeide.html

Installing STM32CubeIDE_1.9.0

* Allow the software to install at C:/ST/STM32CubeIDE_1.9.0
* When asked where to store project files, I recommend creating a path off of C:/Users/YourName/Documents
   Something like: C:/Users/YourName/Documents/STM32CubeIDE_1.9.0
   This allows you to find your projects and makes them easy to backup.

Create a New STM32CubeIDE_1.9.0 Project

1 Click "Start new STM32 project", then select the "Board Selector" tab
2 In the Commercial Part Number box, type "NUCLEO-F103RB", select the board, and then click "Next>" at the bottom
3 Since I have several STM32 boards, I like to have the board name in the name of the project
  I used: "NUCLEO-F103RB_Blinky" as the project name
4 Select "C++" (This allows both C and C++), Executable, STM32Cube Proect Type, Finish
5 Initialize all peripherals with their default Mode ? - Yes
6 Device Configuration Tool editor is associated with Device Configuration Tool perspective.
   Do you want to open this perspective now?  (Select Yes to see what's configured)

7 Under "Project Manager Tab", Linker Settings, I set both Minimum Heap Size and Minimum Stack Size to 0x400 (1K bytes each)
8 On the left, Project Explorer window, Open Core->Src->main.c
Note: If you examine the source code, you will see that the following functions get called:
 * HAL_Init()
 * SystemClockConfig()
 * MX_GPIO_Init()
 Then, the code enters an empty while loop.  Using the JTAG/SWD debugger, we can build, run, and debug the code,
 but it will be rather boring...

9 Find the infinite loop inside the main() function, and add the following two {{#if:|{{#ifexpr:({{#time:U|{{{3}}}}} - {{#time:U|now}}) > 0|highlighted lines of code:|highlighted lines of code:}}|highlighted lines of code:}}
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
{{#if:|{{#ifexpr:({{#time:U|{{{3}}}}} - {{#time:U|now}}) > 0|   HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
   HAL_Delay(500);|   HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
   HAL_Delay(500);}}|   HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
   HAL_Delay(500);}}
   /* USER CODE END WHILE */

   /* USER CODE BEGIN 3 */
 }
 
 NOTE:
 Be sure to always place your code between the USER CODE BEGIN and USER CODE END comments
 This will protect your code from being removed should you make changes using the STM32CubeMX again.

10 Click the Hammer Icon for "Build"
   The program will be compiled, linked, and located to run on your NUCLEO-F103RB
11 Click the Right Pointing Green Arrow Icon for "Run"
  The program will be downloaded to the device and begin execution.
  You should see LED2 blinking at this point.


Fix Eclipse's Small Icon issue

1 Find the installation folder for your STM32CubeIDE_1.9.0.
    For me, this is C:\ST\STM32CubeIDE_1.9.0\STM32CubeIDE
2 Open stm32cubeide.ini in your favorite text editor
3 Add the following bolded line of text in the -vmargs section:
 -vmargs
 -Dswt.autoScale=quarter
 -Dosgi.requiredJavaVersion=1.8
 -Dosgi.instance.area.default=


printf()

The printf() function is commonly used for "C" programming to output formatted text to a terminal.
This allows easy debugging in that variables, intermediate values, entering/leaving functions can
be monitored and status displayed with the printf() stdio library function.
The STM32 development environment provides an stdio printf() library function, but some
"connecting glue" is required to provide the desired output.
The printf() function calls _write() to perform an output function.
See the _write() function in syscalls.c.  This function was given the (weak) attribute, allowing
the function to be over-written (without causing a warning or error message.)
This default _write() function calls __io_putchar() to output one character at a time.
Redefining either function to write characters to a serial port will produce a functioning
printf().


I2C

We will use the upper right two pins on the Arduino header.
These are mapped as follows: D15: P8_8 (SCL) and D14: P8_9 (SDA)
By default, STM's pin selector will map I2C1 to different pins.
To change this, open the project's .ioc file, select "Pinout & Configuration" tab
Select Connectivity category, and then I2C1
If not yet enabled, enable it in the "Mode" section as "I2C"
In the "GPIO Settings" section, we want it to display PB8 for I2C_SCL and PB9 for I2C_SDA.
If it doesn't, go to the Pinout view on the right, select the PB8 pin, and then select the "I2C1_SCL" function.
  Doing this will usually define both pins.  If not, repeat the process for PB9, with function I2C_SDA.

Additional Resources:

Shawn Hymel - How to use printf() on stm32
Digikey Forum: Easily Use Printf On STM32
NUCLEO-F103RB Documentation - Mbed
XNUCLEO boards - Pinouts