2016-03-05 10:39 PM
Hello,
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! Thanks 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->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 ; 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) < TIMslave mode control register
TIM2->CCMR1 = 0xf1f1; // CC1S='01' CC2S='01' < TIMcapture/compare mode register 1
TIM2->CCMR2 = 0x0000; // < TIMcapture/compare mode register 2
TIM2->CCER = 0x0011; // CC1P CC2P < TIMcapture/compare enable register
TIM2->PSC = 0x0000; // Prescaler = (0+1) < TIMprescaler
TIM2->ARR = 0xffffffff; // reload at 0xfffffff < TIMauto-reload register
TIM2->CNT = 0; //reset the counter before we use it TIM2->CR1 = 0x01; // CEN(Counter ENable)='1' #stm32 #tim #encoder2016-03-06 07:37 AM
Well I suspect the way forward is to set up a Master-Slave relationship, where the TRGO of TIM2 feeds to the ITRx of another free running counter, gate that to TRC to latch the CNT to CCRx of that counter, effectively time stamping the arrival. Review timer block diagrams in the Reference Manual RM0090 if these relationships are unclear.
One might also be able to trigger a DMA action reading a free running counter, and time stamp things that way.2016-03-06 10:12 PM
Thanks for the help! Seem to have things working.
Master Mode Selection for TIM2 set to Compare Pulse :TIM2->CR2 = 0x030; //MMS = 101
TIM8 Triggering on ITR2 (TIM2), SMS in Reset Mode:
TIM8->SMCR = 0x94; //TS = 010 for ITR2, SMS = 100
TIM8 Capture/Compare 1 Selection to TRC
TIM8->CCMR1 = 0x3;// CC1S = 11, IC1 mapped on TRC
Trigger on rising edge:
TIM8->CCER |= TIM_CCER_CC1P;
Enable Output:
TIM8->CCER |= TIM_CCER_CC1E;
so TIM8->CNT gets stored in TIM8->CCR1 when triggered by TIM2
2016-11-25 11:44 AM
Hi
I am trying to measure the period (TIM2 encoder mode, TIM4-Reset), but the register CNT TIM4 constantly changing, even in the case where the encoder is stationary. Why is this happening?2016-11-25 02:58 PM
If TIM4 is a free running counter you expect to use to time stamp the period you'd better hope it keeps counting up.
Perhaps you can describe your configuration details with a little more specificity