cancel
Showing results for 
Search instead for 
Did you mean: 

Encoder Interface on TIM2-TIM5

Atay.Stefan
Associate II
Posted on November 20, 2012 at 15:48

Hello,

I am having difficulty configuring the quadrature encoder interface on timers 2 through 5.  I have successfully configured the encoder interface on timers 1 and 8, using the code below:

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStruct;

GPIO_InitTypeDef  GPIO_InitStructure;

//Configure peripheral clocks

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);  

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  

//Configure pins

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);  //C6 -TIM8_CH1

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8);  //C7  TIM8_CH2

//Configure Timer

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_Period = 8191;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  

TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_ARRPreloadConfig(TIM8, ENABLE);

//Debounce filter

TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM8, &TIM_ICInitStruct);

TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM8, &TIM_ICInitStruct);

//Setup quadrature encoder and enable timer

TIM_EncoderInterfaceConfig(TIM8,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);

TIM_Cmd(TIM8, ENABLE); 

However, when I try to use the same code to configure the quadrature encoder interface using timer 3 (or 4), I am unable to do so.  Specifically, I used the exact code shown below.  It is identical to the code above, with the following exceptions:

1) Timer 3 is used instead of timer 8

2) Timer 3 requires use of the APB1 clock instead of the APB2 clock

Also, note that TIM8_CH1 and TIM8_CH2 are mapped to pins C6 and C7, respectively.  Likewise, TIM3_CH1 and TIM3_CH2 are also mapped to C6 and C7, respectively.

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStruct;

GPIO_InitTypeDef  GPIO_InitStructure;

//Configure peripheral clocks

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

//Configure pins

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);  //C6 - TIM3_CH1

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);  //C7 - TIM3_CH2

//Configure Timer

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_Period = 8191;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_ARRPreloadConfig(TIM3, ENABLE);

//Debounce filter

TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM3, &TIM_ICInitStruct);

TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM3, &TIM_ICInitStruct);

//Setup quadrature encoder and enable timer

TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);

TIM_Cmd(TIM3, ENABLE);

It is not clear to me why the code above does not successfully configure the encoder interface module for timer 3.  I would appreciate any help in determining what my errors are.  Thank you!

15 REPLIES 15

This stuff is from over 5-6 years ago, please try not to poke these zombie threads.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

https://community.st.com/s/question/0D50X00009XkibnSAB/stm32f107-quadrature-encoder-example

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hey!

I am old, but not a zombie yet ;)

I'm probably older, but you got your code from 6 years ago to hand?

0690X000006CTOjQAO.jpg

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
FF1
Associate III

Thank you!

With your code I was able to manage the encoder on the TIM2.

Just a note for others, the useful and nice code (firmware181\drivers\ui\encoder) posted from @M0NKA​ is for the STM32F4 series, if you (like me) have to work with the STM32F1 series (e.g. with the STEVAL-PCC009V2) you have to do some little changes that I've reported below (code tested with IAR IDE v8.32.1).

Code is made by means of the StdPeriheral library driver (v 3.5.0).

//*----------------------------------------------------------------------------
//* Function Name       : TIM2_RotaryEncoder_Init
//* Input Parameters    : -
//* Output Parameters   : -
//* Functions called    : -
//*----------------------------------------------------------------------------
void TIM2_RotaryEncoder_Init(void)
{
 
	TIM_TimeBaseInitTypeDef 	TIM_TimeBaseStructure;
	GPIO_InitTypeDef 	        GPIO_InitStructure;
        
        // TIM2 peripheral clock enable
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
	// I/O pins settings and initialisation
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  // PA0
	GPIO_Init(GPIOA, &GPIO_InitStructure);
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // PA1
	GPIO_Init(GPIOA, &GPIO_InitStructure);
 
        // TIM2 structure initialisation
	TIM_TimeBaseStructure.TIM_Period = 399; // 100 PPR encoder used in x4 mode
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
        // Interrupt flag reset
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        
	// Encoder interface configuration (A&B, x4 mode, falling edge)
        TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
 
        // Reset counter TIM2
        TIM_SetCounter(TIM2, 0);
        
        // TIM2 enable
	TIM_Cmd(TIM2, ENABLE);
        
        // Reset flag update interrupt
        TIM_ClearFlag(TIM2, TIM_FLAG_Update);
        
        // Enable interrupt on TIM2 Update (just as test for the interrupt)
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
        
        // Priority 2 bit pre-emption, 2 bit subpriority
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        
        // NVIC configuration
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ;
	NVIC_Init(&NVIC_InitStructure);
}

The encoder was configured to have an output of 2.7 V maximum for each channel and was connected directly to the pin PA0 and PA1 of the J2 connector on the STEVAL-PCC009V2 evaluation board.

Despite this code is working I kindly ask some expert to take a look if some is not useful or other things are missing to have a correct initialisation code, because if this is working this not means that is also good or really completed written.

Thank again @M0NKA​ !

Best regards

Fabio