2015-02-02 05:20 PM
Hello,
I am endeavoring (as with every hair-pulling experience with the STM32F4) to measure/capture LOW frequency pulses. For this, I'm assuming I need to use a 32 bit timer: TIM2 or TIM5. This is a bit of a dilemma since TIM2 or TIM5 do not have a capture compare. So how to measure low frequency pulses? Thank you.... #stm32f4-timer-capture-compare2015-02-02 05:50 PM
This is a bit of a dilemma since TIM2 or TIM5 do not have a capture compare.
Are you sure? Both have input capture, and should clock at 84 MHz2015-02-02 06:48 PM
OK: I suppose that was a silly statement without knowing for sure. But I looked in the stm32f4xx.h file and I only seen these to define the interrupt handlers for a CC:
TIM1_CC_IRQn TIM8_CC_IRQn How do I create an interrupt for a timer that isn't defined...? Thanks...2015-02-03 01:42 AM
As interrupt vectors are limited in number, most peripherals have only one vector which is shared for all interrupt sources of that peripheral. In fact, there are also vectors shared between several peripherals.
You might want to have a look at the ''capabilities'' sheet I concocted a couple of years ago http://efton.sk/STM32/STM32F4xx%20misc.pdf (usual disclaimers apply). JW2015-02-03 07:50 AM
TIM2_IRQn -> TIM2_IRQHandler(), all sources
2015-02-03 08:49 AM
Okay, to set up I did this:
void TIM2_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM6 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); /* TIM2 channel 1 pin (PA.15) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; 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_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect TIM pins to AF2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = ((SystemCoreClock / 2) / TIMER_BASE); TIM_TimeBaseStructure.TIM_Period = (uint16_t)(TIMER_BASE / 10.0); TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //Set up TIM2 interrrupt NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void main { TIM2_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); /* TIM enable counter */ TIM_Cmd(TIM2, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); } //interrupt handler void TIM2_IRQHandler(void) { if( TIM_GetITStatus(TIM2, TIM_IT_Update) ) { /* Clear TIM2 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM2, TIM_IT_Update); printf(''Living in an interrupt\n''); } } However, I cannot find 1 example of how to set up a capture/compare on channel 2. Can you direct me to an example, if there is one, as to how to set this up? Either that, or I have a working example for Timer 1 that runs the counter /capture - bus is too fast though. I do not understand how to set the clock for that timer alone? Thanks2015-02-03 08:59 AM
I've got it working...now to figure out getting the counts and converting to frequency....
thanks...2015-02-03 09:17 AM
The numbers are rolling in, but of course they are looking strange, and I believe I know what the problem may be.
At which rate should the clock be set up to run on the timer? If all of my frequencies are less than 50 Hz, should the Timer be a factor of 10 greater? 100? Any change and the numbers make less sense. Here's the interrupt code now being used (from CMSIS) void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET) { /* Clear TIM1 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); if(uhCaptureNumber == 0) { /* Get the Input Capture value */ uhIC3ReadValue1 = TIM_GetCapture1(TIM2); uhCaptureNumber = 1; } else if(uhCaptureNumber == 1) { /* Get the Input Capture value */ uhIC3ReadValue2 = TIM_GetCapture1(TIM2); /* Capture computation */ if (uhIC3ReadValue2 > uhIC3ReadValue1) { uwCapture = (uhIC3ReadValue2 - uhIC3ReadValue1); } else if (uhIC3ReadValue2 < uhIC3ReadValue1) { uwCapture = ((0xFFFF - uhIC3ReadValue1) + uhIC3ReadValue2); } else { uwCapture = 0; } /* Frequency computation */ uwTIM1Freq = (uint32_t) SystemCoreClock / uwCapture; printf(''frequency = %i\n'', uwTIM1Freq); uhCaptureNumber = 0; } } }2015-02-03 10:33 AM
Wow there's some chronic muddle in there...
TIM6 vs TIM2 CC1 vs CC2 The Prescaler should be ZERO, the Period should be MAXIMAL, ie 0xFFFFFFFF TIM2 is 32-bit, use it's full range. The math with the 0xFFFF is broken for 16-bit, and irrelevant for 32-bit. Take TWO measurements, and delta them, ie delta = B - A The delta is the number of ticks at the TIMCLK frequency, say 84 MHz for an STM32F4, timer on APB1. A 50 Hz signal will have 84,000,000 / 50 ticks, so 1,680,000 ticks. Conversely 84,000,000 / 1,680,000 = 50 (Hz)2015-02-03 01:10 PM