cancel
Showing results for 
Search instead for 
Did you mean: 

Quadrature Encoder STM32 Z Capture

arapp1990
Associate II
Posted on February 23, 2015 at 15:03

Hello,

I'd like to use an quadrature encoder connected to my STM32F4 Discovery Board.

I have connected the A and B outputs to PC6 and PC7. CH1 and CH2 of TIM8.

It works pretty good, the timer counts.

Now I'd like to use the Z output of the encoder to avoid errors.

I have connected Z to the CH3 of TIM8 (PC8) and configured it as an capture input.

In the capture interrupt I want compare the capture value with the expected value and correct the current TIMx->CNT.

Unfortunately it never enters the TIM8_CC_IRQHandler.

I use this encoder:

https://www.sparkfun.com/products/11102

I would be very grateful if someone of you would look at my code.

void

configQuadratureEncoder(

void

)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;

// A, B, Z; CH1, CH2, CH3

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

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);

GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);

GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);

/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 0x07ff;

// Encoder -> 2048 per rotation => 0x07FF = 2047(dez)

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

// Capture Config

NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannel = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_ICInitTypeDef TIM_ICInitStructure;

TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0;

TIM_ICInit(TIM8, &TIM_ICInitStructure);

TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);

TIM_ITConfig(TIM8, TIM_IT_CC3, ENABLE);

// END Capture Config

TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI2, TIM_ICPolarity_Falling, TIM_ICPolarity_Rising);

TIM_Cmd(TIM8, ENABLE);

TIM8->CNT=0;

}

void

TIM8_CC_IRQHandler (

void

)

{

GPIOD->ODR ^= GPIO_Pin_12;

// LED toggle

GPIOD->ODR ^= GPIO_Pin_11;

// Scope control

if

(TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET)

{

// correction

TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);

}

}

2 REPLIES 2
Posted on February 23, 2015 at 22:28

Are you

a) Sure it's generating a pulse

b) Using C++

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
arapp1990
Associate II
Posted on February 23, 2015 at 23:20

Just checked, yes it generates a pulse. It is inverted: 

The Z output is the most of the time HIGH and generates one pulse to LOW at the zero point of the encoder.

I use C together with the  CMSIS files.