cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 Discovery Quadrature Encoding

mattfox
Associate II
Posted on June 21, 2013 at 22:44

I'm working on getting quadrature encoding working through either TIM1 or TIM8.  I searched the past topics on this forum, but I can't tell how mine is different/ why it isn't working.  I'm using USART to debug the count, and I'm consistently getting a counter value of 0, though I can tell my input is valid.  

Can anyone see what i'm doing wrong in this code?  Thanks so much for taking the time to look at it.

/*

 * main.c

 *

 *  Created on: Jun 20, 2013

 */

&sharpinclude ''main.h''

&sharpinclude ''common.h''

&sharpinclude ''usart.h''

&sharpinclude ''peripherals.h''

static void TIM_Config(void);

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

uint32_t a=0;

uint16_t i;

int main(void)

{

/* Initialize USART2 */

USART2_Init(115200, TRUE);

printf(''\fUART2 initialized\n\r'');

TIM_Config();

/* TIM1 clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 , ENABLE);

/* Time Base configuration */

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

//Configure the encoder interface

TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge, TIM_ICPolarity_BothEdge);

TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_ARRPreloadConfig(TIM8, ENABLE);

/* TIM1 counter enable */

TIM_Cmd(TIM8, ENABLE);

//Counter loop

while(1)

{

printf(''Counter: %d\n\r'', (uint16_t)(TIM1->CNT & 0x0000ffff));

for(i=0; i<30000; i++)

{

a++;

a = a%5;

}

}

return 0;

}

static void TIM_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* GPIOA, GPIOB and GPIOE Clocks enable */

RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOC, ENABLE);

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

//Configure pins

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_4);  //C6 -TIM1_CH1

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_4);  //C7  TIM1_CH2

// GPIO_Init(GPIOC, &GPIO_InitStructure);

// GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_2);  //C6 -TIM1_CH1

// GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_2);  //C7  TIM1_CH2

}

&sharpifdef  USE_FULL_ASSERT

/**

 * @brief  Reports the name of the source file and the source line number

 *         where the assert_param error has occurred.

 * @param  file: pointer to the source file name

 * @param  line: assert_param error line source number

 * @retval None

 */

void assert_failed(uint8_t* file, uint32_t line)

{

/* User can add his own implementation to report the file name and line number,

     ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

/* Infinite loop */

while (1)

{

}

}

&sharpendif

#input-capture #quadrature-encoder
15 REPLIES 15
Posted on June 21, 2013 at 23:33

printf(''Counter: %d\n\r'', (uint16_t)(TIM1->CNT & 0x0000ffff));

TIM8?

I would need to double check AF settings.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
raptorhal2
Lead
Posted on June 21, 2013 at 23:47

Cancel - misread the problem

mattfox
Associate II
Posted on June 22, 2013 at 03:13

Oh, yeah, I forgot to change that from when I was trying TIM1.  Even after changing that, I still get 0 from the counter.  Thanks for pointing that out, though.  That definitely needed to be changed.

Any ideas what it could be?

Posted on June 22, 2013 at 03:57

Any ideas what it could be?

 

As stupid as it might sound, I'd probably try this for TIM1 or 8, cause they are ''special''

  /* TIM1 Main Output Enable */

  TIM_CtrlPWMOutputs(TIM1, ENABLE);

I don't have the ability to test the F3-DISCO right now.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 22, 2013 at 06:38

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_4);  //PC6 -TIM8_CH1

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_4);  //PC7  TIM8_CH2

Those look Ok, what pins are you using for TIM1 ?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mattfox
Associate II
Posted on June 24, 2013 at 15:41

Thanks for the help! I just tried adding in the 

 TIM_CtrlPWMOutputs(TIM1, ENABLE);

and it worked.  The only issue I'm running into now is that the counter seems to be a bit biased towards counting up.  When I set it to count only on the rising or falling edge, it does a good job of counting up and then down, etc.  However, when I use both edges, trying to get X4, it seems to count up with a big bias.  Any idea why it would be biased towards counting up?

By the way, I'm using an arduino and a small script to model the quadrature encoding, so I know that it shouldn't go above a certain value, which it is when I do both edges.

Also, I was wondering if it is possible for the timer to use it's top 16 bits as well, or if those are strictly reserved.  I'd like to count to numbers that are larger that a 16 bit number can allow.

mattfox
Associate II
Posted on June 24, 2013 at 16:06

Oh, I take that back. Even the rising and falling aren't working correctly.  It seems like it can't nearly catch the speed of the encoding - for example, it will count up 4 when the arduino program simulates 12658 spins.  Any ideas for what this issue could be?

Posted on June 24, 2013 at 16:23

TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 16-bit

TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mattfox
Associate II
Posted on June 24, 2013 at 17:01

Hmm, I tried that, but the counter still never surpasses 65,000 or so.  I was asking because of these lines in the reference manual:

TIM1/8 CNT Register

Bits 30:16 Reserved, always read as 0.

Bits 15:0 CNT[15:0]: Counter value

Is there something else I need to change to get this to work properly?  Also, any ideas about the encoder not catching all of the rotations?