Why are STM32 GPIO pins, when used as external interrupts, set as NOPULL?

Thread Starter

ApacheKid

Joined Jan 12, 2015
1,762
All of the examples I see of setting up a GPIO pin for use as an interrupt, set the pull to GPIO_NOPULL.

But why? surely it makes sense to pull the pin low or high? Is this done because there's a presumption the pin is never going to be floating?

In my case it is floating, until I manually ground the wire, which fires the interrupt.

If I use NOPULL it is repeatedly triggering, but if I use PULLUP it seems that everything is fine.
 

Thread Starter

ApacheKid

Joined Jan 12, 2015
1,762
Actually that's not 100% accurate, even when pulled up I see it triggered, seems I might have used a pin that I shouldn't have...
 

Thread Starter

ApacheKid

Joined Jan 12, 2015
1,762
This is puzzling. Hard to diagnose. I can't see any reason why I cannot setup GPIO pin A0 as an interrupt on this board. I can't see that any other PIN0s are setup as interrupts on interrupt line 0 either.

Yet the interrupt is triggering, and it starts after the app has finished. When the app "finishes" it enters a loop that pulses an LED forever.

Until that point is reached no interrupt is triggered (unless I manually trigger it) but once the app stops and enters that loop, the interrupts seem to repeatedly trigger randomly.

This is my HAL setup code:

Code:
    GPIO_InitStruct_irq.Pin = GPIO_PIN_0;
    GPIO_InitStruct_irq.Mode = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct_irq.Pull = GPIO_PULLUP;
    GPIO_InitStruct_spi.Speed = GPIO_SPEED_FAST;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct_irq);
   
    /* EXTI interrupt init*/
    HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
and this is the pulse routine, until this is entered no interrupts get triggered (unless I do so manually by touching PIN0 to ground).

Code:
static void pulse_led_forever(uint32_t interval)
{
    HAL_DeInit();
    HAL_Init();
   
    __GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef  GPIO_InitStruct = { 0 };
   
    GPIO_InitStruct.Pin       = GPIO_PIN_5;
    GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_MEDIUM;
   
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    while (1)
    {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
        HAL_Delay(interval);  
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        HAL_Delay(interval);  
    }
}
 

Thread Starter

ApacheKid

Joined Jan 12, 2015
1,762
OK posting that code helped! I have experimentally coded HAL_DeInit and HAL_Init into that pulse routine, that was just an experiment days ago that I forgot about and that seems to be the problem.

Removing those makes the interrupt behave fine
 

nsaspook

Joined Aug 27, 2009
16,249
But stupidity aside, what is the reason so much sample code I see, sets these inputs to NOPULL? is it under the expectation that there will be some device connected so there's no normal prospect of it just floating?

Does it do any "harm" to pull it up/down?

Thx
Yes, the code designer knows (hopefully) the actual hardware circuit so they can be sure of signal conditions like pullups on external signal triggers or open-drain/collector outputs so the default is NOPULL on device reset. The MPU pulls are usually weak so they can be easily overridden by external potentials. Up or Down depends on what's active, Low or High, usually.
 

Thread Starter

ApacheKid

Joined Jan 12, 2015
1,762
Yes, the code designer knows (hopefully) the actual hardware circuit so they can be sure of signal conditions like pullups on external signal triggers or open-drain/collector outputs so the default is NOPULL on device reset. The MPU pulls are usually weak so they can be easily overridden by external potentials. Up or Down depends on what's active, Low or High, usually.
OK good, that makes sense, much appreciated.
 
Top