NUCLEO-F103RB: Difference between revisions

From Embedded Workshop
Jump to navigation Jump to search
No edit summary
 
(21 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The NUCLEO-F103RB development board uses the STM32F103RBT6 as the target processor.  (The is the same processor used on "Blue Pill" boards.)
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.<br>
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.<br>
  This development board functions well in at least three development environments:
  '''This development board functions well in at least three development environments:'''
  1) Arduino & Arduino IDE using the STM32 processor plug-in
  1) Arduino & Arduino IDE using the STM32 processor plug-in
  2) MBed - The on-board STM32 loader / debugger supports loading web site created binaries
  2) MBed - The on-board STM32 loader / debugger supports loading web site created binaries
     See https://os.mbed.com/
     See https://os.mbed.com/
  3) STMicro's STM32CubeMX / Keil uVision or STMicro's new STM32CubeIDE
  3) STMicro's STM32CubeIDE
     See https://www.st.com/en/development-tools/stm32cubeide.html
     See https://www.st.com/en/development-tools/stm32cubeide.html
  I prefer STMicro's environment, allowing me easy access to peripherals, registers,
  I prefer STMicro's environment, allowing me easy access to peripherals, registers,
Line 11: Line 11:


[[File:NUCLEO_large.jpg|right|thumb]]
[[File:NUCLEO_large.jpg|right|thumb]]
'''Processor: STM32F103RBT6'''
==Processor: STM32F103RBT6==
Arm® Cortex®-M3 core
  128KB Flash
  128KB Flash
  20KB SRAM
  20KB SRAM
Line 20: Line 21:
   and as such, has the following peripherals:
   and as such, has the following peripherals:
  3 USARTs
  3 USARTs
  3 16-bit timers
  4 16-bit timers: TIM1, TIM2, TIM3, TIM4
  2 SPIs, 2 I2Cs, USB, CAN, 1 PWM Timer, 2 ADCs
  2 SPIs, 2 I2Cs, USB, CAN, 2 ADCs
  Notes:
  Notes:
     "Low-density device" has fewer peripherals.
     "Low-density device" has fewer peripherals.
Line 28: Line 29:
<strong>Hardware</strong><br>
<strong>Hardware</strong><br>
* Green LED, LD2, connected to PA5, illuminates when driven high
* Green LED, LD2, connected to PA5, illuminates when driven high
* Blue PushButton, B1, connects to PC13, grounding the signal when pressed
* 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)
* 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
* 8MHz HSE, is provided by the 8MHz crystal oscillator from the attached ST-Link, into PD0
Line 35: Line 36:
https://www.st.com/en/evaluation-tools/nucleo-f103rb.html<br>
https://www.st.com/en/evaluation-tools/nucleo-f103rb.html<br>


<strong>Firmware</strong><br>
==Firmware==
https://www.st.com/en/evaluation-tools/nucleo-f103rb.html
https://www.st.com/en/evaluation-tools/nucleo-f103rb.html
https://www.st.com/en/embedded-software/stm32cubef1.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
ST Website for the STM32F1 family: http://www.st.com/stm32f1


<strong>Getting Started</strong><br>
==New Project - Blinky==
* Install STM32CubeMX - https://www.st.com/en/development-tools/stm32cubemx.html
Create a New STM32CubeIDE Project - Blinky
* Install Keil uVision5 - Keil MDK Keil Pack installer: https://www.keil.com/dd2/st/stm32g031j6mx
  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
  1 Open STM32CubeMX
  3 Since I have several STM32 boards, I like to have the board name in the name of the project
2 Create '''New Project''' using "Start My project from ST Board" selector button
  I used: "NUCLEO-F103RB_Blinky" as the project name
  3 In the "Commercial Part Number" box, enter '''NUCLEO-F103RB'''
  4 Select "C" Executable, STM32Cube Project Type, Finish
  4 The board will display in the lower right part of the screen.  Select the board.
  5 Initialize all peripherals with their default Mode ? - Yes
  5 Click on '''Start Project''' in upper right corner of window
6 Device Configuration Tool editor is associated with Device Configuration Tool perspective.
  6 A dialog will be displayed, asking "Initialize all peripherals with their default Mode ?"
  Do you want to open this perspective now?  (Select Yes to see what's configured)
    Select '''Yes'''
  7 Using the '''Clock Configuration''' tab, a 64MHz SYSCLK is configured by default.  This can be adjusted to 72MHz if desired.
  7 Under "Project Manager Tab", Linker Settings, I set both Minimum Heap Size and Minimum Stack Size to 0x800 (2K bytes each)
  8 Using the '''Project Manager''' tab, give the project a name.  Something like '''"Blinky"''' will work well.
  8 On the left, Project Explorer window, Open Core->Src->main.c
  9 Within this same tab, select '''MDK-ARM''' for "Toolchain/IDE".  This instructs the Keil uVision application to be used.
  Note: If you examine the source code, you will see that the following functions get called:
10 Select '''GENERATE CODE''' button in upper right corner.
  * HAL_Init()
    (You may get a dialog box indicating you are missing some dependencies.  Select "Yes" to download them now.)
  * SystemClockConfig()
11 Select '''Open Project''' when prompted.
  * MX_GPIO_Init()
    (Keil may need to run it's package installer if it doesn't have support for the board.  This will take some time.  Don't click anything!)
  Then, the code enters an empty while loopUsing the JTAG/SWD debugger, we can build, run, and debug the code,
  12 Within Keil IDE, before we make any changes / additions to the code, let's make sure it buildsClick on '''Project''' -> '''Build Target'''
  but it will be rather boring...
    You can use the short-cut icon, available in the tool-bar, to '''Build(F7)'''
   
  13 Within the project view, open the project, and then the Application/User/Core folder and then double click '''main.c'''
9 Find the infinite loop inside the main() function, and add the following two bold lines of code:
  14 The LED GPIO should already have initialization code within '''MX_GPIO_Init()'''.
    Find the infinite loop inside the main() function, and add the following two {{Highlight|highlighted lines of code:}}
/* Infinite loop */
 
/* USER CODE BEGIN WHILE */
  /* Infinite loop */
while (1)
  /* USER CODE BEGIN WHILE */
{
  while (1)
  '''HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);'''
  {
  '''HAL_Delay(500);'''
{{Highlight|  HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
  /* USER CODE END WHILE */
    HAL_Delay(500);}}
    /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
}
   
   
    /* 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.
  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.
   
   
  14 Click Build (F7)
  10 Click the Hammer Icon for "Build"
  15 Click Download (F8)
  The program will be compiled, linked, and located to run on your NUCLEO-F103RB
16 At this point the board should now contain your code.  Press the reset button to watch it run.
  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'''<br>
==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)<br>
'''See:''' https://en.wikipedia.org/wiki/Servo_control and  https://en.wikipedia.org/wiki/Servo_(radio_control)<br>
This assumes the instructions from "Getting Started" have already been performed...
This assumes the instructions from "Getting Started" have already been performed...
Line 91: Line 94:
  1) Looking at the PCBA, I see the Arduino connector set and the PWM marking for Arduino D6
  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
  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 {{Highlight|TIM2_CH3}}.
  3) Select PB10 using STM32CubeMX, Pinout & Configuration tab.  From the drop-down menu, choose '''TIM2_CH3'''.
  4) Select Timers ->TIM2.
  4) Select Timers ->TIM2.
  4.1) Change Channel3 from '''Disable''' to {{Highlight|PWM Generation CH3}}
  4.1) Change Channel3 from '''Disable''' to '''PWM Generation CH3'''
  4.2) Set "Clock Source to "Internal Clock"
  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.3) Set Prescaler (PSC - 16 bits value) to "72-1"  (This will reduce our 72MHz SYSCLK to 1MHz (1us period))
  4.4) Set Counter Period to "20000-1" (This configures the period to be 20,000us long - 20ms / 50Hz)
  4.4) Counter Mode: Up
  4.5) Set Pulse (16 bits value) to 1500  (This configures the pulse width to 1500us / 1.5ms
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
  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,
  6) If you have the Arduino D6 pin connected to your RC-Servo control signal pin,
Line 104: Line 108:
   /* Infinite loop */
   /* Infinite loop */
   /* USER CODE BEGIN WHILE */
   /* USER CODE BEGIN WHILE */
   {{Highlight|// Initialize TIM2_CH3, for PB10 (Arduino D6)
   '''// Initialize TIM2_CH3, for PB10 (Arduino D6)'''
   HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);}}
   '''HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);'''
   while (1)
   while (1)
   {
   {
Line 131: Line 135:
     The '''while (1) loop''' will create multiple pulse widths, causing the servo to move to five distinct positions.
     The '''while (1) loop''' will create multiple pulse widths, causing the servo to move to five distinct positions.


'''Arduino IDE Support'''<br>
==Arduino IDE Support==
Using the Arduino Board Manager for the "duino" family<br>
Using the Arduino Board Manager for the "duino" family<br>
https://www.instructables.com/id/Quick-Start-to-STM-Nucleo-on-Arduino-IDE/<br>
https://www.instructables.com/id/Quick-Start-to-STM-Nucleo-on-Arduino-IDE/<br>
http://www.emcu.eu/2017/03/13/how-to-use-stm32-and-arduino-ide/<br>
http://www.emcu.eu/2017/03/13/how-to-use-stm32-and-arduino-ide/<br>
<br>
 
===[[External STLink V2]]===
==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==
<strong>External STLink V2:</strong>  
<strong>External STLink V2:</strong>  
https://www.st.com/resource/en/user_manual/dm00026748-stlinkv2-incircuit-debuggerprogrammer-for-stm8-and-stm32-stmicroelectronics.pdf<br>
https://www.st.com/resource/en/user_manual/dm00026748-stlinkv2-incircuit-debuggerprogrammer-for-stm8-and-stm32-stmicroelectronics.pdf<br>
<br>
<br>

Latest revision as of 13:07, 14 June 2024

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