AnsweredAssumed Answered

STM32F072 Timer Slave Mode Configuration

Question asked by Seto.Chris on Jul 16, 2016
Latest reply on Jul 18, 2016 by ForumSTM32.ForumSTM3
Hi,

I need to measure the time a PWM signal spends high. I have the input capture side of this working fine, but with IC mode set to both edges, there are occasional issues with the signal measurement.

It seems like the proper way to do this is by setting the IC config to capture on a falling edge, then using the timer in slave config to reset on a rising edge. Thus, the timestamp stored in the capture compare register would be the difference in time between the two events.

Like I said, I know my GPIO config IC/timer config are right, but I cannot seem to get the timer to reset on a rising signal. Any ideas on what I'm missing here?

I'm using the STM32 Cube libraries.

Code:
void ConfigurePwmControlIn()
{
    /*
        Input capture for PWM in


    */
     
    // Enable clocks
    __TIM14_CLK_ENABLE();
    __GPIOB_CLK_ENABLE();
 
    // Configure GPIO
    GPIO_InitTypeDef   GPIO_InitStruct;
     
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_TIM14;
     
    // TIM14_CH1 GPIO Config
    // PB1
    GPIO_InitStruct.Pin = GPIO_PIN_1;
     
    // Commit the GPIO config
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
    // Configure the NVIC
    // For right now, we'll leave this at a pretty high priority
    HAL_NVIC_SetPriority(TIM14_IRQn, 0, 1);
 
    // Enable TIM14's global interrupt
    HAL_NVIC_EnableIRQ(TIM14_IRQn);
     
    // Configure the timer
    rcPwmInTimer.Instance = TIM14;
    rcPwmInTimer.Init.Period            = 0xFFFF;
    rcPwmInTimer.Init.Prescaler         = 12;
    rcPwmInTimer.Init.ClockDivision     = 0;
    rcPwmInTimer.Init.CounterMode       = TIM_COUNTERMODE_UP;
    rcPwmInTimer.Init.RepetitionCounter = 0;
     
    // Commit the timer config
    HAL_TIM_IC_Init(&rcPwmInTimer);
     
    // Configure the input capture channel
    rcPwmInIC.ICPolarity  = TIM_ICPOLARITY_FALLING;
    rcPwmInIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    rcPwmInIC.ICPrescaler = TIM_ICPSC_DIV1;
    rcPwmInIC.ICFilter    = 0;
     
    // Commit the input capture config
    HAL_TIM_IC_ConfigChannel(&rcPwmInTimer, &rcPwmInIC, TIM_CHANNEL_1);
     
    // Setup external triggering
    TIM_SlaveConfigTypeDef TIM_SlaveConfig;
    TIM_SlaveConfig.InputTrigger        = TIM_TS_TI1FP1;
    TIM_SlaveConfig.SlaveMode           = TIM_SLAVEMODE_RESET;
    TIM_SlaveConfig.TriggerPrescaler    = TIM_TRIGGERPRESCALER_DIV1;
    TIM_SlaveConfig.TriggerPolarity     = TIM_CLOCKPOLARITY_RISING;
    TIM_SlaveConfig.TriggerFilter       = 0;
 
    // Commit the trigger configuration
    HAL_TIM_SlaveConfigSynchronization(&rcPwmInTimer, &TIM_SlaveConfig);
     
    // Now start input capture
    HAL_TIM_IC_Start_IT(&rcPwmInTimer, TIM_CHANNEL_1);
}
 
extern "C" void TIM14_IRQHandler()
{
    // Determine where this interrupt came from
    if (__HAL_TIM_GET_IT_SOURCE(&rcPwmInTimer, TIM_IT_CC1)!=RESET)
    {
        // Clear the flag
        __HAL_TIM_CLEAR_IT(&rcPwmInTimer, TIM_IT_CC1);
     
        // Get the captured value
        PwmInCaptureData.LastCapture = HAL_TIM_ReadCapturedValue(&rcPwmInTimer, TIM_CHANNEL_1);
 
        // Immeditly clear the timer
        //__HAL_TIM_SetCounter(&rcPwmInTimer, 0);
    }
}


Thanks!

Outcomes