Try it without HAL, it's not complicated.
void start_TIM2() {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_EN;
}
uint16_t read_TIM2() {
return TIM2->CNT;
}
Answer from followed Monica to Codidact on Stack Overflowc - Stm32 Timer Counter With Registers - Stack Overflow
Correct way of setting a 1μs timer on a STM32 MCU with HAL
microcontroller - Prescaler vs Counter Period (STM32) - Electrical Engineering Stack Exchange
STM32 timers: the most efficient settings for prescalers vs counter periods?
Is interrupt handling required for cascaded counters?
Can advanced-control timers and general-purpose timers be cascaded together?
Can this method be used for event counting instead of time measurement?
Videos
Try it without HAL, it's not complicated.
void start_TIM2() {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_EN;
}
uint16_t read_TIM2() {
return TIM2->CNT;
}
Setting the value of
htim2.Init.Period = 0;
zero initializes the auto reload register (ARR) not a very handy default choice of cubeMX, you probably want an ARR value of 0xFFFFFFFF
The accepted answer relies on the ARR value after reset of 0xFFFFFFFF without mentioning it, more luck than wisdom if you ask me
I am barely new to the embedded world and for a new project I require a 1μs timer. I am using the discovery board STM32F407VG.
These are the settings on how I have configured the timer:
-
Basic timer 6 at a clock frequency of 84 MHz
-
Following this formula I set the Prescaler to 0 and the Counter period to 83 to obtain a period of 1μs:
-
Counter Period = ( Time base required (in seconds) × ( Timer clock source / (Prescaler + 1) ) ) - 1
-
Counter Period = ( 0.000001 × ( 84000000 / (0 + 1) ) ) - 1 = 83
-
Then, I use this function with the flag TIM_FLAG_UPDATE:
static void microDelay (uint32_t delay){
while (delay){
if(__HAL_TIM_GET_FLAG(&htim6, TIM_FLAG_UPDATE)){
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_FLAG_UPDATE);
delay--;
}
}
}I haven't had any issues so far. I tested it with a logic analyzer by toggling a pin, and I didn't encounter any problems. My concern is that in a few tutorials, I saw that they simply matched the prescaler value to the timer clock frequency to obtain a Timer clock source of 1MHz and then set the Counter period to its maximum value. Then, they used the following function:
void delay_us (uint16_t us)
{
__HAL_TIM_SET_COUNTER(&htim1,0);
while (__HAL_TIM_GET_COUNTER(&htim1) < us);
}Maybe I am being too fussy, but with this solution, if you enter a value bigger than the counter period the while loop will loop forever... and I don't see that problem in my solution.
However, do you think my solution could lead a further problems? Maybe, I am missing something that could make the timer fail in the future.
Thanks
- Prescaler defines the frequency of the counter unit. AR (auto reload) is just a cap for maximum count unit and reg update; in PWM or a simple time-base, they work the same. but what about a input capture? What about PWM without sacrificing resolution?
- More flexibility. Usually the prescalers are just a power of 2 like 2,4,8,... and despite the fact that there are some microcontrollers with no limit on that, but adding both makes it more flexible.
The prescaler is used to set the frequency in which counter is changed.
Example:
If your timer clock is 100MHz and you want the timer to overflow every 2ms you need to do some math.
For 2ms your counter will have to count to 100MHZ * 2ms = 200000. Most STM32 timers counters are 16 bits and this value will not fit. The maximum value is 65535.
200000 / (65535 + 1) = 3.05. The closest integer number greater than this is 4.
100MHz / 4 = 25MHz. The counter will need to count to 50000 and this value will fit the 16 bits register.
So your prescaler register (PSC) will need to be set to 3 (4-1) and counter register (ARR) to 49999 (50000-1). The offsets of one are necessary because it is how those timers work.