Electronic – nucleo-f401re button interrupt keep getting into the irq handler

nucleostm32

the nucleo board button is pulled up to high to gpioc13 so i made the interrupt on a falling edge , the code keeps getting into the irq handler without me pushing the button
my main.c

#include "Board_LED.h"
#include "stm32f401xe.h"

void PIN_CONFG();
void PIN_EN();
void clear();

int main(void) {
  LED_Initialize();
  PIN_CONFG(13);
  PIN_EN(13);

  LED_On(0);
  while(1){
  }

  return 0;
}

void delay(void) {
  int i; 
  for(i = 0; i < 5000000; i++) {
  } 
}

void EXTI15_10_IRQHandler(void) {
  clear(13);
  LED_On(0);
  delay();
  LED_Off(0);
  delay();
}

my interrupt functions.c

#include "stm32f401xe.h"

void PIN_CONFG(uint16_t pin) {
  EXTI->FTSR |= (1 << pin); 
}

void PIN_EN(uint16_t pin) {
  EXTI->IMR |= (1<<pin);    
  NVIC_EnableIRQ(40);
}

void clear(uint16_t pin) {
  if(EXTI->PR & (1<<pin)) {
    EXTI->PR |= (1<<pin);
  } 
}

Best Answer

The source pin for EXTI13 must be selected. It can be any of PA13, PB13, PC13 etc, and the SYSCFG->EXTICR registers tell the system which one to use.

RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC->APB2ENR; // see "Delay after an RCC peripheral clock enabling" in the errata sheet
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC; // EXTICR4 in the Reference Manual correspond to EXTICR[3]!

Without setting it defaults to PA13 (value 0), which is used as the SWDIO line from the onboard debugger. Any activity by the debugger triggers the interrupt.

By the way, don't forget to enable GPIOC in the clock controller. Same errata as above applies, you might want to interleave it with the code above to have the necessary delays without extra code.

RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC;