cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f103 Counter (EXTI/Timer)

amir_lm35
Associate II
Posted on August 04, 2016 at 20:09

Hi there.

i want to make a pulse counter with stm32f103RB. at first time i using EXTI to count the pulses means configure one of EXTI in falling or rising edge and in the IRQ_hander routine increase a variable. it works good in frequency lower than 100Hz !!!! when my frequency higher than 100Hz my counting lower than real pulses. i think this maybe because of EXTI low speed and go to use timer/counter but with channel capture i have same results :( my sample code like blow. could you please help me where is the problem?

void Configure_PA(void) {
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_9 | GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource11);
EXTI_InitStruct.EXTI_Line = EXTI_Line11; // EXTI15_10_IRQn
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn; 
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Set sub priority */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn; 
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource10); 
EXTI_InitStruct.EXTI_Line = EXTI_Line10;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource9); 
EXTI_InitStruct.EXTI_Line = EXTI_Line9;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource8); 
EXTI_InitStruct.EXTI_Line = EXTI_Line8;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
}
/* Handle Digital Input interrupts */
void EXTI15_10_IRQHandler(void) { 
if (EXTI_GetITStatus(EXTI_Line11) != RESET) { 
CounterCh[1]++;
EXTI_ClearITPendingBit(EXTI_Line11); 
} 
if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
CounterCh[2]++; 
EXTI_ClearITPendingBit(EXTI_Line10);
}
}
void EXTI9_5_IRQHandler(void) { 
if (EXTI_GetITStatus(EXTI_Line9) != RESET) {
CounterCh[3]++;
EXTI_ClearITPendingBit(EXTI_Line9); 
} 
if (EXTI_GetITStatus(EXTI_Line8) != RESET) {
CounterCh[4]++;
EXTI_ClearITPendingBit(EXTI_Line8); 
}
}

10 REPLIES 10
Walid FTITI_O
Senior II
Posted on August 25, 2016 at 14:16

Hi olafti.amir,

You should proceed as Input capture application. I recommend that you look to ''TIM_InputCapture'' example in

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef1.html

at this path: STM32Cube_FW_F1_V1.4.0\Projects\STM3210E_EVAL\Examples\TIM\TIM_InputCapture

In this example:TIM2 is configured in Input Capture Mode: the external signal is connected to

TIM2 Channel2 used as input pin.

To measure the frequency we use the TIM2 CC2 interrupt request, so in the

TIM2_IRQHandler routine, the frequency of the external signal is computed.

The ''uwFrequency'' variable contains the external signal frequency:

uwFrequency = TIM2 counter clock / uwDiffCapture (Hz),

where ''uwDiffCapture'' is the difference between two consecutive TIM2 captures.

The minimum frequency value to measure is TIM2 counter clock / CCR MAX

= 72 MHz / 65535

Due to TIM2_IRQHandler processing time (around 3.50us), the maximum

frequency value to measure is around 300kHz.

-Hannibal-