
Explore the STM32 Cube framework, timers, PWM, CAN, low-power modes, and RTC with hands-on exercises on STM32 boards using Open STM32 system workbench.
Use the nucleo f446re STM32 development board by ST as the course’s basis, based on STM32F4x and STM32F446RE, with guidance on using similar boards and required driver and ST-LINK updates.
Power the board with a mini USB cable from your PC, observe red LED, and use blue user button and black reset button; download datasheet, reference manual, and schematic.
Install ST-Link drivers for your ST discovery or nucleo board to enable UART communication, using Windows 32/64-bit installers from ST, Ubuntu commands, and noting that Mac requires no driver.
Upgrade ST-Link firmware for V2 and V2-1 using the software on Windows, Mac, or Ubuntu. Connect the board, open update mode, and restart to complete the upgrade.
Choose your IDE for this course: STM32CubeIDE with cubeMX, or STM32 System Workbench with cubeMX. You may also use VS Code with debug plugin, though it is not yet covered.
migrate to stm32cubeide using version 1.19 for consistency, set up workspace and project, configure USART2 for virtual COM, and adopt a manual coding workflow while excluding code generator files.
Download OpenSTM32 System Workbench for STM32 for Windows, Mac, or Linux, choose the correct 32/64-bit installer, grant executable permission, and ensure Java runtime is installed.
Install and launch the OpenSTM32 System Workbench for STM32, including installing ST-Link drivers, configuring the workspace, and initializing the ARM toolchain.
Install STM32 CubeMX, download and log in, extract and install version 4.22, then open the CubeMX application, and regularly check for updates for STM32 F4 and F7 families.
Learn the STM32 cube project architecture using HAL driver APIs, not auto-generation, with CubeMX templates, CMSIS-Core, and peripheral driver files to test on hardware.
Create a hello world project for STM32 with CubeMX on the Nucleo F446RE board, generate code, and import it into the Mastering MCU2 workspace in Open STM32 System Workbench.
Understand the CubeMX generated project hierarchy: drivers, include, source, and startup files, plus CMSIS-core and HAL drivers. Build creates elf and bin binaries and enables hello world output over UART.
Explore how the stm32 cube framework uses the device hal and cmsis-core layers to drive peripherals like uart via hal_uart_transmit, with proper initialization order and cubeMX-generated setup.
Learn the STM32 cube framework program flow, starting with proper basic microcontroller initialization and clock setup, before calling peripheral HAL APIs to ensure correct peripheral timing and system clocks.
Learn how main.c, msp.c, and it.c coordinate with the stm32 HAL to initialize peripherals, start UART communication, and handle interrupts through callbacks, bridging application code with Cube HAL.
Understand the peripheral handle structure in STM32 Cube HAL, including instance and init parameters, and attach the handle to a peripheral using its base address.
Link a UART peripheral to its handle by initializing the handle’s instance with the peripheral base address and compute register addresses from the bus base and offset.
Explore the stm32 header file hierarchy, including stm32f4xx.h for the device family, f446xx.h for the specific MCU, and stm32f4xx_hal.h for cube hal APIs, plus how startup relies on system_init.
Learn how to download course projects from GitHub and import them into Eclipse, organize an original and a personal workspace, and build CAN and timer projects for testing.
Create a cube hal based project template in CubeMX for stm32f4, import into eclipse, replace auto generated files with main.c, msp.c, and it.c, and initialize HAL with HAL_Init().
Learn how to implement low level processor specific initializations in HAL_MspInit, including configuring the ARM Cortex-Mx priority grouping, enabling system exceptions, and setting their priorities.
Learn processor-specific initialization via the cube hal cortex driver, exploring NVIC, SYSTICK, and MPU APIs in hal_cortex.c, and configure priority grouping with HAL_NVIC_SetPriorityGrouping, understanding preemption and subpriority (default group 4).
Enable MemManage, BusFault, and UsageFault via the system control block SHCSR, set priority grouping to 4, and assign the highest preempt priority; HAL_Init handles SYSTICK.
Define and link a UART2 handle, configure baud rate, word length, stop bits, parity, and mode, then call HAL_UART_Init for high-level peripheral initialization and set up for later low-level initialization.
Learn low level initializations for the USART2 peripheral, including enabling its clock, performing pin muxing, and configuring NVIC interrupts with priority in HAL UART setup.
Identify and configure usart2 pin packs by assigning tx and rx to alternate function mode, using af7, such as pa2/pa3 or pd5/pd6.
Configure PA2 as USART2_TX and PA3 as USART2_RX by setting the GPIO alternate function AF7, initializing with GPIO_InitTypeDef via HAL_GPIO_Init, with push-pull, pull-up, and low speed.
Enable USART2 IRQ in the NVIC and set its priority to allow interrupt-driven data handling. The module covers pin muxing, clock enable, and low level initialization for low power operation.
Explore stm32 hal peripheral data handling APIs and compare polling, interrupt, and dma transfers for uart, can, spi, and i2c. Select the API based on timing and power needs.
Learn to send characters over uart using hal_uart_transmit in blocking mode, calculate data length with strlen, and handle timeout and status checks for reliable transmission.
Debug and fix UART data transmission using HLA_UART_transmit() API by enabling clocks for USART2 and GPIO port A, and implement systick handler to drive the STM32 Cube tick.
Demonstrates implementing UART data receive in polling mode with HAL_UART_Receive, reading one byte at a time into a data buffer, detecting carriage return, echoing uppercase data back to the host.
Convert a blocking uart receive into interrupt-based data receiving using the STM32 cube framework, learn uart interrupts, and prepare to move on to timers.
Convert a blocking polling UART into an interrupt-based receive flow using the non-blocking API. Implement USART2_IRQHandler and call HAL_UART_IRQHandler to process UART interrupts.
Explore non-blocking UART data reception using interrupt mode, implement receive complete callback to gather bytes into a global buffer until carriage return, leveraging the Cube framework callbacks.
Explore UART data reception using STM32 Cube framework in interrupt and polling modes, learn to navigate driver APIs, and prepare to work with timers, RTC, and CAN peripherals.
Explore microcontroller's clock architecture and the RCC HAL APIs for configuring HSI, HSE, and PLL-based SYSCLK, derive HCLK and PCLKx, and drive RTC and watchdog timers with LSI and LSE.
Enable system clock (HSI or HSC), optionally PLL; configure CPU, AHB, APB, and USB clocks with prescalers; set flash latency; switch to the sysclk using HAL_RCC_OscConfig and HAL_RCC_ClockConfig.
Configure the RCC with HAL_RCC_OscConfig and HAL_RCC_ClockConfig. Set HSE as the system clock to 8 MHz with HCLK 4 MHz, PCLK1 2 MHz, and PCLK2 2 MHz.
Configure the stm32 clock tree, enable hse as sysclk, and use apb1 and apb2 prescalers with HAL_RCC_ClockConfig to reach 4 mhz hclk and 0 ws flash latency.
Reconfigure the systick to generate a 1 ms interrupt using CMSIS SYSTICK_Config, after changing the system clock from 16 MHz to 4 MHz, and reinitialize UART baud rate accordingly.
Program the microcontroller and verify clock domains—SYSCLK, HCLK, PCLK1, and PCLK2—achieving 16 MHz after main. Preview the next lecture on HSI calibration and temperature behavior.
Calibrate the HSI clock to counter temperature drift using the HSITRIM 5-bit field in the RCC control register; 16 at 25 degree Celsius, measure with timer input capture for trimming.
Explore the pll engine to generate system clocks from HSE or HSI using M divider, N multiplier, and P divider, with VCO input 1–2 MHz and VCO output 100–432 MHz.
Configure the microcontroller's PLL to generate 50, 84, or 120 MHz from HSI or HSE, setting PLLM, PLLN, and PLLP, and apply with HAL_RCC_OscConfig for precise system clock and HCLK.
Explain configuring system clock with pll using hsi, adjusting apb1/apb2 prescalers, flash latency, and systick via SystemClock_Config; verify sysclk and hclk, and prepare to use hse in the next lecture.
Configure the microcontroller's PLL with an HSE input clock to produce 50 MHz, using a dedicated system clock config function and HSE bypass without calibration.
Configure the PLL to boost the HCLK to the STM32F446RE's 180 MHz maximum using HSE as the PLL source.
Configure PLL to 180 MHz by setting PLLN to 360 and enabling over-drive after selecting voltage scale 1; enable power clock and set HCLK to 180, PCLK1 45, PCLK2 90.
Discover how timers in STM32 microcontrollers count from zero to a programmed period, up or down, generating update events and interrupts for timebase, PWM, and ADC/DAC triggering.
Explore timer availability in stm32 mcus, including advanced timers like timer1 and timer8, 32-bit general purpose timers (timer2, timer5) and basic timers like timer6 and timer7.
learn how STM32 timer peripherals vary by family, with same-name timers sharing features across microcontrollers, enabling code reuse; TIM17 clarifies that a single timer isn't the total count.
Explore STM32 basic timer architecture including 16-bit counter, prescaler, and auto-reload register, and learn to generate 100 ms interrupts to toggle a GPIO in the IRQ handler.
Explore how to configure a basic timer using TIM6, including setting up the TIM_HandleTypeDef, InitTypeDef parameters (prescaler, period), and calculating the timer clock from APB1 and system clock settings.
Learn how the system clock is divided by the prescaler to form the timer and counter clocks, and how the period in the auto-reload register governs counting.
Explore how prescaler and period values set the timer base, calculate a 100 ms interval with a 16 MHz clock, and address the 16-bit arr limitation.
Master timer 6 initialization with a 16 MHz clock, tuning prescaler and ARR to fit 64k. Implement HAL_TIM_Base_Init and HAL_TIM_Base_MspInit, enable TIM6 clock and NVIC IRQ 54 with priority 15.
Initialize timer6 and its LED pin, then poll the update interrupt flag to toggle the LED every 100 ms using HAL_TIM_Base_Start and HAL_GPIO_TogglePin, with GPIOA pin 5.
Switch from polling to timer interrupt mode to generate a 100 ms time base, enabling low power operation via update events, and toggle an LED in the period elapsed callback.
Learn to generate a 10 μs timebase with Timer6 using a 50 MHz system clock, configure the prescaler and ARR, and compare software toggling versus output compare mode.
Measure a signal’s time period using a timer’s input capture block with a square wave from LSE or HSI, then infer frequency and understand timer input channels and capture registers.
Explore how input capture on a general purpose timer records rising edges, saves capture values, and computes signal period and frequency from clock pulses using the arr and capture/compare registers.
Learn to measure input frequency or period with the timer input capture by configuring timer2 as the timebase using HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel, with a 32-bit up counter and prescaler.
Configure the timer input capture channel with TIM_IC_InitTypeDef using polarity, ICSelection, prescaler, and filter settings, and initialize with HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel for TI1 and TI1F.
Configure timer 2 input capture channel 1 with rising polarity and direct mode, implement msp and gpio setup, enable TIM2 IRQ, and prepare to measure an external signal’s period.
Configure the LSE on MCO1 PA8, verify clock output around 32.79 kHz, and route it to timer 2 channel 1 PA0 to measure the period.
Implement a timer input capture callback to capture CCR values on rising edges, compute the signal period and frequency, and transmit results via UART using HAL on the STM32 timer2.
Perform input capture testing by wiring PA8 to PA0 and observing signal frequency, then adjust the prescaler and switch LSE to HSI to verify 4 MHz timer input.
Get a quick update on using SystemClockConfig_HSE for input capture: output near 32768, with HSE offering greater stability and accuracy than HSI, recommended for all timer related applications.
Configure HSI and divide the clock by four to output 4 MHz on MCO1, analyze input capture interrupts, then generate a 50 kHz test signal with Timer6 for Timer2 capture.
Perform an input capture exercise with a 50 kHz external signal, configuring timer6, starting the timer, and toggling GPIOA pin 5 to verify the measurement.
Update: English closed captions have been added, transcript available
Course code: MCU2
>>Welcome to the course which teaches you advanced Micro-controller programming. In this course you are going to learn and master Timers , PWM, CAN, RTC, Low Power modes of STM32F4x Micro-controller with step by step guidance. Highly recommended if you are seeking a career in the domain of Embedded software. <<
In this course, you will understand behind the scene working of peripherals with supportive code exercises. I have included various real-time exercises which help you to master every peripheral covered in this course and this course thoroughly covers both theory and practical aspects of Timers, PWM, CAN, RTC, Low Power modes of STM32F4x Micro-controller.
In Timer Section the course covers,
1. Simple time-based generation using the basic timer in both polling and interrupt mode
2. Timer interrupts and IRQ numbers, ISR implementation, callbacks, etc
3. General-purpose timer
4. Working with Input Capture channels of General-purpose timer
5. Interrupts, IRQs, ISRs, callbacks related to Input Capture engine of the general purpose timer
6. Working with output capture channels of the General purpose timer
7. Interrupts, IRQs, ISRs, callbacks related to Output Capture engine of the general purpose timer
8. PWM generation using output capture modes
9. PWM Exercises
10. Step by Step code development process will help you to master the TIMER peripheral
In CAN Section the course covers,
1. Introduction to the CAN protocol
2. CAN frame formats
3. Understanding a CAN node
4. CAN signaling (single-ended signals vs differential signals ) \
5. CAN Bus recessive state and dominant state
6. CAN Bit timing Calculation \
7. CAN network with Transceivers
8. Exploring inside view of CAN transceivers
9. CAN Self-test modes such as LOOPBACK, SILENT LOOPBACK, etc with code exercises.
10. Exploring STM32 bXCAN peripheral
11. self-testing of bxCAN peripheral with exercises
12. bXCAN block diagram
13. Tx/Rx path of the bxCAN Peripheral
14. CAN frame filtering and executrices
15. CAN in Normal Mode
16. Communicating between 2 boards over CAN
17. Code exercises
In the Power Controller Section the course covers,
1. ARM Cortex Mx Low Power Modes Normals Vs DeepSleep
2. STM32 SLEEP mode
3. STOP mode
4. STANDBY mode
5. Current measurement with different submode
6. Waking up MCU by using wakeup pins, EXTI, RTC, etc
7. Backup SRAM
8. Step by Step coverage with lots of code exercises.
In RTC Section the course covers,
1. RTC functional block diagram
2. RTC clock management
3. RTC calendar unit
4. RTC Alarm unit
5. RTC wake-up unit
6. RTC Time Stamp Unit
7. waking up MCU using RTC events
8. RTC interrupts
9. and lots of other details with step by step code exercises.
STM32 Device HAL framework
1. STM32 Device Hal framework details
2. APIs details
3. Interrupt handling
4. Callback implementation
5. Peripheral Handling and configurations
6. Step by Step explanation with code exercises.
==> Important note: This course is NOT about auto-generating code using STM32CubeMx software<==
Hardware used :
STM32F446RE-NUCLEO Board
CAN Transceivers for CAN Exercises
IDE :
Eclipse-based OpenSTM32 SystemWorkbench or STM32CubeIDE
Learning order of FastBit Embedded Brain Academy Courses,
If you are a beginner in the field of embedded systems, then you can take our courses in the below-mentioned order.
This is just a recommendation from the instructor for beginners.
1) Microcontroller Embedded C Programming: absolute beginners(Embedded C)
2) Embedded Systems Programming on ARM Cortex-M3/M4 Processor(ARM Cortex M4 Processor specific)
3) Mastering Microcontroller with Embedded Driver Development(MCU1)
4) Mastering Microcontroller: TIMERS, PWM, CAN, RTC,LOW POWER(MCU2)
5) Mastering Microcontroller: STM32-LTDC, LCD-TFT, LVGL(MCU3)
6) Embedded System Design using UML State Machines(State machine)
7) Mastering RTOS: Hands-on FreeRTOS and STM32Fx with Debugging(RTOS)
8) ARM Cortex M Microcontroller DMA Programming Demystified(DMA)
9) STM32Fx Microcontroller Custom Bootloader Development(Bootloader)
10) Embedded Linux Step by Step using Beaglebone Black(Linux)
11) Linux device driver programming using Beaglebone Black(LDD1)
Other programming courses
1) Master The Rust Programming Language : Beginner To Advanced