2013-01-18 06:12 AM
Hi all,
I am using a DiscoreryF4 board to develop a small application that counts pulses entering a specific pin. This is required to read the pulses from a field instrument that generates the pulses as some processes within the instrument occurs. Thus it is never a fixed number of pulses or a fixed frequency. All I need to do is count the number of pulses within a second in order to provide the results of the process within the instrument. I am using a signal generator so simulate the instrument that generates the pulses. Although it is a fixed frequency, it serves as a good enough simulation tool. The problem I experience is that I can only accurately count the pulses up to a frequency of 1.3MHz. At higher frequencies the values counted initially halves and then the processor halts. When decreasing the frequency after a halt occurred, the processor continues to operate again. Is there a maximum limit to the input frequencies that can be handled? Possibly the error occurs due to noise generated as part of this high input frequency that is affecting the processor or other components. I am posting the code used. Please comment if anyone spots mistakes that might be the cause of my problem.
static
void
init_exti_capture(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
__disable_irq();
/* SYSCFG clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* GPIOC clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* TIM8 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
/* EXTI1 line 0 : pin (PA.01) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect EXTI Line1 to PA1 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource1);
/* Configure EXTI Line1 */
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI Line1 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the TIM8 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* configure timebase for 1s */
TIM_TimeBaseStructure.TIM_Prescaler = (168 * 10) - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 10 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in Timing mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0x0;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
/* Enable the TIM8 Update Interrupt */
TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM8, ENABLE);
__enable_irq();
return
;
}
void
EXTI1_IRQHandler(
void
)
{
if
(EXTI_GetITStatus(EXTI_Line1) == SET)
{
/* increment as pulse detected */
EXTI_Capture_Rising_Cnt++;
EXTI_ClearITPendingBit(EXTI_Line1);
}
/* end ''if (EXTI_GetITStatus(EXTI_Line1) == SET)'' */
return
;
}
The value of EXTI_Capture_Rising_Cnt is printed and cleared every 1 second as part of the main loop.
Also see attached system_stm32f4xx.c file for clock and PLL configuration.
Thanks guys,
H
#exti #timer #timer
2013-03-14 05:16 AM
It's not really my job, I suggest you read through the documentation for the timers, and understand the modes they are capable of. Be conscious that if using a 16-bit counter sampling at 1 Hz it will max out at 65 KHz, at 10 Hz sampling 655 KHz, etc. You can sample the CNT register in an interrupt, although using a paced DMA would have better accuracy/consistency.
In terms of using the count for external input pulse you could look at [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/incrementation%20of%20a%20timer%20%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=296]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2Fincrementation%20of%20a%20timer%20%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=296