cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103RBTx, Tim3_CH3/4, Incremental Encoder

hackerli90
Associate II
Posted on November 30, 2015 at 12:54

Hello

Im currently trying to read a incremental encoder via timer3 (channel3/4). Im working with a STM32F103RBTx.

The encoder is connected to PC8 and PC9.

If i connect the encoder to PC6 and PC7 (Tim3_CH1/2), then i can successfully read the encoder value. But since im going to use PC6/PC7 otherwise, im trying to do the same thing with Tim3_CH3/4. (Funny thing is, the encoder_counter can still be read on PC6/7 even if i configure GPIO PC8 and 9) 

Is there something missing? 

Here some code:

  /* Encoder: Enable and set TIM3 general Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  

  

  

  

  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

/* GPIO Configuration */

#define PORT_TI GPIOC

#define GPIO_TI1 GPIO_Pin_8

#define GPIO_TI2 GPIO_Pin_9

/* Encoder: Configure PC8 and PC9 as input function */

GPIO_InitStructure.GPIO_Pin = GPIO_TI1 | GPIO_TI2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(PORT_TI, &GPIO_InitStructure);

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Ref. Man. p. 178 (DocID13902 Rev 15)

void TIM_Configuration (void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

/* 32bit Timestamp: Configuration of Timer2 for Slave */

TIM_TimeBaseStructure.TIM_Prescaler = 0; 

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

// Select TIM1 Trigger Output as Trigger

TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);

  // Slave Mode selection: Trigger on external Trigger

  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);

  // Enable the TIM2 Master Slave Mode

  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

// TIM2 enable

TIM_Cmd(TIM2, ENABLE);  

/* 32bit Timestamp: Configuration of Timer1 for Master */

TIM_TimeBaseStructure.TIM_Prescaler = 7199; // Prescaler = Teilerwert - 1

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  // Master Mode selection: Output Trigger on Update (Overflow)

  TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);

// Select the Master Slave Mode: Output Trigger TRGO on TIM_TS_ITR0

TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

// Clear Counters

TIM_SetCounter (TIM1, 0);

TIM_SetCounter (TIM2, 0);

// TIM1 enable

TIM_Cmd(TIM1, ENABLE);

/* 32bit Encoder: Configuration of Timer3 in Encoder Mode */

TIM_TimeBaseStructure.TIM_Prescaler = 0; 

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

// Interrupt Flag löschen

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

// Enable Interrupt on update (under-/overflow of timer)

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

// TIM enable

TIM_Cmd(TIM3, ENABLE); 

}

void TIM3_IRQHandler(void)

{

// Aktueller Zählerstand

static uint16_t counterValue;

// Lesen des aktuellen Zählerstands

counterValue = TIM_GetCounter(TIM3);

if(counterValue  < 0x8000)

{

// Nach Overflow werden die oberen 2 Byte inkrementiert

TIM3CounterHighByte++;

} else

{

// Nach Underflow werden die oberen 2 Byte dekrementiert

TIM3CounterHighByte--;

}

/*****************************************************************************

* Beispiel zur Anpassung der Auflösung des Encoders auf 24bit.

*****************************************************************************/

/*if(counterValue  < 0x8000)

{

TIM3CounterHighByte++;

TIM3CounterHighByte &= 0x00FF;

} else

{

TIM3CounterHighByte--;

TIM3CounterHighByte &= 0x00FF;

}*/

/* Clear TIM3 Trigger pending bit */

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

}
4 REPLIES 4
Posted on November 30, 2015 at 14:42

Is there something missing?

A whole bunch of imagined connectivity? The diagram for the TIM only shows routing for Channel 1 and 2

You should also qualify the source of interrupts, and clear them early in the handler, clearing them as the last thing before exit exposes you to a race hazard.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hackerli90
Associate II
Posted on November 30, 2015 at 19:41

hello clive

thanks for your response.

where do you mean that the code is routing for channel 1 and 2? thats what im looking for, the route channel 3 and 4 instead.

Posted on November 30, 2015 at 19:50

I'm saying there is no connectivity for channels 3 and 4 with respect to Encoder Mode.

0690X00000605FvQAI.png

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hackerli90
Associate II
Posted on December 01, 2015 at 09:53

ah thats it. thanks clive.