cancel
Showing results for 
Search instead for 
Did you mean: 

how do I fix an interrupt that fires multiple times on EXTI4-15

YShko.1
Associate II

Hey,

I am using nucleo F030R8 om window os.

I connected buttons to the board and i proggramted that each push will trigger an interupt(rising and faling). However many times i can see the the unterupt callback function is triggerd twice(2 calls for one edge),for instance tow times for the rising and tow times for the falling. insted only tow(1 for falling, 1 for rising).

I red on the internet that maybe uts is something with the PR register..

I want to figure out the reason behind it. Could someone kindly explain?

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
 
	HAL_NVIC_DisableIRQ(EXTI4_15_IRQn);
 
	printf(
			"%s : %d :--------- Inside interrupt handler function - HAL_GPIO_EXTI_Callback------- \r\n",
			__FUNCTION__, __LINE__);
 
	uint16_t selectedPin;
	GPIO_TypeDef *selectedPort;
	int position = 0;
	switch (GPIO_Pin) {
 
	case Button1_Pin: {
		//Button 1 Press/release
		printf("%s : %d : Button 1 Press/release \r\n", __FUNCTION__, __LINE__);
		selectedPin = Button1_Pin;
		selectedPort = Button1_GPIO_Port;
		position = 1;
		break;
	}
 
	case Button2_Pin: {
		//		//Button 2 Press/release
		printf("%s : %d : Button 2 Press/release \r\n", __FUNCTION__, __LINE__);
		selectedPin = Button2_Pin;
		selectedPort = Button2_GPIO_Port;
		position = 2;
		break;
	}
 
	case Button3_Pin: {
		//Button 3  Press/release
		printf("%s : %d : Button 3 Press/release \r\n", __FUNCTION__, __LINE__);
		selectedPin = Button3_Pin;
		selectedPort = Button3_GPIO_Port;
		position = 3;
		break;
	}
 
	case Button4_Pin: {
		//Button 4  Press/release
		printf("%s : %d : Button 4 Press/release \r\n", __FUNCTION__, __LINE__);
		selectedPin = Button4_Pin;
		selectedPort = Button4_GPIO_Port;
		position = 4;
		break;
	}
 
	}
 
	
	if (position > 0) {
		GPIO_PinState state = HAL_GPIO_ReadPin(selectedPort, selectedPin);
 
		int i;
		//Bouncing
		for (i = 0; i < 15; i++) {
			sysSleep(1);
			if (state != HAL_GPIO_ReadPin(selectedPort, selectedPin)) {
				printf(
						"%s : %d :********Bouncing!!********\r\nExiting HAL_GPIO_EXTI_Callback function\r\n ",
						__FUNCTION__, __LINE__);
				HAL_NVIC_ClearPendingIRQ(EXTI4_15_IRQn);
				HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
				return;
			}
		}
 
		if (state == GPIO_PIN_SET) {
			debug("Pin state : %d \r\n", GPIO_PIN_SET);
			sendAsyncInput(position, GPIO_PIN_SET);
 
		} else {
			debug("Pin state is = %d \r\n", GPIO_PIN_RESET);
			sendAsyncInput(position, GPIO_PIN_RESET);
		}
		
 
		HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
 
	}
}

5 REPLIES 5

Pushbuttons bounce http://www.ganssle.com/debouncing.htm so you have to write your software to suppress the rapid multiple inputs.

One way to tackle this is to disable further interrupts on given pin for a short time.

Timers' channels have a hardware filter.

JW

ONadr.1
Senior III

Button generated few peaks when is pushed. It is normal situation. It can be handled by timestamps, that blocked after first interrupt user routine( action when button is pressed) for some time. Other variant is use some HW (filter, RS flip flop, monostable flip flop).

Thank you so much for your response to my request for information.

However what you descripe is call "Bouncing" and I took care of that with a for loop(line 57)

Even when I am in debugger I get the interrupt triggers twice, which was not suppose to happen in bouncing situation.

maybe something else?!

Thank you so much for your response to my request for information.

However what you descripe is call "Bouncing" and I took care of that with a for loop(line 57)

Even when I am in debugger I get the interrupt triggers twice, which was not suppose to happen in bouncing situation.

maybe something else?!

gbm
Lead III

It's generally a bad idea to use buttons with interrupts. To do it in the right way you also need to have a timer interrupt, and if you use timer interrupt (like SysTick), there is no need for button interrupt.

The simplest button handling: in the SysTick ISR create a section executed once per 20 ms. You need one static Boolean variable per button. In this section get the state of a button to another Boolean variable, trigger the action if the prevoius state was not pressed and current state is pressed. Copy the current state to the previous state static variable - 4 lines of code in total, no port pin interrupt needed.