cancel
Showing results for 
Search instead for 
Did you mean: 

How do I get the STM32F103C8T6 to read frequencies from 1Hz to 100KHz correctly and accurately onTIM

BangDuLzGG
Associate II

How do I get the STM32F103C8T6 to read frequencies from 1Hz to 100Khz correctly and accurately on TIM3?

I set HCLK in the program at 72Mhz, Prescaler at 2999 and Period at 65536.

htim3.Instance = TIM3;
htim3.Init.Prescaler = 2999;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

and the program can read the 1Hz frequency correctly but when reading the 1KHz frequency, the value displayed by the program output becomes 1090Hz.
BangDuLzGG_1-1715919248726.png


I use the following formula to get the value for the output frequency:

BangDuLzGG_3-1715919439599.png

The value of IC_direct_mode_periode is obtained from this section:

BangDuLzGG_2-1715919410096.png

 

What is the correct prescaler, period or HCLK value so that the program can read frequencies correctly and accurately up to 100Khz?
or is the formula I used to get the value for the output frequency wrong?

2 REPLIES 2
hardrock
Associate III

The TIM3 on STM32F103 is 16-bit timer.
To improve accuracy, the prescaler of timer3 was set to 1 MHz.
Please refer to the sample code below, and you can modify it as you wish.

Clock Configuration.jpg

TIM3.jpg

/* USER CODE BEGIN 0 */ uint32_t cap_val1 = 0; uint32_t cap_val2 = 0; float frequency = 0; float duty_cycle = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // Input Capture Channel 1 (Rising Edge) { cap_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); TIM3->CNT = 0; // Clear TIM3 Counter } if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // Input Capture Channel 2 (Falling Edge) { cap_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); frequency = 1000000 / (float)cap_val1; duty_cycle = (float)(cap_val2 * 100) / (float)cap_val1; } } /* USER CODE END 0 */ int main(void) { MX_TIM3_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); /* USER CODE END 2 */ }
View more

 

saurabhkore
Associate III

Hii youre code is correct,but need to change in cube ide settings.

TIM3->Clock source->Internal clock

->combined channels->PWM input on channel 1

After this settings just generate code and using capture callback function measure frequency.