Skip to main content
Graduate
August 4, 2025
Solved

How to Deeply Understand STM32 HAL Without Relying on CubeMX?

  • August 4, 2025
  • 6 replies
  • 667 views

Hi, my name is Zaeem Ahmed.

I'm currently digging into the STM32F1 HAL and trying to understand it at a deeper level. I'm intentionally not using STM32CubeMX — not because I have anything against it (it’s a great tool) — but because I want to read the HAL documentation and implement configurations manually to better understand what’s really happening under the hood.

What I'm looking for:

I would really appreciate any good resources, expert tips, or learning strategies that help connect:

  • HAL APIsHardware-level understanding from the reference manual

The challenge I'm facing:

Often, when reading HAL documentation, I encounter vague or overly simplified explanations. For example:

  • HAL_TIM_Base_Init vs. HAL_TIM_Base_MspInit — the documentation just says one initializes the timer and the other the MSP, which is obvious from the names but not why they're separated or how they work together under the hood.

Another example:

  • When initializing timers, there are different functions for different modes (e.g., HAL_TIM_OnePulse_Init, HAL_TIM_PWM_Init, etc.).
    But modes like PWM, Input Capture, Output Compare seem to be channel-specific, not timer-wide.
    So why is the timer itself initialized in a specific mode?

This leads to questions like:

  • What happens if I initialize a timer in one mode (say PWM), and configure its channel for another (like Input Capture)?

  • How is HAL actually helping if I have to dig into its source every time to validate my approach?

I understand how the timer works at the register level from the reference manual, but when I move to HAL, it feels like a black box. I'd really like to bridge that gap.

  • How can one truly learn HAL (not just use it as a wrapper)?

  • Are there any guides/resources that map HAL APIs to actual peripheral behavior?

  • What’s the best way to approach HAL if you want full control and hardware understanding, but still benefit from its abstraction?

I’d really appreciate any learning resources, explanations, or just your own journey if you’ve been through this.

Thanks in advance!

— Zaeem Ahmed

    This topic has been closed for replies.
    Best answer by AScha.3

    Hi,

    so maybe useful - read:

    https://www.st.com/resource/en/user_manual/um1850-description-of-stm32f1-hal-and-lowlayer-drivers-stmicroelectronics.pdf

    and see the CMSIS-Core (Cortex-M) overview and the Common Microcontroller Software Interface Standard (CMSIS) of Arm .

    + in my opinion : 

    Using Cube to set up the chip and then HAL to use it , is the fastest way , to use a "new" chip/cpu by STM.

    If its doing all you need/want : fine.

    If not...you have to look at examples (if you find some matching) and read the rm , to see , whats possible and then write it (to registers).

    Or if you need something faster or "better" than HAL doing, still set the functions with HAL and then look at it, how its doing it and do it "better" . (or, just to learn, what and how its doing)

    example: I want to use a small TFT , 320x240 pix, on a STMF303 :

    - set up cpu , clock tree, SPI with Cube

    - search ILI9341 lib on github....ok, adapt it to my F303, just using the HAL ( HAL_SPI_Transmit(&ILI9341_SPI_PORT, buff...) )

    - compile, check, ok, write a grid (like on a DSO) to the TFT

    - grid writing needs about 305ms , slow..., so writing the color data now by writing to SPI register direct: 6 ms ! ok.

    Now its ok for me, good speed and minimum time spent to do it.

    AScha3_0-1754319857386.png

     

    6 replies

    Super User
    August 4, 2025

    Timers are one of the things that HAL doesn't do that well, purely due to the sheer number of configurations possible. Consider using register-only code instead if it's something that can't be selected in CubeMX.

    Best way to learn is to look at the code and see what it's doing, IMO.

    Technical Moderator
    August 4, 2025

    Hello @Zaeem-Ahmed 

    To learn what the HAL function do exactly you should follow these steps

    • Step 1: Read the reference manual for the peripheral (e.g., TIMx).
    • Step 2: Look at the HAL function (e.g., HAL_TIM_PWM_Init).
    • Step 3: Dive into the HAL function and see which registers are set.
    • Step 4: Compare with the reference manual to see what’s being configured.
    Super User
    August 4, 2025

    @Zaeem-Ahmed wrote:

    I want to read the HAL documentation


    That would be a good starting point - have you done that?

    eg, for F1, it's UM1850 Description of STM32F1 HAL and low-layer drivers.

    See also the 'Documentation' tab on the Cube-F1 package Product Page:

    https://www.st.com/en/embedded-software/stm32cubef1.html#documentation

     

    You could also look at the code that CubeMX generates - it's all just HAL calls...

    AScha.3Answer
    Super User
    August 4, 2025

    Hi,

    so maybe useful - read:

    https://www.st.com/resource/en/user_manual/um1850-description-of-stm32f1-hal-and-lowlayer-drivers-stmicroelectronics.pdf

    and see the CMSIS-Core (Cortex-M) overview and the Common Microcontroller Software Interface Standard (CMSIS) of Arm .

    + in my opinion : 

    Using Cube to set up the chip and then HAL to use it , is the fastest way , to use a "new" chip/cpu by STM.

    If its doing all you need/want : fine.

    If not...you have to look at examples (if you find some matching) and read the rm , to see , whats possible and then write it (to registers).

    Or if you need something faster or "better" than HAL doing, still set the functions with HAL and then look at it, how its doing it and do it "better" . (or, just to learn, what and how its doing)

    example: I want to use a small TFT , 320x240 pix, on a STMF303 :

    - set up cpu , clock tree, SPI with Cube

    - search ILI9341 lib on github....ok, adapt it to my F303, just using the HAL ( HAL_SPI_Transmit(&ILI9341_SPI_PORT, buff...) )

    - compile, check, ok, write a grid (like on a DSO) to the TFT

    - grid writing needs about 305ms , slow..., so writing the color data now by writing to SPI register direct: 6 ms ! ok.

    Now its ok for me, good speed and minimum time spent to do it.

    AScha3_0-1754319857386.png

     

    Graduate II
    August 4, 2025

    Presumably you want to understand HAL because you want to use it, or are considering using it for a project. Why not just spend <£30 on an Nucleo board and start using it? You'll learn a lot faster and gain knowledge that will stick by working hands-on with it. 

    Of course, we all learn in different ways... The above is just my opinion :)

    Graduate
    August 5, 2025

    Thank you all for the guidance.
    I’ve learned several new approaches to deepen my understanding of STM32 development. Initially, I was hoping for more detailed documentation on the HAL functions, but I now realize that true understanding comes from exploring CubeMX-generated code, studying the examples, and closely examining which registers the HAL functions modify.

    This hands-on, exploratory method has given me more confidence in learning the HAL, and I now feel assured that I’m on the right track.

    Thanks again for the helpful insights!

    Super User
    August 5, 2025