I'm using a STM32F469 Discovery board, and I'm trying to get an external momentary push button to work.
It is currently connected to PG11, and it is set up so than when pressed it connects the pin to +5V supplied by the MCU. Before I continue, I just want to state that I use the following code in stmf4xx_it.c to perform debounce:
#define REFdebounce 200
int In1 = 3;
int In1_0 = 0;
int In1_1 = 0;
int StatoIn1 = 3;
void SysTick_Handler(void)
{
In1 = HAL_GPIO_ReadPin( GPIOG, GPIO_PIN_11 );
if ( In1 == 0 )
{
In1_0++;
In1_1 = 0;
if ( In1_0 >= REFdebounce )
{
In1_0 = REFdebounce + 1;
StatoIn1 = 0;
}
}
else
{
In1_0 = 0;
In1_1++;
if ( In1_1 >= REFdebounce )
{
In1_1 = REFdebounce + 1;
StatoIn1 = 1;
}
}
}
I have the following code in a header file inout.h:
typedef void ( * TSelectCallback ) ( int aSelectSignal );
void ConfigSelectPin
(
TSelectCallback aSelectCallback
);
And then in inout.c I have the following code for setup of the button GPIO pin:
#define SELECT_SIGNAL_PIN GPIO_PIN_11
#define SELECT_SIGNAL_GPIO_PORT GPIOG
#define SELECT_SIGNAL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
#define SELECT_SIGNAL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE()
#define SELECT_SIGNAL_EXTI_IRQn EXTI15_10_IRQn
void ConfigSelectPin( TSelectCallback aSelectCallback )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOC clock */
SELECT_SIGNAL_GPIO_CLK_ENABLE();
/* Configure washer signal pin as input floating */
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Pin = SELECT_SIGNAL_PIN;
HAL_GPIO_Init( SELECT_SIGNAL_GPIO_PORT, &GPIO_InitStructure );
/* Enable and set EXTI lines 0 Interrupt to the lowest priority */
HAL_NVIC_SetPriority( SELECT_SIGNAL_EXTI_IRQn, 8, 0 );
HAL_NVIC_EnableIRQ( SELECT_SIGNAL_EXTI_IRQn );
SelectCallback = aSelectCallback;
}
void EXTI15_10_IRQHandler( void )
{
if (__HAL_GPIO_EXTI_GET_IT( SELECT_SIGNAL_PIN ) != RESET)
{
RedLedOn();
__HAL_GPIO_EXTI_CLEAR_IT( SELECT_SIGNAL_PIN );
HAL_GPIO_EXTI_IRQHandler( SELECT_SIGNAL_PIN );
}
}
void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
{
if ( GPIO_Pin == SELECT_SIGNAL_PIN )
{
YellowLedOn();
GPIO_PinState pinState;
//pinState = HAL_GPIO_ReadPin( SELECT_SIGNAL_GPIO_PORT, GPIO_Pin );
pinState = 1;
if ( SelectCallback )
SelectCallback ( pinState );
}
}
Then in my main.c file I have the following:
/* variable to detect that hardware button is pressed */
static int Select = 0;
extern int StatoIn1;
void SelectIsrCallback( int aSelectSignal )
{
if ( StatoIn1 == 1 )
{
OrangeLedOn();
Select = 1;
}
}
I then use the following code to detect if the button has been pressed and perform my required action
if ( Select )
{
BlueLedOn();
Select = 0;
}
Now EVERY time I press the button, the EXTI15_10_IRQHandler is called as acknowledged by the red led turning on.
If I keep pressing the button, many many many times, the HAL_GPIO_EXTI_Callback will eventually be called as acknowledged by the yellow led turning on.
If I then keep pressing the button even more times, then eventually the SelectIsrCallback is called and my desired action is perfomed, as acknowledged by the orange and blue led turning on.
Why do the HAL_GPIO_EXTI_Callback and SelectIsrCallback not get called on the first button press? And why does the SelectIsrCallback not get called once the HAL_GPIO_EXTI_Callback is called?
NOTE: I've just moved the YellowLedOn() call, to before the if statement in HAL_GPIO_EXTI_Callback to see if it was this function of the if statement that takes loads of button presses before it is called. It made no difference, so the issue is with the calling of the HAL_GPIO_EXTI_Callback function.