GPIOB 上的 EXTI 不起作用,但在 GPIOA 上一切正常

EXTI on GPIOB does not work but on GPIOA everything's ok

我想启用 EXTI 中断以获得有关端口是否已更改其状态的信息。 如下所示,我配置了 2 个引脚,GPIOA5 和 GPIOB3。两者都配置了上拉电阻,所以接地后应该会改变状态。

问题是一切都适用于 GPIOA5 但不适用于 GPIOB3。正在调用 GPIO5 的 isr,但没有调用 GPIOB。

我评论了有关 UART 配置的部分代码,因为它在这种情况下不相关 - Uart 工作正常,所以我可以看到从 MCU 发出的消息。

这里可能有什么问题?

我正在使用 STM32f411CEU6 和 libopencm3。

#include <libopencm3/stm32/gpio.h>

#include <libopencm3/stm32/flash.h>
#include <libopencm3/cm3/systick.h>

volatile bool sensor_isr_process { false };
volatile bool sensor_isr_process2 { false };

extern "C" {

void exti3_isr()
{
  sensor_isr_process2 = true;

    exti_reset_request(EXTI3);
}

void exti9_5_isr()
{
  sensor_isr_process = true;

    exti_reset_request(EXTI5);
}
}

void configure_exti(uint32_t nvicirq, uint32_t exti, uint32_t gpioport)
{
  nvic_enable_irq(nvicirq);

  exti_select_source(exti, gpioport);

  exti_set_trigger(exti, EXTI_TRIGGER_FALLING);
  exti_enable_request(exti);
}

int main()
{
  //Setup Clock
  auto clock = rcc_clock_scale{};
  clock.pllm = 8;
  clock.plln = 100; //336;
  clock.pllp = 2; //4;
  clock.pllq = 4; //7;
  clock.pllr = 2; //0;
  clock.pll_source = RCC_CFGR_PLLSRC_HSI_CLK;
  clock.hpre = RCC_CFGR_HPRE_DIV_NONE; //?
  clock.ppre1 = RCC_CFGR_PPRE_DIV_2; // ?
  clock.ppre2 = RCC_CFGR_PPRE_DIV_NONE; // ?
  clock.voltage_scale = PWR_SCALE1; //?
  clock.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
      FLASH_ACR_LATENCY_2WS;
  clock.ahb_frequency  = 100000000;
  clock.apb1_frequency = 50000000;
  clock.apb2_frequency = 100000000;

  rcc_clock_setup_pll(&clock);

  //Enable GPIO
  rcc_periph_clock_enable(RCC_GPIOA);
  rcc_periph_clock_enable(RCC_GPIOB);

  //Setup GPIO
  gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO5);
  gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO3);

  configure_exti(NVIC_EXTI9_5_IRQ, EXTI5, GPIOA);
  configure_exti(NVIC_EXTI3_IRQ,   EXTI3, GPIOB);

  while(1)
  {
    if (sensor_isr_process) {
      // trace(1, "Sensor 1\r\n"); //sends message by uart
      sensor_isr_process = false;
    } 
    else if (sensor_isr_process2) {
      // trace(1, "Sensor 2\r\n"); //send message by uart
      sensor_isr_process2 = false;
    }
  }
}

我不熟悉 libopencm3,但通常 EXTI 映射在 SYSCFG_EXTICR 寄存器中配置,以便访问它们,SYSCFG 需要启用时钟。

如果你检查它的 source 文件,你可以看到 exti_select_source() 函数没有启用 SYSCFG 时钟本身。所以可能你需要通过调用相关函数自己完成:

rcc_periph_clock_enable(RCC_SYSCFG);