NUCLEO-F103RB

From Embedded Workshop
Jump to navigation Jump to search

The NUCLEO-F103RB development board uses the STM32F103RBT6 as the target processor. (The is the same processor used on "Blue Pill" boards.) It was after playing with the "Blue Pill" boards that I decided I need a REAL STMicro development board. This board is a rock solid development board with on-board ST-Link loader / debugger, using an STM32F103CBT6.

This development board functions well in at least three development environments:
1) Arduino & Arduino IDE using the STM32 processor plug-in
2) MBed - The on-board STM32 loader / debugger supports loading web site created binaries
    See https://os.mbed.com/
3) STMicro's STM32CubeIDE
    See https://www.st.com/en/development-tools/stm32cubeide.html
I prefer STMicro's environment, allowing me easy access to peripherals, registers,
  and clock systems, with full access to every part of this system on chip.

Processor: STM32F103RBT6

Arm® Cortex®-M3 core
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
4 16-bit timers: TIM1, TIM2, TIM3, TIM4
2 SPIs, 2 I2Cs, USB, CAN, 2 ADCs
Notes:
   "Low-density device" has fewer peripherals.
   "High-density device" has more peripherals.

Hardware

  • Green LED, LD2, connected to PA5, illuminates when driven high
  • Blue PushButton, B1, connects to PC13, grounding the signal when pressed. Button signal has 4.7K and 0.1uF capacitor hardware filter
  • 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)

https://www.st.com/en/evaluation-tools/nucleo-f103rb.html

Firmware

https://www.st.com/en/evaluation-tools/nucleo-f103rb.html https://www.st.com/en/embedded-software/stm32cubef1.html

The firmware packages (including examples) installs in this directory:
C:\Users\UserName\STM32Cube\Repository

ST Website for the STM32F1 family: http://www.st.com/stm32f1

New Project - Blinky

Create a New STM32CubeIDE Project - Blinky
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" Executable, STM32Cube Project 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 0x800 (2K 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 bold lines of code:

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
  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.

PWM - Driving an RC Servo, 20ms period, 1.5ms initial pulse-width

See: https://en.wikipedia.org/wiki/Servo_control and https://en.wikipedia.org/wiki/Servo_(radio_control)
This assumes the instructions from "Getting Started" have already been performed...

1) Looking at the PCBA, I see the Arduino connector set and the PWM marking for Arduino D6
2) Looking at the MB1136.pdf schematic for this board, the D6 signal is mapped to PB10
3) Select PB10 using STM32CubeMX, Pinout & Configuration tab.  From the drop-down menu, choose TIM2_CH3.
4) Select Timers ->TIM2.
4.1) Change Channel3 from Disable to PWM Generation CH3
4.2) Set "Clock Source" to "Internal Clock"
4.3) Set Prescaler (PSC - 16 bits value) to "72-1"  (This will reduce our 72MHz SYSCLK to 1MHz (1us period))
4.4) Counter Mode: Up
4.5) Set Counter Period to "20000-1" (This configures the period to be 20,000us long - 20ms / 50Hz)
4.6) Set Pulse (16 bits value) to 1500  (This configures the pulse width to 1500us / 1.5ms
5) Select GENERATE CODE button in upper right corner. This will produce the code that will initialize the TIM2_CH3 accordingly
6) If you have the Arduino D6 pin connected to your RC-Servo control signal pin,
   you won't see any changes even after building and downloading the code.
7) Add the following lines of highlight code:  (1 line of code with 1 line for comment)
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 // Initialize TIM2_CH3, for PB10 (Arduino D6)
 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
 while (1)
 {
8) Build (F7), Download (F8), press reset button.  The Arduino D6 pin will begin creating the desired PWM pulse,
   causing the servo to center itself.
9) Add the following additional code to the while (1) loop:
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 // Initialize TIM2_CH3, for PB10 (Arduino D6)
 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
 while (1)
 {
    htim2.Instance->CCR3 = 1000; // 1.0ms
    HAL_Delay(1000);
    htim2.Instance->CCR3 = 1250; // 1.25ms
    HAL_Delay(1000);
    htim2.Instance->CCR3 = 1500; // 1.5ms
    HAL_Delay(1000);
    htim2.Instance->CCR3 = 1750; // 1.75ms
    HAL_Delay(1000);
    htim2.Instance->CCR3 = 2000; // 2.0ms
    HAL_Delay(1000);
    /* USER CODE END WHILE */
10) Build (F7), Download (F8), press reset button.
    The while (1) loop will create multiple pulse widths, causing the servo to move to five distinct positions.

Arduino IDE Support

Using the Arduino Board Manager for the "duino" family
https://www.instructables.com/id/Quick-Start-to-STM-Nucleo-on-Arduino-IDE/
http://www.emcu.eu/2017/03/13/how-to-use-stm32-and-arduino-ide/

STM32-F103 Timers

Trying to find a 32-bit timer for micro-second time measurements.  Examining the hardware timers available:
TIM1 : 16-bit each
TIM2, TIM3, TIM4 : 16-bits each
Note: Although documentation may mention other timers, they are NOT available on the F103RB.

It appears if we desire a 32-bit timer, we need to check if any of the above timers are cascadable - combine two
16-bit timers together with the first one feeding into the second.  The problem with this is that the "total count"
is contained in two 16-bit registers, that while reading, one can overflow producing an erroneous 32-bit result.
ST Micro App Note: https://www.st.com/resource/en/application_note/an2592-achieving-32bit-timer-resolution-with-software-expansion-for-stm32cube-and-standard-peripheral-library-stmicroelectronics.pdf

External STLink V2

External STLink V2: https://www.st.com/resource/en/user_manual/dm00026748-stlinkv2-incircuit-debuggerprogrammer-for-stm8-and-stm32-stmicroelectronics.pdf