AnsweredAssumed Answered

Measure time between encoder counts

Question asked by bkatz on Mar 6, 2016
Latest reply on Nov 25, 2016 by Clive One

I'm trying to measure the period between counts on a quadrature encoder while simultaneously keeping count.  

I'm using an F446 on a Nucleo dev board (for now), and using mbed for compiling.  I've got keeping track of the encoder count working just fine on PA0 and PA1, TIM2.  Basically, I'd like to store the count of a free-running timer every time TIM2->CNT  changes value (i.e. whenever there's a rising or falling edge on either encoder channel)

According to the reference (RM0090, p609), "You can obtain dynamic information (speed, acceleration, deceleration) by measuring the period between two encoder events using a second timer configured in capture mode.", but I don't really know how to go about this.  The pins are set up for alternate function 1 (attached to TIM2_CH1 and TIM2_CH2), so I don't know how to also attach them to another timer for input capture. 

Any advice about how to do this would be greatly appreciated!

Here's my encoder setup code, for reference:

RCC->AHB1ENR |= 0x00000001;  // Enable clock for GPIOA
GPIOA->MODER   |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1 ;           //PA0,  PA1 as Alternate Function
GPIOA->OTYPER  |= GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 ;                 //PA0,  PA1 as Inputs 
GPIOA->PUPDR   |= GPIO_PUPDR_PUPDR0_1 | GPIO_PUPDR_PUPDR1_1 ;           // Pull Down
GPIOA->AFR[0]  |= 0x00000011 ;                                          //  AF01 for PA0,  PA1    
 // configure TIM2 as Encoder input
RCC->APB1ENR |= 0x00000001;  // Enable clock for TIM2
TIM2->SMCR  = 0x0003;     // SMS='011' (Encoder mode 3)  < TIM slave mode control register
TIM2->CCMR1 = 0xf1f1;     // CC1S='01' CC2S='01'         < TIM capture/compare mode register 1
TIM2->CCMR2 = 0x0000;     //                             < TIM capture/compare mode register 2
TIM2->CCER  = 0x0011;     // CC1P CC2P                   < TIM capture/compare enable register
TIM2->PSC   = 0x0000;     // Prescaler = (0+1)           < TIM prescaler
TIM2->ARR   = 0xffffffff; // reload at 0xfffffff         < TIM auto-reload register
TIM2->CNT = 0;  //reset the counter before we use it  
TIM2->CR1   = 0x01;     // CEN(Counter ENable)='1'