2013-06-21 01:44 PM
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-encoder2013-06-21 02:33 PM
printf(''Counter: %d\n\r'', (uint16_t)(TIM1->CNT & 0x0000ffff));
TIM8? I would need to double check AF settings.2013-06-21 02:47 PM
Cancel - misread the problem
2013-06-21 06:13 PM
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?2013-06-21 06:57 PM
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.
2013-06-21 09:38 PM
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 ?2013-06-24 06:41 AM
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.2013-06-24 07:06 AM
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?
2013-06-24 07:23 AM
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 16-bit
TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit2013-06-24 08:01 AM
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 RegisterBits 30:16 Reserved, always read as 0.Bits 15:0 CNT[15:0]: Counter valueIs 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?