Reading quadrature encoder output using NUCLEO-F072RB

662 views Asked by At

I am using the NUCLEO-F072RB board in conjunction with X2C to read the output of a DC motor encoder, in order to measure its speed. According to the datasheet, using timers TIM2 and TIM3 it is possible to perform this read. For that purpose, I followed this and this sources to write the following code:

/** - configure A6 for encoder input (T1) */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_Init (GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_InitStruct.GPIO_Pin, GPIO_AF_1);

/** - configure A7 for encoder input (T2) */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_Init (GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_InitStruct.GPIO_Pin, GPIO_AF_1);

/**********************************************/
/* Encoder input setup */

/* TIM3 clock enabled */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* TIM3 DeInit */
TIM_DeInit(TIM3);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure); 

/* Configure the timer TIM3 for encoder input */
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,  TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_SetAutoreload (TIM3, 0xffff);

/* TIM3 counter enable */
TIM_Cmd(TIM3, ENABLE);

Here I use the alternate function 1 for both inputs, which, according to the datasheet, corresponds to TIM3. As far as I understand, with that setup, every time there is a rising edge on T1 (GPIO A6 in this case), the TIM3 counter increases by 1, and when there is a rising edge on T2 (A7), the counter decreases by one.

For debugging purposes, I set a value to a variable I can monitor. If the counter is 1 or greater the value is INT16_MAX is set, otherwise 0 is set.

if (TIM_GetCounter(TIM3) > 0x0) {
    Inports.Encoder_Input = INT16_MAX;
} else {
    Inports.Encoder_Input = 0;
}

Before using the actual encoder, I have tried using a switch to manually generate rising edges and a PWM output from another GPIO to feed the inputs (GPIO's A6 and A7). This way, I expect the TIM3 counter starts counting up/down, but nothing happens. I have noticed that when I connect a signal to A6 or A7, it gets degradated, which may explain why no rising edges are detected. Measuring with a DC multimeter the resistance on these inputs I get approximately 40 Ohm, which is very low for an input port.

How can I properly setup the timer and the GPIOs to be able to read the encoder signal and get the TIM3 counter start counting?

0

There are 0 answers