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?

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

}