AnsweredAssumed Answered

Quadrature encoders on STM32F4

Question asked by rebeat.pete on Apr 29, 2013
Latest reply on May 26, 2015 by Clive One
Hi everyone and thanks in advance for your advices.

I'm using a quadrature encoder from Bourns :
with an STM32F4 chip.

I have two questions : 

- First of all, is it possible to use multiple encoders with a reasonable amount of used pins on the STM32? Maybe with shift registers or dedicated components? I have to implement 9 encoders for my project and I can't use 9 different timers to receive the datas.

- My second question is about the code I already wrote. It works and ables me to read the encoder position but when I turn it too fast, it seems that I loose some datas. Any help with that? Here is the code : 

#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
//  |  TIM4_CH1  pin (PB.06) |
//  |  TIM4_CH2  pin (PB.07) |
//  --------------------------
#define Codeur_A           GPIO_Pin_6
#define Codeur_A_SOURCE    GPIO_PinSource6
#define Codeur_B           GPIO_Pin_7
#define Codeur_B_SOURCE    GPIO_PinSource7
#define Codeur_GPIO        GPIOB
#define Codeur_RCC         RCC_AHB1Periph_GPIOB
#define Codeur_AF          GPIO_AF_TIM4
#define Codeur_TIMER       TIM4
#define Codeur_TIMER_CLK   RCC_APB1Periph_TIM4
#define Codeur_COUNT()     Codeur_TIMER->CNT
#define Led_Red            GPIO_Pin_12
#define Led_Green          GPIO_Pin_14
#define Led_GPIO           GPIOD
#define Led_RCC            RCC_AHB1Periph_GPIOD
volatile int16_t Codeur_count;
volatile int32_t Codeur_total;
static volatile int16_t Codeur_old;
static volatile int16_t Codeur_actual;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIMER_Configuration(void);
void CODEUR_Reset(void);
void CODEUR_Read(void);
int main(void)
    return 0;
void CODEUR_RESET (void)
    Codeur_old = 0;
    Codeur_total = 0;
    TIM_SetCounter (Codeur_TIMER, 0);
void TIMER_Configuration(void)
    // set them up as encoder inputs
    // set both inputs to rising polarity to let it use both edges
    TIM_EncoderInterfaceConfig (Codeur_TIMER, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
    TIM_SetAutoreload (Codeur_TIMER, 0xffff);
    // turn on the timer/counters
    TIM_Cmd (Codeur_TIMER, ENABLE);
    // Reset
void CODEUR_Read (void)
    Codeur_old = Codeur_actual;
    Codeur_actual = TIM_GetCounter (Codeur_TIMER) ;
    Codeur_count = Codeur_actual - Codeur_old;
    Codeur_total += Codeur_count;
void RCC_Configuration(void)
    // Enable RCC codeur
    RCC_AHB1PeriphClockCmd(Codeur_RCC, ENABLE);
    // Enable RCC led
    RCC_AHB1PeriphClockCmd(Led_RCC, ENABLE);
    // Enable Timer 4 clock
    RCC_APB1PeriphClockCmd(Codeur_TIMER_CLK, ENABLE);
void GPIO_Configuration(void)
    GPIO_InitTypeDef GPIO_InitStructure;
    // 2 Inputs for A and B Encoder Channels
    GPIO_InitStructure.GPIO_Pin = Codeur_A|Codeur_B;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(Codeur_GPIO, &GPIO_InitStructure);
    //Timer AF Pins Configuration
    GPIO_PinAFConfig(Codeur_GPIO, Codeur_A_SOURCE, Codeur_AF);
    GPIO_PinAFConfig(Codeur_GPIO, Codeur_B_SOURCE, Codeur_AF);
    // Output Leds
    GPIO_InitStructure.GPIO_Pin = Led_Red|Led_Green;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(Led_GPIO, &GPIO_InitStructure);

Thanks again.