2014-03-17 09:39 AM
Hello,
I am writing code to capture an incoming square wave frequency. Here is my initialization code:TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
// GPIOB clock enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
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 TIM pin to AF2
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM5);
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
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_DIV8;
TIM_ICInitStructure.TIM_ICFilter = 0x2;
TIM_PWMIConfig(TIM5, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM5,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM5, ENABLE);
TIM_ITConfig(TIM5, TIM_IT_CC2, ENABLE);
And here is my interrupt code:
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2); //perhaps changing this to cc1
/* Get the Input Capture value */
IC2Value = TIM_GetCapture2(TIM5);
if (IC2Value != 0)
{
/* Duty cycle computation */
DutyCycle = (TIM_GetCapture1(TIM5) * 100) / IC2Value;
Frequency = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value;
}
else
{
DutyCycle = 0;
Frequency = 0;
}
At frequencies of about 1.02 MHz, I am getting inaccurate readings, like 1.223051MHz. Is there a way to tune this in more? or do I have to characterize it like a noisy sensor?
Thanks for your help.
#stm32f4 #discovery #timers
2014-03-17 10:11 AM
Interrupting at 1 MHz is a bit high, wouldn't been reading/computing the processor speed at each interrupt.
Do you appreciate what the DIV8 is doing? The precision would depend on the frequency and stability of clock being provided to the timer. The speed would determine the measurement granularity. The input to the timer is resynchronized to the internal clock. The other method to compute frequency would be as an external counter, measured over a defined period.2014-03-17 02:44 PM
Yes, I believe that I 'appreciate' the DIV8 parameter. If I understand it correctly, it only throws an interrupt once every 8 events, and that is what I am using so that the rest of my code can run, otherwise it would simply interrupt constantly. I might have missed this in the datasheet, but I assumed that the timer could input capture at 1/168th the clock speed. I am actually intending it for frequencies of roughly 2MHZ and a bit above.
Also, clive1, I liked your old user pic better.