NUCLEO-F103RB
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, 1 PWM Timer, 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 and TIM8 : 16-bits each TIM2, TIM3, TIM4, TIM5 : 16-bits each TIM9, TIM10, TIM11, TIM12, TIM13, TIM14 : 16-bits each TIM6 and TIM7 : 16-bits each, no external pins, may be used with DAC 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