AnsweredAssumed Answered

STM32F407 captured value two times bigger than expected

Question asked by li.gavin on Jan 14, 2015
Latest reply on Jan 15, 2015 by waclawek.jan
Hi, I have the MCU run SysClk at 168MHz, and I setup the timer to capture mode, but the returned value is two times bigger than expected. I checked the waveform of the toggled LED, it is correct, just the Timer capture value is bigger. Please help me understand why.

*                    Supported STM32F40xxx/41xxx devices
*-----------------------------------------------------------------------------
*        System Clock source                    | PLL (HSE)
*-----------------------------------------------------------------------------
*        SYSCLK(Hz)                             | 168000000
*-----------------------------------------------------------------------------
*        HCLK(Hz)                               | 168000000
*-----------------------------------------------------------------------------
*        AHB Prescaler                          | 1
*-----------------------------------------------------------------------------
*        APB1 Prescaler                         | 4
*-----------------------------------------------------------------------------
*        APB2 Prescaler                         | 2


static uint16_t *buf_tim1;
static uint16_t *buf_tim3;
  
void capture_init(TIM_TypeDef* TIMx, uint32_t *buf, int total_samples_per_channel)
{
  
    /* TIM Update Frequency = TIM Clock / (P * Q)
     *
     * Where Prescaler = P - 1, and Period = Q - 1
     *
     * TIM1 input freq = 84MHz, it is in APB2
     * TIM3 input freq = 42MHz, it is in APB1
     */
  
    if ((TIMx != TIM1) && (TIMx != TIM3)) return;
  
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = ~0; // 65536us update // 0..FFFF
    if (TIMx == TIM1)
        TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1; // 0..FFFF
    else
        TIM_TimeBaseStructure.TIM_Prescaler = 42 - 1; // 0..FFFF
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //TIM_CKD_DIV1, TIM_CKD_DIV2, TIM_CKD_DIV4
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
  
    TIM_ICInitTypeDef  TIM_ICInitStructure;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
  
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
    TIM_ICInit(TIMx, &TIM_ICInitStructure);
    TIM_ITConfig(TIMx, TIM_IT_CC3, ENABLE);
  
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
    TIM_ICInit(TIMx, &TIM_ICInitStructure);
    TIM_ITConfig(TIMx, TIM_IT_CC4, ENABLE);
  
    NVIC_InitTypeDef NVIC_InitStructure;
    if (TIMx == TIM1) {
        /* Enable the TIM1 global Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
        buf_tim1 = (uint16_t*)buf;
    }
    else {
        /* Enable the TIM3 global Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
        buf_tim3 = (uint16_t*)buf;
    }
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
  
    /* TIM enable counter */
    TIM_Cmd(TIMx, ENABLE);
}
void TIM1_CC_IRQHandler(void)
{
    static uint16 u00, u01, u10, u11;
    if (TIM_GetITStatus(TIM1, TIM_IT_CC3)) {
        u11 = TIM_GetCapture3(TIM1);
        TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);
        buf_tim1[1] = u11 - u10;
        u10 = u11;
        gpio_toggle_pin(GPIOPortID_E, GPIOPinID_1);
    }
    if (TIM_GetITStatus(TIM1, TIM_IT_CC4)) {
        u01 = TIM_GetCapture4(TIM1);
        TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
        buf_tim1[0] = u01 - u00;
        u00 = u01;
        gpio_toggle_pin(GPIOPortID_E, GPIOPinID_0);
    }
}
void TIM3_IRQHandler(void)
{
    static uint16 u00, u01, u10, u11;
    if (TIM_GetITStatus(TIM3, TIM_IT_CC3)) {
        u11 = TIM_GetCapture3(TIM3);
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
        buf_tim3[1] = u11 - u10;
        u10 = u11;
        gpio_toggle_pin(GPIOPortID_E, GPIOPinID_3);
    }
    if (TIM_GetITStatus(TIM3, TIM_IT_CC4)) {
        u01 = TIM_GetCapture4(TIM3);
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
        buf_tim3[0] = u01 - u00;
        u00 = u01;
        gpio_toggle_pin(GPIOPortID_E, GPIOPinID_2);
    }
}
  
void main(void)
{
    uint16 capture[4];
    //initializations
    .....
      
    capture_init(TIM3, (uint32_t *)&capture[0], 1);
    capture_init(TIM1, (uint32_t *)&capture[2], 1);
    while(1);
}

Outcomes