Skip to main content
BangDuLzGG
Associate
May 17, 2024
Question

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

  • May 17, 2024
  • 2 replies
  • 1541 views

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

hardrock
Associate II
May 17, 2024

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 */

}

 

Associate III
December 11, 2024

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.