2024-05-16 09:19 PM
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.
I use the following formula to get the value for the output frequency:
The value of IC_direct_mode_periode is obtained from this section:
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?
2024-05-17 02:10 AM
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.
/* 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 */
}