2016-04-09 07:45 AM
Hello,
I wanna calculate the motor speed using timer of STM32F4. I wanna know the time spended in one revolution. So , who would explain for me how can I do that . thanks a lot.2016-04-09 09:12 AM
The timer counts at a fixed rate, you use the counter to time-stamp the two time separated events A and B, subtracting them (B - A) will give you the clock ticks of the interval. So if the timer counts at 1 MHz, and the motor rotates at 50 times a second (3000 rpm), then the counter will indicate 20000 ticks have passed. ie 1,000,000 / 50
There have been several threads covering the measurement of frequency, review them.2016-04-09 12:35 PM
2016-04-09 05:24 PM
The most accurate and efficient way to measure the time between two pulses using a microcontroller is a technique called ''Input Capture'', or ''IC''. Read the sections of the STM32F407's reference manual that describe its Timer peripherals, most of which are capable of IC.
2016-04-09 05:34 PM
The mechanics here are not inherently complicated,
// STM32F4-Discovery TIM2 32-bit Input Capture (PA.01 TIM2_CH2) - sourcer32@gmail.com #include ''stm32f4_discovery.h'' /**************************************************************************/ void RCC_Configuration(void) { /* GPIOA clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* TIM2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); } /**************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the TIM2 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /**************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* GPIOA Configuration: TIM2 CH2 (PA1) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect TIM2 pins to AF */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); } /**************************************************************************/ void TIM2_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit maximal TIM_TimeBaseStructure.TIM_Prescaler = ((SystemCoreClock / 2) / 1000000) - 1; // 1 MHz TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Input capture configuration */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM2, &TIM_ICInitStructure); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); /* TIM Interrupts enable */ TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); } /**************************************************************************/ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) { static uint32_t A, B; uint32_t DeltaTicks; TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); B = TIM2->CCR2; DeltaTicks = B - A; // Ticks of 1 MHz clock, ie 1us per tick // Do something with the measurement of time A = B; } } /**************************************************************************/ int main(void) { RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); TIM2_Configuration(); while(1); // Do not exit } /**************************************************************************/ #ifdef 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) */ while (1) {} } #endif2016-04-10 11:14 AM
2016-04-10 12:49 PM
No in this case the timer keeps ticking, which is why you keep a running total from interrupt to interrupt, and look at the *difference*
Now if you used PWM Input mode, then the timer would get reset, and you'd use two of the channels to hold the period and duty. These modes are covered in the Reference Manual2016-04-11 08:30 AM
2016-04-12 08:54 AM
2016-04-12 10:18 AM
I'm afraid I don't have any resources to apply to your problem.
If you are using a switch to generate the pulses, perhaps there is some noise/bouncing coming from that. Look at the options related to filtering the input.I would suggest using another timer to generate periodic pulses, and wire those pins externally, and use that to measure and evaluate the code you have.