AnsweredAssumed Answered

STM32F4: In encoder mode, TIM2 counts only in one direction

Question asked by joseph.jiss on Sep 10, 2014
Latest reply on Sep 18, 2014 by ysaykal
Hi All,
I have a quadrature encoder interfaced to my STM32F427 using TIM2.
In encoder mode, TIM2 counts up in one direction of the motor but does not count up/down in the other direction.
I am adding my init code below, which I think is enough to get the encoder running (After going through STM32F4xx_StdPeriph_Driver and the forum here).

1) I have verified the A and B channels of the enocder going into STM32F4. They are proper 90 degree out of phase with leading or lagging for each direction respectively.
2) In one direction, TIM2 counts up from 0 and the count values are as expected.
3) In the other direction, TIM2 count just oscillates between 0x00000000 and 0xFFFFFFFF (And sometimes gives the value of 0x00000001).
4) In the properly counting direction (2 above), I could see that DIR bit in TIM2->CR1 is stable at 0.
5) In the non-counting direction (3 above), DIR bit is unstable and oscillates between 1 and 0.

    // Port A Configuration
    // GPIOA Periph clock enable
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    

    // Setup GPIO for ENC
    GPIO_InitStructure.GPIO_Pin =
        GPIO_Pin_0 |        // ENC1_CH1
        GPIO_Pin_1 |        // ENC1_CH2
        GPIO_Pin_6 |        // ENC2_CH1
        GPIO_Pin_7;         // ENC2_CH2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // Setup TIM2

    // Enable TIM2 clock
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // Configure GPIO pin alternate function
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
    // Configure GPIO pin alternate function
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

    // Configure TIM2 to read quadrature encoder
    TIM_EncoderInterfaceConfig( TIM2, TIM_EncoderMode_TI12,
                                   TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

    // Setup TimeBase for TIM2 (default values for now)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_Period = 0xFFFFFFFF;
    TIM_TimeBaseInitStruct.TIM_Prescaler = 0x0000;
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0x0000;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

    // Enable TIM2
    TIM_Cmd(TIM2, ENABLE);
    TIM_SetCounter( TIM2, 0x00000000 );

Any inputs or pointers for understanding this behavior will be really appreciated. Expecting your co-operation.