0

试图在 A3 上获得中断,以在 rx 字符上将 cpu 从睡眠中唤醒,但它没有触发。

是什么定义了 GPIO 引脚将触发哪个中断?我在参考手册中找不到

static void EXTI0_1_IRQHandler_Config(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure;

  /* Enable GPIOA clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  GPIO_InitStructure.Pin = GPIO_PIN_3;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Enable and set EXTI line 0 Interrupt to the lowest priority */
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}
4

1 回答 1

2

第 11 章中断和事件,第 11.1.3 节中断和异常向量中(简要)描述了中断函数。

在此处输入图像描述

所以,中断号是EXTI2_3_IRQn,你应该定义EXTI2_3_IRQHandler()调用HAL_GPIO_EXTI_IRQHandler()

一些背景

发生中断请求时调用回调函数涉及几个步骤。

每个中断请求都有一个分配给它的中断号,请参见上表中的位置条目。数字由硬件定义,符号名称在机器标题中的某处分配。

typedef enum {
   [...]
   EXTI0_1_IRQn                = 5,      /*!< EXTI Line 0 and 1 Interrupt */
   EXTI2_3_IRQn                = 6,      /*!< EXTI Line 2 and 3 Interrupt */
   [...]
} IRQn_Type;

向量表中有对应的函数指针,其中应该包含处理函数的地址。该向量表在启动模块中填写,该模块被称为startup_stm32f030x8.s或类似的东西,并且链接器配置文件确保在对闪存进行编程时该表最终位于正确的物理地址。

g_pfnVectors:
  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  0
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler
  .word  WWDG_IRQHandler                   /* Window WatchDog              */
  .word  0                                 /* Reserved                     */
  .word  RTC_IRQHandler                    /* RTC through the EXTI line    */
  .word  FLASH_IRQHandler                  /* FLASH                        */
  .word  RCC_IRQHandler                    /* RCC                          */
  .word  EXTI0_1_IRQHandler                /* EXTI Line 0 and 1            */
  .word  EXTI2_3_IRQHandler                /* EXTI Line 2 and 3            */
...

这些条目是固定顺序的,因为硬件只关心数字地址。每当一个EXTI2orEXTI3事件发生并被IRQ6启用时,它就会跳转到位于 的地址0x00000058。上表确保 的地址EXTI2_3_IRQHandler()进入向量表中的0x00000058

在启动模块中进一步挖掘,我们发现了这个

.weak      EXTI0_1_IRQHandler
.thumb_set EXTI0_1_IRQHandler,Default_Handler

.weak      EXTI2_3_IRQHandler
.thumb_set EXTI2_3_IRQHandler,Default_Handler

还有这个

Default_Handler:
Infinite_Loop:
  b Infinite_Loop

EXTI0_1_IRQHandler()这意味着如果or没有定义EXTI2_3_IRQHandler(),那么它们会调用一个无限循环,这对调试很有用,但没有别的。为了实际使用它,您必须在程序中覆盖此符号。如果你看这个GPIO_EXTI例子,它有这个处理程序

void EXTI0_1_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN);
}

定义在发生中断时stm32f0xx_it.c调用。如果你想采取行动,那么你应该有一个类似的功能HAL_GPIO_EXTI_IRQHandler()EXTI0EXTI3

void EXTI2_3_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(3);
}

打电话HAL_GPIO_EXTI_IRQHandler()

于 2017-04-18T10:17:18.197 回答