
Download STM32CubeIDE from the ESTIE Microelectronics website, using the Windows installer. Create a free account or log in to start the download, which is about 729 MB.
Install STM32CubeIDE by extracting the package, running the installer, selecting a suitable location, creating a desktop shortcut, and launching the IDE to set the workspace and handle firewall prompts.
Download the reference manual, datasheet, and Nucleo user guide to enable bare-metal development without libraries, locate peripheral addresses, and create registers from scratch.
Define peripheral base address and use memory-map offsets to compute GPIO A base, then locate port and pin for the user led using the data sheet and reference manual.
Enable peripheral clocks with the RCC on the APB bus, locate RCC and GPIO registers from the reference manual, and configure a GPIO pin using MODER and ODR.
Configure pin five as an output via the mode register, then drive it high with bitwise operations, and validate with an infinite loop toggling the LED.
Represent stm32l0 peripherals as structures whose members are registers, creating registers from structure members and aligning offsets to the reference manual using volatile types. Access registers via the structure pointer.
Explore the general-purpose input/output module and ports. Identify alternate functions for peripherals, use the direction and data registers, and compare hp and apb buses with rc oscillator, crystal, and pll.
Develop a new gpio output driver using pre-defined register definitions from a downloaded package; include device headers, configure the project, and build and flash to the board.
Develop a gpio input driver for the board by enabling gpio clock and configuring pc13 as input. Read idr bit13 to detect the push button (active low) and drive lcd.
Develop the uart transmitter driver for the usart module two using the ewart's protocol, configuring af4 pins and enabling the apb1 clock and transmitter.
Learn to implement and test a UART transmitter driver for the STM32L0, including writing to the transmit data register, polling the TXI bit in the USR, and validating transmission.
Learn how to retarget printf on stm32l0 bare-metal by implementing a _putchar wrapper that forwards characters to the uart write function, enabling printf output over serial.
Develop the uart receiver driver by initializing the transmitter and receiver, configuring the alternate function and mode registers, and enabling both transmitter and receiver in the control register.
Implement a UART receiver driver by polling the receive data register not empty bit (RDRF), read data, and drive an LED when the '1' key is pressed.
Explore how transducers convert physical quantities to electrical signals, and how ADCs translate these analog voltages into digital readings with 8–16 bit resolutions and reference voltage–dependent step sizes.
Explore ADC independent modes on a single ADC module with 16 channels, covering five configurations—single channel single conversion, multi-channel single/continuous conversions, and injected continuous mode—each with configurable channel sampling times.
Develop an ADC driver by locating the ADC bus, enabling the APB clock, configuring pins for analog mode, then setting sampling time, continuous conversion, channel sequence, calibration, and data readout.
Implement the adc init function by enabling the ADC clock on the APB2 bus, setting sampling, enabling continuous analog conversion, selecting channel four, and dividing the ADC clock by four.
Develop and test the ADC driver by enabling calibration, enabling the ADC, starting conversions, and clearing the end-of-conversion flag, using symbolic names for control bits.
Develop and test the STM32L0 adc driver by implementing the adc read function, polling the end-of-conversion flag, and reading the data register, with practical jumper-based validation.
Develop the adc single conversion driver by configuring the single conversion mode via the configuration register flag. Build and deploy the code to the board to observe a single conversion.
Explore the cystic timer, a 24-bit down counter driven by the processor clock, with the current value, system control and status, and reload value registers for delay calculations.
Develop a SysTick timer driver to create millisecond delays on a Cortex-M0+ by configuring the control, reload, and current value registers and selecting the internal clock source.
Explore STM32L0 general purpose timers for time bases, input capture, and output waveform generation via compare and one-pulse modes, plus using auto reload and prescaler to set timeouts.
Develop a general-purpose timer (GPTM) driver for the STM32L0 bare-metal. Configure APB1 timer 2, set prescaler and auto-reload for a 1 Hz timer.
Discover how interrupts suspend execution and trigger an interrupt service routine to service modules, while the vector table and nested interrupt controller manage external lines and priorities.
Test the GPIO interrupt driver by handling the interrupt in the ISR, identify pin 13 from the vector table, clear the interrupt, toggle the LED, and verify via serial output.
Develop a timer interrupt driver for a general-purpose timer by enabling the update interrupt, configuring the NVIC, and implementing the interrupt handler with a callback to perform periodic tasks.
Explore the serial peripheral interface (spi): master/slave operation, full-duplex data transfer with mosi/miso and sck, slave select, and clock polarity/phase modes 0–3.
Configure the spi pins for stm32l0. Enable alternate function mode for pins 5, 6, and 7 and set pin 9 as the slave select to interface with adxl345 accelerometer.
Configure SPI parameters by enabling SPI1 clock on APB2, setting baud rate to APB clock divided by 32, enabling master mode, MSB first, 8-bit data, full duplex, and enabling SPI.
Implement the stm32l0 spi transmit function by looping through data, waiting for TXI and TE flags, writing to the data register, and clearing the overrun flag.
Develop an SPI ADXL345 accelerometer driver by configuring registers and multi-byte reads. Define symbolic names for power control and data format, then read data bytes for X, Y, Z.
Test the accelerometer driver via SPI by initializing the interface and configuring data format and power settings, then read six bytes to derive x, y, z and convert to g.
Are you tired of Copying and Pasting code you don't understand?
With a programming based approach, this course is designed to give you a solid foundation in bare-metal firmware development for ARM-based microcontrollers . The goal of this course is to teach you how to navigate the microcontroller reference manual and datasheet to extract the right information to professionally build peripheral drivers and firmware. To achieve this goal, no libraries are used in this course, purely bare-metal embedded-c and register manipulations.
Still keeping it simple, this course comes in different ARM Cortex-M development boards so that students can put the techniques to practice using an ARM Cortex-M development board of their choice. This version of the course uses the STMicroelectronics STM32L0-NUCLEO which has an ARM Cortex-M0+ microcontoller.
So with that understood, let me tell you…
Exactly What You’re Getting
This is dramatically different from any course you have ever taken because it’s more of a professional hands-on “field guide” to stm32 bare metal firmware development.
The reason why is because there’s no fluff or filler. It immediately gets down to the actual subject, showing you exactly what to do, how to do it, and why.
Plus, it’s easy.
And you’ll immediately “get” the entire mythology I personally use to build firmware for consumer devices in my professional life.
It's About MORE Than Just Getting the Code to Work
See, this course will change your professional life forever. Here is what one student had to say about the 1st version (STM32F4) of the course :
"I would suggest this course for all the beginners. The concepts have been covered in the right sequence.And also the best part of this lecture series is getting to know how to explore the reference manual and datasheets."
Here is what another student had to say :
"Extremly helpful to get to understand the uC programming deeper! For me it is much easier from now to develop code because I undertstand the base behind, so I'm more confident and more experienced to develop and debug the code. Really, this course is very useful to link the hardware knowledge with the coding skills. This fills the gap between them. Thanks for it! :)"
A third student :
"I am a professional semiconductor chipset application engineer with 30 years in global embedded product design in system applications. I can say this teacher is very straight forward by sharing his many years knowledge to the students with his true heart. Yes. I love his teaching pace and style!"
The First Version (STM32F4) is being Taken by 5000+ Students with 1000+ Reviews
If at least one of the following applies to you then keep reading if not then simply skip this course:
" Escape From "
Copying/Pasting code you don’t understand
Using third party libraries and header files like HAL, LL and StdPeriph
Experiencing bugs you don’t understand
Being afraid of technical documentations like the reference manual and datasheet of the chip
Imposter syndrome
" Arrive At "
Building every single line of code from scratch by writing to the microcontroller’s memory space directly.
Using No third party libraries or header files
Understanding and writing every single line of code yourself- no Copy/Paste
Using the debugger effectively to analyze and resolve any bugs
Developing proficiency in your embedded development skills and confidently take the next steps
So like I said, there’s more than just getting each piece of code to work.
Here’s an overview of what you’re getting...
Analyzing the chip documentations:
Before developing the firmware for any chip you have to learn how to read the documentation provided by the chip manufacturer.
Defining Peripheral address
All components on the microcontroller have an address range. To write to a component or read from a component you need to locate its address range in the documentation and properly define the addresses in your code.
Creating registers from the address:
The addresses in the address range of a component represent the registers of that component. To access these registers you have effectively typecast the addresses.
Understanding CMSIS:
Cortex-Microcontroller Interface Standard (CMSIS)CMSIS is a standard developed by Arm for all Cortex-Microcontrollers. This is the standard used in professional firmware development
But it gets better because you’re also getting…
Deep Lessons on Developing Peripheral Drivers
You will learn how to develop bare-metal drivers for the following peripherals :
Analog-to-Digital Converter (ADC)
Serial Peripheral Interface (SPI)
Nested Vector Interrupt Controller (NVIC)
General Purpose Timers (TIM)
System Tick Timer (SysTick)
General Purpose Input/Output (GPIO)
Specially Designed For People Who Hate Copy/Paste
Listen. If you don’t like “Copy/Paste” you’re not alone. I can’t stand it either. I’d literally rather have a piece of code that I wrote from scratch that doesn’t work than someone else’s working code I copied and pasted.
And that’s why I’ve spent months designing and recording this course in which I show you how to locate every single register used and the meaning of every hexadecimal value written into the register.
Also it comes with a money back guarantee so you have nothing to loose.