cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Timer14 as impulse counter

matjaz
Associate
Posted on January 07, 2016 at 19:16

Hi,

I'm trying to capture and count impulses on pin PA7 using timer 14 input captu

re

TIM14_CH1

. I have tried with the following code:

Initialization:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM14);

TIM_DeInit(TIM14);

TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);

TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;

// TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;

TIM_TimeBaseInitStruct.TIM_Prescaler = 0x0000;

TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStruct);

TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;

TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_BothEdge;//TIM_ICPolarity_Rising;//TIM_ICPolarity_BothEdge;

TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;

TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;

TIM_ICInitStruct.TIM_ICFilter=0;

TIM_ICInit(TIM14, &TIM_ICInitStruct);

TIM_TIxExternalClockConfig(TIM14,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Rising,0x0F);

TIM_Cmd(TIM14, ENABLE);

I read and reset the value every second:

Nr_transitions = TIM_GetCounter(TIM14);

TIM_SetCounter(TIM14, 0);

USB_VCP_Putc(Nr_transitions>>8);

USB_VCP_Putc(Nr_transitions);

The problem is I can't get the correct result. I constantly get a number between 0xBCxx and 0xBDxx no matter how many impulses I send to the pin. To be on the safe side I have confirmed the same pin can accept counting impulses through TIM3_CH2 timer using the following code:

Initialization:

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);

TIM_DeInit(TIM3);

TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);

TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;

TIM_TimeBaseInitStruct.TIM_Prescaler = 0x0000;

TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStruct);

TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;

TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_BothEdge;//TIM_ICPolarity_Rising;//TIM_ICPolarity_BothEdge;

TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;

TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;

TIM_ICInitStruct.TIM_ICFilter=0;

TIM_ICInit(TIM3, &TIM_ICInitStruct);

TIM_TIxExternalClockConfig(TIM3,TIM_TIxExternalCLK1Source_TI2,TIM_ICPolarity_BothEdge,0x0F);

TIM_Cmd(TIM3, ENABLE);

One second timer:

Nr_transitions = TIM_GetCounter(TIM3);

TIM_SetCounter(TIM3, 0);

USB_VCP_Putc(Nr_transitions>>8);

USB_VCP_Putc(Nr_transitions);

On the F4 discovery board this pin serves as a data pin to MEMS sensor. But I have verified the signal with an oscilloscope and it seems it has no influence to the input.

Any suggestions are much appreciated.

Regards,

Mat

3 REPLIES 3
Posted on January 07, 2016 at 19:23

Per the Reference Manual RM0090, TIM14 doesn't have any routing of the TI1 pin into the counter function. See ''Figure xxx. General-purpose timer block diagram (TIM10/11/13/14)''

You shouldn't need to implement Input Capture for the pins here, and your TIM3 code seems to configure TIM14

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
matjaz
Associate
Posted on January 07, 2016 at 21:40

I see now. I missed it's a capture/compare register and not counter register so

TIM_GetCounter(TIM14)

won't return anything useful. So it is impossible for higher number timers (9-14) to be used as impulse counters. Thanks for the help Clive! Another peculiar thing I've noticed on lower timers (2-5); how come I'm only able to record impulses to the frequencies of up to roughly 163kHz. After this mark, the counter collapses. Again, I've checked the signal and it is a nice square wave. 163k is very close to 168M divided by 1 Just saying. It might not be related... Regards, Mat
Posted on January 07, 2016 at 22:14

If you are interrupting you are likely saturating the processor. To read Input Capture at high frequencies you'd want to use DMA to grab the time stamps.

You can decimate the input using the Input Prescaler, ie time stamp 1, 2, 4 or 8 periods.

The input pin has a synchronization circuit, in this case probably at the AHB or a fraction thereof, and then into the domain of the timer. This would likely exhibit nyquist sampling characteristics, but not an issue at the low end frequencies you describe.

PWM Input mode works better where you poll the timer as it provides period and duty numbers in the CCR1/CCR2 latches. It resets the timer, instead of you having to delta two/three subsequent captures under interrupt.

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