cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with Timer Input capture delta value on STM32F4

Bogdan
Senior
Posted on July 11, 2015 at 17:46

Hell all.

i encounter some problems when trying to read the lenght of a pulse (low-hi-low) The ideea is the followin. I have a flag wich is set 5, then at the first falling edge in cc2 event, i capture in ''captureA'' the counter value and set flag = 1. Then at the following rising edge, the flag is checked if previous was 1, if so, set it to 2. Then at the following falling edge i capture in ''captureB'' the second value, and calculate delta from captureB - captureA, . After delta is calculated, store in captureA the last value, wich is captureB, and set flag =3. Then at the next rising edge the flag is checked if was previous set to 3, if so, set it to 2 and the loop continues that way. After each delta is calculated, i set the update =1, and in the main while loop i just displayed the delta values. Since i am using ppm signal wich has diferent lenghts, at some point delta is overflowing into 0xFFFFFFFF and i dont catch why... Some advices would be usefull My code is bellow

#include <
sysTimer.h
>
#include <
stm32f4xx.h
>
#include ''stm32f4xx_it.h''
#include ''stm32f4xx_usart.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_exti.h''
#include ''gps_serial.h''
#include ''stm32f4xx_tim.h''
#include ''misc.h''
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; 
uint8_t flag=0;
uint8_t update=0;
uint32_t delta,capHi,capLo,captureA, captureB;
char txt[20];
int main()
{
init_leds();
gps_serial_init(); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
/* TIM2 GPIO pin configuration : CH1=PA0, C2=PA1 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure Timer2 timebase */
TIM_TimeBaseStructure.TIM_Prescaler = 83;
TIM_TimeBaseStructure.TIM_Period = 4294967295;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* configure Timer2 Channel 1 */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; /*Capture performed each time an edge is detected on the capture input. */
TIM_ICInitStructure.TIM_ICFilter = 0x00;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
/* configure Timer2 Channel 2 */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x00;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
/* Configure Timer2 Interupt Sources */ 
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); 
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); 
//enable tim2 irq
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE); // Start the Timer
flag=5;
while(1){
if(update==1){
sprintf(txt,''%u'',delta);
USART_Puts(txt);
USART_Puts('' \r''); 
update=0;
}
}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == 1){ // If Low-Hi transition occured
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); 
capHi = TIM_GetCapture1(TIM2); // Get timer counts for Period
GPIO_SetBits(GPIOD,GPIO_Pin_5);
GPIO_ResetBits(GPIOD,GPIO_Pin_5);
if(flag==1){ flag=2; }
if(flag==3) { flag=2; }
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == 1){ // If Hi-Low transition occured
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); 
capLo= TIM_GetCapture2(TIM2);
GPIO_SetBits(GPIOD,GPIO_Pin_15);
GPIO_ResetBits(GPIOD,GPIO_Pin_15);
if(flag == 5) {
captureA=capLo;
flag =1; 
} 
if(flag == 2) {
captureB = capLo; 
delta = ( captureB - captureA);
captureA = captureB; // get last value for the next delta
flag=3;
update=1;
}

}
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Counter overflow, reset interrupt
GPIO_ToggleBits(GPIOD,GPIO_Pin_12);
}
}

1 REPLY 1
Posted on July 12, 2015 at 16:07

Not sure the value of configuring the channel 2 pin

Or the usefulness of resetting the counter

TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1);

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

Might make the counter appear to go backward, ie very large deltas, without wrapping.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..