STM32 Clock questions

Thread Starter

Futurist

Joined Apr 8, 2025
748
I'm working on a Nucleo board - F446RE version - and using VisualGDB with Visual Studio.

I'm confused about clocks, recall reading up on this a year or so ago and never really managed to fully grasp it with "sys clocks" and "sys tick" and so on.

Anyway I often see code like this:

C:
// Configure TIM2 in One-Pulse Mode
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 90 - 1; // 1 MHz timer clock (assuming 90 MHz system clock)
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 10 - 1; // Pulse duration: 10 µs
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
Note the hard coded "90" there on line 3, but why? isn't it better practice to write this as:

Code:
// Configure TIM2 in One-Pulse Mode
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = (HAL_RCC_GetSysClockFreq() / 1000000) - 1; // 1 MHz timer clock (based on actual system clock)
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 10 - 1; // Pulse duration: 10 µs
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
In my case the HAL_RCC_GetSysClockFreq() function returns 16,000,000 so the code I have can't assume a 90 MHz clock.
 

MrChips

Joined Oct 2, 2009
34,809
You are correct.

The STM32F446RE can be operated at different clock frequencies. On startup, it will run at 16 MHz using internal RC oscillator. The MCU is capable of running at 180 MHz.

You can set the clock prescaler in the timer module to any value you need. This is fine if you are not planning on porting your code to another device or a different application.

Another option is to use #define SYS_CLOCK_FREQ at the top of your code or in a header file so that you know exactly what frequency your application needs.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
Thanks, the code should - ideally - be portable to (some) other STM32 chips or even the same chip but perhaps running at a different system clock speed.

Any STM32 that supports a timer that can be used in this "pulse" mode would in principle be able to use this code unchanged, that my ideal anyway.



You are correct.

The STM32F446RE can be operated at different clock frequencies. On startup, it will run at 16 MHz using internal RC oscillator. The MCU is capable of running at 180 MHz.

You can set the clock prescaler in the timer module to any value you need. This is fine if you are not planning on porting your code to another device or a different application.

Another option is to use #define SYS_CLOCK_FREQ at the top of your code or in a header file so that you know exactly what frequency your application needs.
 

MrChips

Joined Oct 2, 2009
34,809
Do you use the LL libraries or are you a bare metal man?
I am a bare metal man.

1) When I started programming STM32 chips HAL was not yet available.
2) Also, I try not to use other people's libraries. I like to have full control over the code I use. (You can call me a control freak!)
3) Sometimes I like to over-clock the MCU. I can push a part to 200 MHz even though it is spec'd at 180 MHz.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
I am a bare metal man.

1) When I started programming STM32 chips HAL was not yet available.
2) Also, I try not to use other people's libraries. I like to have full control over the code I use. (You can call me a control freak!)
3) Sometimes I like to over-clock the MCU. I can push a part to 200 MHz even though it is spec'd at 180 MHz.
Well I hope I'm able to learn from you, you must be an absolute guru by this time.

I'm actually designing/writing/developing a library for managing an NRF24L01+, I happened to have a few lying around and wanted a project I can pick up and put down as I feel like it.

I can understand your desire to write your own library code, gives one complete control over the software and forces you to really understand the device.

I find the LL and HAL stuff helpful to a degree but also frustrating, there are just so many functions and #defines involved and many tens of .c and .h files.

For now I'm relying on HAL to do the nitty gritty and focused more on the best way to wrap the NRF in an API.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
Well you're in luck. I have done some applications using NRF24L01+.
Again, I write my own code.
I recently found this and as a novice I found it helpful. I mean it raises questions, is a bit simplistic and uses HAL, but it was clearly explained.


The NRF manual too could be better, it's a bit jumbled up and has a lot of detail about "shockburst" operation but not enough about basic operation. I formed the impression that the chip designers, engineers really understand their domain but don't explain it as well as they designed it.
 

MrChips

Joined Oct 2, 2009
34,809
I will go over my notes and see if I can create a blog for this.

One of the reasons I prefer to write my own code is because oftentimes I need to tailor the interface for a different MCU for which there is no library available.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
I will go over my notes and see if I can create a blog for this.
That sounds interesting, I've been immersed in their manual (on and off) for several weeks now.

One of the reasons I prefer to write my own code is because oftentimes I need to tailor the interface for a different MCU for which there is no library available.
I'm curious, if you want to tailor it for a non-STM32 MCU, how do you approach that? how do you write portable code, or is it - as you say - tailored, easy to adjust, designed to be easy to adjust to a change in MCU?

I'm interested in writing a library mainly because I don't think many of the open source libraries are that well designed, they all seem to be simplistic and don't really abstract the device that well and so you may want to do something unusual with the device use a lesser used but documented feature and find the library doesn't go there and is designed in such a way that it needs a lot of work to make it go there.

A good library for devices like this should - ideally - expose all features and expose the logical concepts that the designers designed.

Of course "libraries" and "portability" in the MCU world are not the same as they are in the general computing world, that's both extremely interesting and extremely challenging all at once.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,809
I'm curious, if you want to tailor it for a non-STM32 MCU, how do you approach that? how do you write portable code, or is it - as you say - tailored, easy to adjust, designed to be easy to adjust to a change in MCU?
MCU applications are always hardware specific. If you wish to create portable code, you have to write the code in such a way so that all hardware assignments are defined outside of the library. Define statements are then placed in a header file (.h file) for that specific MCU.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
MCU applications are always hardware specific. If you wish to create portable code, you have to write the code in such a way so that all hardware assignments are defined outside of the library. Define statements are then placed in a header file (.h file) for that specific MCU.
Do you code in C or C++ ?

Also I guess the only way to be sure that transmission works is to receive data via the other NRF24, I'm wondering how best to test this because if I do not receive data then I won't really know if that's a flaw in the transmit code or receive code.

I can monitor SPI traffic being sent to the transmitter but of course can't be certain that RF is truly being generated.

Having said that, the interrupt is being triggered and I see the STATUS.TX_DS is high (but is low right before I transmit) so the device seems to be responding as I'd expect it to.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,809
I program in C.

I need to review my notes. It was difficult to get it working. As you encountered, the datasheet is not particularly helpful.

I have one advantage in that I have an RF spectrum analyser at my disposal. I can detect when transmissions are taking place.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
I program in C.

I need to review my notes. It was difficult to get it working. As you encountered, the datasheet is not particularly helpful.

I have one advantage in that I have an RF spectrum analyser at my disposal. I can detect when transmissions are taking place.
I'm jealous !
 

MrChips

Joined Oct 2, 2009
34,809
I also have an SDR (software-defined radio) which could probably do the same thing but I have never tried it for this purpose.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
I also have an SDR (software-defined radio) which could probably do the same thing but I have never tried it for this purpose.
That's true, I have an SDR here but it tops out at 1.7 GHz.

Anyway I'm getting close to running a simple receiver test with the code I have here, I'm starting to build a mental model of the device but an that manual could be more helpful.
 

Thread Starter

Futurist

Joined Apr 8, 2025
748

MrChips

Joined Oct 2, 2009
34,809
@MrChips - If I have two NRF boards on the bench, say 12 inches apart but NO antenna attached to either, can I expect comms to work?

Also is there any limit to how close two boards can be, if I DO attach their antenna? (like is it possible to damage a receiver is the transmitted signal is very close, strong?).
Ah, so! Mine did not come with external antennas. The antennas were printed on the PCB.
In any case, I don't think that you can damage the chips. With the antenna connected, I would space the units at least 1 metre apart.

The units will not work until the software is setup and running correctly. I still have to find my notes and code for you.
The MCU below is STM32L071C8T6 and the smaller chip is IIS3DWB 3-axis accelerometer. The project is a machine vibration sensor.

DMI_MEMS.jpg
 

Thread Starter

Futurist

Joined Apr 8, 2025
748
Well I'm at the point where I expect to see a message received, but I'm not and no surprise given this is only just beginnning to get tested (and I found a few tiny code oversights).

A challenge is not knowing if the RX or TX or both, are not working.

I'm going to dump all device registers for the TX and RX and compare what I see with other articles and blogs, I might spot something this way, if the regs are in any way wrong then it won't work, if they really do look correct then the issue lies elsewhere...
 
Top