2025-04-17 7:43 AM
Hello!
Using TIM1 for pwm input capture.
Works OK for trigger prescaler 1 (default).
Want to use prescaler 4, but it doesn't work. Capture value the same as prescaler 1.
Timer config:
void FC_SERVO_1_TIM1_Init(void)
{
// USER CODE END TIM1_MspInit
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM1 GPIO Configuration
PA8 ------> TIM1_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* TIM1 interrupt Init */
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
// --------------------
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 15;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV4;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV4;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
void TIM1_CC_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim1);
}
2025-04-17 11:10 AM
You say it works with 1, but not 4, but the code shows it at 15.
No code actually reads the value. How do you determine it "doesn't work"?
I assure you the timer works with a prescaler of 1, and 4, and 15. So the bug has to be somewhere else--in your code somewhere.
2025-04-17 11:56 AM
I'm not about
htim1.Init.Prescaler = 15;
Yes it's works OK.
I'm about
sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV4;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV4;
I'm
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM1) {
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){
tim1_trig_time = HAL_GetTick();
if(tim1_isFistCaptured == 0){
tim1_isFistCaptured=1;
} else {
tim1_period = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
tim1_isFistCaptured=0;
}
tim1_duty = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
__HAL_TIM_SET_COUNTER(htim, 0);
}
}
}
tim1_period and tim1_duty does not change after switch from TIM_ICPSC_DIV1 to TIM_ICPSC_DIV4
2025-04-17 12:40 PM
The input prescaler shouldn't substantially affect duty cycle or period. It is used to perform the IC comparison every X cycles (prescaler > 0) instead of every cycle (prescaler = 0, default).
2025-04-17 1:38 PM
AS I understand and It's show in https://www.youtube.com/watch?v=P6211ic2N_s&list=PLfIJKC1ud8gjLZBzjE3kKBMDEH_lUc428&index=2&ab_channel=ControllersTech
TIM_ICPSC_DIV4 will trigger interrupt every fourth rising edge of input signal, not every one.
So for this time timer wii count 4 times more.
I want to reduse timer interrupts.
2025-04-17 1:44 PM - edited 2025-04-17 1:44 PM
I think you're right. I was mixing up filter and prescaler. I may take a closer look later.
Apologies for the noise.
2025-04-17 3:15 PM
The capture divider applies only to the capture itself, i.e. not to the TI1FP1 signal which is input to the slave-mode controller. Thus, the slave-mode controller resets the counter upon every riding edge and so the capture captures duration of the last of the 4 periods.
JW
2025-04-20 11:20 PM
Do you have a chance take a look? Looking forward some info.