cancel
Showing results for 
Search instead for 
Did you mean: 

Encoder Mode TIM1

andywild
Associate II
Posted on February 08, 2009 at 15:34

Encoder Mode TIM1

8 REPLIES 8
andywild
Associate II
Posted on May 17, 2011 at 12:18

Hi,

to have a high resolution in encoder mode it is essential to use both edges on each of the two signals TI1FP1 and TI2FP2. These signals are coming out of the Filter & Edge Detectors provided for each timer.

However for my understanding the edge detector can only be configured in terms of POLARITY of the signal. So either the rising or the falling edge can be used. This done by the CC1P and CC2P Bits respectivly.

In Encoder Mode obviously both edges are used according to the counting diagrams in the reference manual.

But where are the bits to configure ''both edges''?

Does Encoder Mode force the counter to use both edges regardless of CC1P/CC2P?

Thanks for your help

Andi

16-32micros
Associate III
Posted on May 17, 2011 at 12:18

Hi Andi,

To select Encoder Interface mode write SMS=‘001’ in the TIM1_SMCR register if the counter is counting on TI2 edges only, SMS=’010’ if it is counting on TI1 edges only and SMS=’011’ if it is counting on both TI1 and TI2 edges.

Select the TI1 and TI2 polarity by programming the CC1P and CC2P bits in the TIM1_CCER register.

Therefore, you should select:

SMS: 001: Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 level.

SMS: 010: Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 level.

SMS: 011: Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input.

And this configuration depends on your TI1 and TI2 polarity programming (you should choose only one of this polarity in CC1P or/and one of this polarity CC2P bits in the TIM1_CCER register).

Thx

utelettronico
Associate II
Posted on May 17, 2011 at 12:18

Hi Thx,

from your post seems that the encoder function of TIM1 works both with quadrature encoder and clock-direction encoder (one pin with count edge and the other one with direction). Is this correct? Is there any application note that explain this deeply?

Andrea

utelettronico
Associate II
Posted on May 17, 2011 at 12:18

Hi,

Is there an error in reference manual about encoder functionality?

In the TABLE 40 (p.240) seems that while counting on TI1 only or TI2 only the counter is incremented on rising edge and decremented on falling edge. So for each impulse does the counter simply produce a glitch?

I think that, for an useful counting mode, the counter should be incremented only on rising edge and not decremented on the falling one. The up-down direction should be selected by the other channel.

Thanks

utelettronico

[ This message was edited by: utelettronico on 16-07-2008 11:42 ]

darcy
Associate II
Posted on May 17, 2011 at 12:18

Hi, I'm starting to wonder the same thing! I've been scouring forums and anything I can think of to find out more info about how to interface with the quad encoder. The best I've had it working is for TIM1_CNT to have either incremented by 1 or decremented by 1 (to 0xFFFF, or whatever the ARR is set to). This certainly looks like we're counting up/down by one on every edge - as opposed to only on a single edge. I can see the DIR bit changing but it tends to switch on/off even though the direction of travel is unchanged.

Setup is...

Code:

<BR>RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); <BR>RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); <BR> <BR>GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; <BR>GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; <BR>GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; <BR>GPIO_Init(GPIOA, &GPIO_InitStructure); <BR> <BR>GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; <BR>GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; <BR>GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; <BR>GPIO_Init(GPIOA, &GPIO_InitStructure); <BR> <BR>TIM1->SMCR=(u16)0x0001; <BR>TIM1->ARR=(u16)0xFFFF; <BR>//Enabling filters has no affect <BR>TIM1->CCMR1=(u16)0x0101; <BR>TIM1->CCMR2=(u16)0x0000; <BR>//TI1 polarity inverted (tried all combinations) <BR>TIM1->CCER=(u16)0x0013; <BR>TIM1->PSC=(u16)0x0000; <BR> <BR>TIM1->CR1=(u16)0x0001; <BR> <BR>/* <BR>Waveform... <BR> <BR>Counter should increment on falling edge of ChA while ChB is logic low. <BR>Counter should increment on falling edge of ChA while ChB is logic high. <BR> <BR> ----- ----- ----- <BR> | | | | | | <BR>ChA(TI2) ----- ----- ----- ----- <BR> ----- ----- ----- <BR> | | | | | | <BR>ChB(TI1) --- ----- ----- ----- <BR>*/ <BR>

I really would have thought this well advertised feature would have been included in the examples and libraries! Even the library config for the encoder isn't worth using as there's still so much register manipulation to perform outside the library

Is there anyone in the forum group that could help out with this please?

Thanks all

Darcy

[ This message was edited by: darcy.williams on 07-01-2009 01:39 ]

[ This message was edited by: darcy.williams on 07-01-2009 02:45 ]

redmonds
Associate II
Posted on May 17, 2011 at 12:18

Hi darcy,

I'm also keen to try and get the quadrature encoder functionality on stm32 working. And not having much luck.

I was a bit confused by your code extract.

You seem to be configuring TIM1 and PA0 and PA1. I believe that PA0 and PA1 are connected to TIM2.

If that fixes it for you, please could you post your working code as I'm not having any joy.

Thanks,

Richard

redmonds
Associate II
Posted on May 17, 2011 at 12:18

Here's some code that works for me.

It uses PA0 and PA1 on TIM2. Some of the initialisation may be overkill.

void EncoderInit(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIOA->BSRR = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_Init(GPIOA, &GPIO_InitStructure);

TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

TIM_Cmd(TIM2, ENABLE);

}

u16 Encoder(void)

{

u32 count = TIM2->CNT;

return count;

}

darcy
Associate II
Posted on May 17, 2011 at 12:18

Quote:

I'm also keen to try and get the quadrature encoder functionality on stm32 working. And not having much luck.

I was a bit confused by your code extract.

You seem to be configuring TIM1 and PA0 and PA1. I believe that PA0 and PA1 are connected to TIM2.

If that fixes it for you, please could you post your working code as I'm not having any joy.

Hi Richard,

I should have posted a reply here earlier but I often end up avoiding this forum as it isn't all that nice to use (compared to most other uC forums). Which is unfortunate because it's often the place where the most useful responses come from.

In the end I tracked the problem down to the schematic footprint the h/w engineer had made up - where the labels referred to TIM1 instead of TIM2. Once I figured that out it started working immediately 🙂